diff --git a/config.yml.example b/config.yml.example index 43f8e4b..718f7a8 100644 --- a/config.yml.example +++ b/config.yml.example @@ -7,6 +7,9 @@ concurrent_workers: 10 check_for_changes_every_secs: 15 info_cache_time_hours: 12 enable_repair: true # BEWARE! THERE CAN ONLY BE 1 INSTANCE OF ZURG THAT SHOULD REPAIR YOUR TORRENTS +on_library_update: | + echo "hook" +network_buffer_size: 32768 # 32KB # List of directory definitions and their filtering rules directories: diff --git a/internal/config/load.go b/internal/config/load.go index 07d229f..02391b2 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -18,6 +18,7 @@ type ConfigInterface interface { GetDirectories() []string MeetsConditions(directory, torrentID, torrentName string, fileNames []string) bool GetOnLibraryUpdate() string + GetNetworkBufferSize() int } func LoadZurgConfig(filename string) (ConfigInterface, error) { diff --git a/internal/config/types.go b/internal/config/types.go index 63ca8b6..330cd20 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -9,10 +9,7 @@ type ZurgConfig struct { CacheTimeHours int `yaml:"info_cache_time_hours"` CanRepair bool `yaml:"enable_repair"` OnLibraryUpdate string `yaml:"on_library_update"` -} - -func (z *ZurgConfig) GetVersion() string { - return "v1" + NetworkBufferSize int `yaml:"network_buffer_size"` } func (z *ZurgConfig) GetToken() string { @@ -20,14 +17,23 @@ func (z *ZurgConfig) GetToken() string { } func (z *ZurgConfig) GetPort() string { + if z.Port == "" { + return "9999" + } return z.Port } func (z *ZurgConfig) GetNumOfWorkers() int { + if z.NumOfWorkers == 0 { + return 10 + } return z.NumOfWorkers } func (z *ZurgConfig) GetRefreshEverySeconds() int { + if z.RefreshEverySeconds == 0 { + return 60 + } return z.RefreshEverySeconds } @@ -42,3 +48,10 @@ func (z *ZurgConfig) EnableRepair() bool { func (z *ZurgConfig) GetOnLibraryUpdate() string { return z.OnLibraryUpdate } + +func (z *ZurgConfig) GetNetworkBufferSize() int { + if z.NetworkBufferSize == 0 { + return 32 * 1024 + } + return z.NetworkBufferSize +} diff --git a/internal/config/v1.go b/internal/config/v1.go index 9bd0d3d..dd2bf9b 100644 --- a/internal/config/v1.go +++ b/internal/config/v1.go @@ -17,6 +17,10 @@ func loadV1Config(content []byte) (*ZurgConfigV1, error) { return &configV1, nil } +func (z *ZurgConfigV1) GetVersion() string { + return "v1" +} + func (z *ZurgConfigV1) GetDirectories() []string { rootDirectories := make([]string, len(z.Directories)) i := 0 diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 840d872..6d770aa 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -557,7 +557,7 @@ func (t *TorrentManager) repair(torrentID string, selectedFiles []File, tryReins t.reinsertTorrent(torrent, missingFiles2, false) } } else { - log.Println("Cannot repair", torrent.Name) + log.Println("Cannot repair as the only 1 torrent is already broken in RD", torrent.ID, torrent.Name) return } log.Println("Waiting for downloads to finish") diff --git a/internal/universal/get.go b/internal/universal/get.go index af4079d..d7d0224 100644 --- a/internal/universal/get.go +++ b/internal/universal/get.go @@ -7,7 +7,6 @@ import ( "path" "path/filepath" "strings" - "sync" "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/dav" @@ -40,7 +39,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent return } if data, exists := cache.Get(requestPath); exists { - http.Redirect(w, r, data, http.StatusFound) + streamFileToResponse(data, w, r, c.GetNetworkBufferSize()) return } @@ -51,7 +50,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent torrents := t.FindAllTorrentsWithName(baseDirectory, torrentName) if torrents == nil { log.Println("Cannot find torrent", requestPath) - http.Error(w, "Cannot find file", http.StatusNotFound) + http.Redirect(w, r, "https://send.nukes.wtf/tDeTd0", http.StatusFound) return } @@ -87,49 +86,45 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent } else { log.Println("Filename mismatch", resp.Filename, filenameV2) } - } else { - cache.Add(requestPath, resp.Download) - streamFileToResponse(resp.Download, w) } + cache.Add(requestPath, resp.Download) + streamFileToResponse(resp.Download, w, r, c.GetNetworkBufferSize()) } -func streamFileToResponse(url string, w http.ResponseWriter) { - resp, err := http.Get(url) // HTTP/2 is used by default if the server supports it +func streamFileToResponse(url string, w http.ResponseWriter, r *http.Request, bufferSize int) { + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + log.Println("Error creating new request:", err) + http.Redirect(w, r, "https://send.nukes.wtf/ARjVWb", http.StatusFound) + return + } + + for k, values := range r.Header { + for _, v := range values { + req.Header.Add(k, v) + } + } + + resp, err := http.DefaultClient.Do(req) if err != nil { log.Println("Error downloading file:", err) - http.Error(w, "Error downloading file", http.StatusInternalServerError) + http.Redirect(w, r, "https://send.nukes.wtf/TB2u2n", http.StatusFound) return } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent { log.Printf("Received a non-OK status code: %d", resp.StatusCode) - http.Error(w, "Error downloading file", http.StatusInternalServerError) + http.Redirect(w, r, "https://send.nukes.wtf/b5AiON", http.StatusFound) return } - // Parallelize header copying to reduce waiting time - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - for k, vv := range resp.Header { - for _, v := range vv { - w.Header().Add(k, v) - } + for k, vv := range resp.Header { + for _, v := range vv { + w.Header().Add(k, v) } - }() - - // If Content-Length is available from the original response, set it - if val, ok := resp.Header["Content-Length"]; ok { - w.Header().Set("Content-Length", val[0]) } - // Wait for the header copying to complete - - // Stream the response with a buffer for better performance - bufferSize := 32 * 1024 // 16KB buffer buf := make([]byte, bufferSize) - wg.Wait() io.CopyBuffer(w, resp.Body, buf) }