all repos — fixyoutube-go @ 50c43a7eba19e6652a1c88bc3b129281f1ede12a

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