all repos — fixyoutube-go @ e57b55acea1bb8e55a8620c62c41cd23984e0c46

A better way to embed YouTube videos everywhere (inspired by FixTweet).

use VideoBuffer for all proxy functions
Marco Andronaco andronacomarco@gmail.com
Mon, 15 Jan 2024 15:58:06 +0100
commit

e57b55acea1bb8e55a8620c62c41cd23984e0c46

parent

78a91dca196fbcf8499a86c8282cce3b83e1302d

5 files changed, 43 insertions(+), 36 deletions(-)

jump to
M fixyoutube.gofixyoutube.go

@@ -130,8 +130,8 @@ return func(w http.ResponseWriter, r *http.Request) {

vars := mux.Vars(r) videoId := vars["videoId"] - b, l, s := invidiousClient.ProxyVideoId(videoId) - if l == 0 || l != int64(b.Len()) { + vb, s := invidiousClient.ProxyVideoId(videoId) + if !vb.ValidateLength() { logger.Error("proxyHandler() failed. Final code: ", s) http.Error(w, "Something went wrong.", s) return

@@ -139,9 +139,8 @@ }

h := w.Header() h.Set("Status", "200") h.Set("Content-Type", "video/mp4") - h.Set("Content-Length", strconv.FormatInt(l, 10)) - - io.Copy(w, b) + h.Set("Content-Length", strconv.FormatInt(vb.Length, 10)) + io.Copy(w, vb.Buffer) return } }
M invidious/api.goinvidious/api.go

@@ -55,12 +55,12 @@ return nil, http.StatusInternalServerError

} res.Expire = time.Unix(expireTimestamp, 0) - b, l, i := c.findCompatibleFormat(res) - if l == 0 { + vb, i := c.findCompatibleFormat(res) + if vb.Length <= 0 { logger.Warn("No compatible formats found for video.") res.Url = "" } else { - videoBuffer := NewVideoBuffer(b, l) + videoBuffer := vb.Clone() c.buffers.Set(videoId, videoBuffer) res.Url = res.Formats[i].Url }
M invidious/invidious.goinvidious/invidious.go

@@ -21,8 +21,8 @@ var expireRegex = regexp.MustCompile(`(?i)expire=(\d+)`)

var logger = logrus.New() type VideoBuffer struct { - buffer *bytes.Buffer - length int64 + Buffer *bytes.Buffer + Length int64 } type Client struct {

@@ -66,9 +66,17 @@ duplicate := new(bytes.Buffer)

duplicate.Write(b.Bytes()) return &VideoBuffer{ - buffer: duplicate, - length: l, + Buffer: duplicate, + Length: l, } +} + +func (vb *VideoBuffer) Clone() *VideoBuffer { + return NewVideoBuffer(vb.Buffer, vb.Length) +} + +func (vb *VideoBuffer) ValidateLength() bool { + return vb.Length > 0 && vb.Length == int64(vb.Buffer.Len()) } func (c *Client) GetVideo(videoId string, fromCache bool) (*Video, error) {
M invidious/proxy.goinvidious/proxy.go

@@ -6,34 +6,34 @@ "io"

"net/http" ) -func (c *Client) urlToBuffer(url string) (*bytes.Buffer, int64, int) { +func (c *Client) urlToBuffer(url string) (*VideoBuffer, int) { if url == "" { - return nil, 0, http.StatusBadRequest + return nil, http.StatusBadRequest } req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { logger.Error(err) // bad request - return nil, 0, http.StatusInternalServerError + return nil, http.StatusInternalServerError } resp, err := c.http.Do(req) if err != nil { logger.Error(err) // request failed - return nil, 0, http.StatusGone + return nil, http.StatusGone } if resp.StatusCode != http.StatusOK { - return nil, 0, resp.StatusCode + return nil, resp.StatusCode } if resp.ContentLength == 0 { - return nil, 0, http.StatusNoContent + return nil, http.StatusNoContent } if resp.ContentLength > maxSizeBytes { logger.Debug("Content-Length exceeds max size.") - return nil, 0, http.StatusBadRequest + return nil, http.StatusBadRequest } defer resp.Body.Close()

@@ -41,47 +41,47 @@ b := new(bytes.Buffer)

l, err := io.Copy(b, resp.Body) if l != resp.ContentLength { logger.Debug("Content-Length is inconsistent.") - return nil, 0, http.StatusBadRequest + return nil, http.StatusBadRequest } - return b, l, http.StatusOK + return &VideoBuffer{b, l}, http.StatusOK } -func (c *Client) findCompatibleFormat(video *Video) (*bytes.Buffer, int64, int) { +func (c *Client) findCompatibleFormat(video *Video) (*VideoBuffer, int) { for i := len(video.Formats) - 1; i >= 0; i-- { url := video.Formats[i].Url logger.Debug(url) - b, l, httpStatus := c.urlToBuffer(url) + vb, httpStatus := c.urlToBuffer(url) if httpStatus == http.StatusOK { - videoBuffer := NewVideoBuffer(b, l) + videoBuffer := vb.Clone() c.buffers.Set(video.VideoId, videoBuffer) - return b, l, i + return vb, i } logger.Debug("Format ", i, "failed with status code ", httpStatus) } - return nil, 0, -1 + return nil, -1 } -func (c *Client) getBuffer(video Video) (*bytes.Buffer, int64, int) { +func (c *Client) getBuffer(video Video) (*VideoBuffer, int) { vb, err := c.buffers.Get(video.VideoId) if err != nil { - b, l, s := c.urlToBuffer(video.Url) - if l > 0 { - videoBuffer := NewVideoBuffer(b, l) + vb, s := c.urlToBuffer(video.Url) + if vb.Length > 0 { + videoBuffer := vb.Clone() c.buffers.Set(video.VideoId, videoBuffer) } - return b, l, s + return vb, s } - videoBuffer := NewVideoBuffer(vb.buffer, vb.length) - return videoBuffer.buffer, videoBuffer.length, http.StatusOK + videoBuffer := vb.Clone() + return videoBuffer, http.StatusOK } -func (c *Client) ProxyVideoId(videoId string) (*bytes.Buffer, int64, int) { +func (c *Client) ProxyVideoId(videoId string) (*VideoBuffer, int) { video, err := GetVideoDB(videoId) if err != nil { logger.Info("Cannot proxy a video that is not cached: https://youtu.be/", videoId) - return nil, 0, http.StatusBadRequest + return nil, http.StatusBadRequest } return c.getBuffer(*video) }
M volatile/volatile.govolatile/volatile.go

@@ -93,7 +93,7 @@ func (v *Volatile[K, V]) Remove(key K) (*V, error) {

i := v.indexOf(key) if i == -1 { err := fmt.Errorf("Can't remove unexisting index") - logger.Warn("Trying to delete unexisting key: ", key) + logger.Debug("Trying to delete unexisting key: ", key) return nil, err }