Use a proper client for fetch byte

This commit is contained in:
Ben Sarmiento
2023-11-24 21:35:22 +01:00
parent 1e8c50a350
commit 595040ad7e
6 changed files with 97 additions and 116 deletions

View File

@@ -17,8 +17,16 @@ import (
"go.uber.org/zap"
)
type GetFile struct {
client *zurghttp.HTTPClient
}
func NewGetFile(client *zurghttp.HTTPClient) *GetFile {
return &GetFile{client: client}
}
// HandleGetRequest handles a GET request universally for both WebDAV and HTTP
func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) {
func (gf *GetFile) HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) {
log := logutil.NewLogger().Named("file")
requestPath := path.Clean(r.URL.Path)
@@ -65,15 +73,19 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentM
return
}
if data, exists := cache.Get(requestPath); exists {
streamFileToResponse(file, data, w, r, t, c, log)
if url, exists := cache.Get(requestPath); exists {
if c.ShouldServeFromRclone() {
http.Redirect(w, r, url, http.StatusFound)
} else {
gf.streamFileToResponse(file, url, w, r, t, c, log)
}
return
}
if !strings.HasPrefix(file.Link, "http") {
// This is a dead file, serve an alternate file
log.Warnf("File %s is not yet available, zurg is repairing the torrent", filename)
streamErrorVideo("https://www.youtube.com/watch?v=bGTqwt6vdcY", w, r, t, c, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=bGTqwt6vdcY", w, r, t, c, log)
return
}
link := file.Link
@@ -83,7 +95,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentM
log.Warnf("File %s is no longer available", file.Path)
file.Link = "repair"
t.SetChecksum("") // force a recheck
streamErrorVideo("https://www.youtube.com/watch?v=gea_FJrtFVA", w, r, t, c, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=gea_FJrtFVA", w, r, t, c, log)
} else {
if resp.Filename != filename {
// this is possible if there's only 1 streamable file in the torrent
@@ -92,25 +104,29 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentM
expectedExt := filepath.Ext(filename)
if actualExt != expectedExt && resp.Streamable != 1 {
log.Warnf("File was changed and is not streamable: %s and %s", filename, resp.Filename)
streamErrorVideo("https://www.youtube.com/watch?v=t9VgOriBHwE", w, r, t, c, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=t9VgOriBHwE", w, r, t, c, log)
return
} else {
log.Warnf("Filename mismatch: %s and %s", filename, resp.Filename)
}
}
cache.Add(requestPath, resp.Download)
streamFileToResponse(file, resp.Download, w, r, t, c, log)
if c.ShouldServeFromRclone() {
http.Redirect(w, r, resp.Download, http.StatusFound)
} else {
gf.streamFileToResponse(file, resp.Download, w, r, t, c, log)
}
}
}
func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter, r *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *zap.SugaredLogger) {
func (gf *GetFile) streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter, r *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *zap.SugaredLogger) {
// Create a new request for the file download.
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
if file != nil {
log.Errorf("Error creating new request for file %s: %v", file.Path, err)
}
streamErrorVideo("https://www.youtube.com/watch?v=H3NSrObyAxM", w, r, torMgr, cfg, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=H3NSrObyAxM", w, r, torMgr, cfg, log)
return
}
@@ -119,17 +135,14 @@ func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter,
req.Header.Add("Range", r.Header.Get("Range"))
}
// Create a custom HTTP client
client := zurghttp.NewHTTPClient(cfg.GetToken(), 10, cfg)
resp, err := client.Do(req)
resp, err := gf.client.Do(req)
if err != nil {
if file != nil {
log.Warnf("Cannot download file %s: %v", file.Path, err)
file.Link = "repair"
torMgr.SetChecksum("") // force a recheck
}
streamErrorVideo("https://www.youtube.com/watch?v=FSSd8cponAA", w, r, torMgr, cfg, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=FSSd8cponAA", w, r, torMgr, cfg, log)
return
}
defer resp.Body.Close()
@@ -140,7 +153,7 @@ func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter,
file.Link = "repair"
torMgr.SetChecksum("") // force a recheck
}
streamErrorVideo("https://www.youtube.com/watch?v=BcseUxviVqE", w, r, torMgr, cfg, log)
gf.playErrorVideo("https://www.youtube.com/watch?v=BcseUxviVqE", w, r, torMgr, cfg, log)
return
}
@@ -154,11 +167,15 @@ func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter,
io.CopyBuffer(w, resp.Body, buf)
}
func streamErrorVideo(link string, w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, log *zap.SugaredLogger) {
func (gf *GetFile) playErrorVideo(link string, w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, log *zap.SugaredLogger) {
resp := t.UnrestrictUntilOk(link)
if resp == nil {
http.Error(w, "REAL-DEBRID IS DOWN", http.StatusInternalServerError)
return
}
streamFileToResponse(nil, resp.Download, w, r, t, c, log)
if c.ShouldServeFromRclone() {
http.Redirect(w, r, resp.Download, http.StatusFound)
return
}
gf.streamFileToResponse(nil, resp.Download, w, r, t, c, log)
}