Use a proper client for fetch byte
This commit is contained in:
@@ -18,6 +18,7 @@ type ConfigInterface interface {
|
||||
EnableRetainFolderNameExtension() bool
|
||||
EnableRetainRDTorrentName() bool
|
||||
GetRandomPreferredHost() string
|
||||
ShouldServeFromRclone() bool
|
||||
}
|
||||
|
||||
type ZurgConfig struct {
|
||||
@@ -34,6 +35,7 @@ type ZurgConfig struct {
|
||||
RetainFolderNameExtension bool `yaml:"retain_folder_name_extension"`
|
||||
RetainRDTorrentName bool `yaml:"retain_rd_torrent_name"`
|
||||
PreferredHosts []string `yaml:"preferred_hosts"`
|
||||
ServeFromRclone bool `yaml:"serve_from_rclone"`
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetToken() string {
|
||||
@@ -105,3 +107,7 @@ func (z *ZurgConfig) GetRandomPreferredHost() string {
|
||||
randomIndex := rand.Intn(len(z.PreferredHosts))
|
||||
return z.PreferredHosts[randomIndex]
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) ShouldServeFromRclone() bool {
|
||||
return z.ServeFromRclone
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/debridmediamanager.com/zurg/internal/config"
|
||||
"github.com/debridmediamanager.com/zurg/internal/dav"
|
||||
zurghttp "github.com/debridmediamanager.com/zurg/internal/http"
|
||||
intHttp "github.com/debridmediamanager.com/zurg/internal/http"
|
||||
"github.com/debridmediamanager.com/zurg/internal/torrent"
|
||||
"github.com/debridmediamanager.com/zurg/internal/universal"
|
||||
"github.com/debridmediamanager.com/zurg/pkg/logutil"
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// Router creates a WebDAV router
|
||||
func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentManager, cache *expirable.LRU[string, string]) {
|
||||
func Router(mux *http.ServeMux, getfile *universal.GetFile, c config.ConfigInterface, t *torrent.TorrentManager, cache *expirable.LRU[string, string]) {
|
||||
log := logutil.NewLogger().Named("net")
|
||||
|
||||
mux.HandleFunc("/http/", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -23,9 +23,9 @@ func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentMana
|
||||
case http.MethodGet:
|
||||
requestPath := path.Clean(r.URL.Path)
|
||||
if countNonEmptySegments(strings.Split(requestPath, "/")) > 3 {
|
||||
universal.HandleGetRequest(w, r, t, c, cache)
|
||||
getfile.HandleGetRequest(w, r, t, c, cache)
|
||||
} else {
|
||||
zurghttp.HandleDirectoryListing(w, r, t)
|
||||
intHttp.HandleDirectoryListing(w, r, t)
|
||||
}
|
||||
|
||||
case http.MethodHead:
|
||||
@@ -47,7 +47,7 @@ func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentMana
|
||||
dav.HandleDeleteRequest(w, r, t, davlog)
|
||||
|
||||
case http.MethodGet:
|
||||
universal.HandleGetRequest(w, r, t, c, cache)
|
||||
getfile.HandleGetRequest(w, r, t, c, cache)
|
||||
|
||||
case http.MethodOptions:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user