all repos — fixyoutube-go @ 467b10906293eb85238d02c16a7fb0b434363987

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

invidious/proxy.go (view raw)

 1package invidious
 2
 3import (
 4	"bytes"
 5	"io"
 6	"net/http"
 7)
 8
 9func (c *Client) urlToBuffer(url string) (*bytes.Buffer, int64, int) {
10	if url == "" {
11		return nil, 0, http.StatusBadRequest
12	}
13
14	req, err := http.NewRequest(http.MethodGet, url, nil)
15	if err != nil {
16		logger.Error(err) // bad request
17		return nil, 0, http.StatusInternalServerError
18	}
19
20	resp, err := c.http.Do(req)
21	if err != nil {
22		logger.Error(err) // request failed
23		return nil, 0, http.StatusGone
24	}
25
26	if resp.StatusCode != http.StatusOK {
27		return nil, 0, resp.StatusCode
28	}
29
30	if resp.ContentLength == 0 {
31		return nil, 0, http.StatusNoContent
32	}
33
34	if resp.ContentLength > maxSizeBytes {
35		logger.Debug("Content-Length exceeds max size.")
36		return nil, 0, http.StatusBadRequest
37	}
38	defer resp.Body.Close()
39
40	b := new(bytes.Buffer)
41	l, err := io.Copy(b, resp.Body)
42	if l != resp.ContentLength {
43		logger.Debug("Content-Length is inconsistent.")
44		return nil, 0, http.StatusBadRequest
45	}
46
47	return b, l, http.StatusOK
48}
49
50func (c *Client) findCompatibleFormat(video *Video) (*bytes.Buffer, int64, int) {
51	for i := len(video.Formats) - 1; i >= 0; i-- {
52		url := video.Formats[i].Url
53		logger.Debug(url)
54		b, l, httpStatus := c.urlToBuffer(url)
55		if httpStatus == http.StatusOK {
56			return b, l, i
57		}
58		logger.Debug("Format ", i, "failed with status code ", httpStatus)
59	}
60	return nil, 0, -1
61}
62
63func (c *Client) ProxyVideoId(videoId string) (*bytes.Buffer, int64, int) {
64	video, err := GetVideoDB(videoId)
65	if err != nil {
66		logger.Info("Cannot proxy a video that is not cached: https://youtu.be/", videoId)
67		return nil, 0, http.StatusBadRequest
68	}
69
70	return c.urlToBuffer(video.Url)
71}