all repos — fixyoutube-go @ 4fde0f88bf0b2a1271263fadb19eebd2c2caa622

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	"time"
 8
 9	"github.com/birabittoh/rabbitpipe"
10)
11
12const MaxSizeBytes = int64(20 * 1024 * 1024)
13
14func urlToBuffer(url string) (*VideoBuffer, int) {
15	if url == "" {
16		return nil, http.StatusBadRequest
17	}
18
19	req, err := http.NewRequest(http.MethodGet, url, nil)
20	if err != nil {
21		logger.Error(err) // bad request
22		return nil, http.StatusInternalServerError
23	}
24
25	resp, err := http.DefaultClient.Do(req)
26	if err != nil {
27		logger.Error(err) // request failed
28		return nil, http.StatusGone
29	}
30
31	if resp.StatusCode != http.StatusOK {
32		return nil, resp.StatusCode
33	}
34
35	if resp.ContentLength == 0 {
36		return nil, http.StatusNoContent
37	}
38
39	if resp.ContentLength > MaxSizeBytes {
40		logger.Debug("Content-Length exceeds max size.")
41		return nil, http.StatusBadRequest
42	}
43	defer resp.Body.Close()
44
45	b := new(bytes.Buffer)
46	l, _ := io.Copy(b, resp.Body)
47	if l != resp.ContentLength {
48		logger.Debug("Content-Length is inconsistent.")
49		return nil, http.StatusBadRequest
50	}
51
52	return &VideoBuffer{b, l}, http.StatusOK
53}
54
55func getBuffer(video rabbitpipe.Video) (*VideoBuffer, int) {
56	vb, err := buffers.Get(video.VideoID)
57	if err != nil {
58		// no cache entry
59		vb, s := urlToBuffer(GetVideoURL(video))
60		if vb != nil {
61			if s == http.StatusOK && vb.Length > 0 {
62				buffers.Set(video.VideoID, *vb, 5*time.Minute)
63				return vb, s
64			}
65		}
66		return nil, s
67	}
68	//cache entry
69	videoBuffer := vb.Clone()
70	return videoBuffer, http.StatusOK
71}
72
73func ProxyVideoId(videoID string) (*VideoBuffer, int) {
74	video, err := RP.GetVideo(videoID)
75	if err != nil {
76		logger.Info("Cannot get video: https://youtu.be/", videoID)
77		return nil, http.StatusBadRequest
78	}
79	return getBuffer(*video)
80}