Add basic auth and fix repair issues
This commit is contained in:
@@ -11,6 +11,8 @@ type ConfigInterface interface {
|
||||
EnableRepair() bool
|
||||
GetHost() string
|
||||
GetPort() string
|
||||
GetUsername() string
|
||||
GetPassword() string
|
||||
GetDirectories() []string
|
||||
MeetsConditions(directory, torrentName string, torrentSize int64, torrentIDs, fileNames []string, fileSizes []int64) bool
|
||||
GetOnLibraryUpdate() string
|
||||
@@ -34,6 +36,8 @@ type ZurgConfig struct {
|
||||
|
||||
Host string `yaml:"host" json:"host"`
|
||||
Port string `yaml:"port" json:"port"`
|
||||
Username string `yaml:"username" json:"username"`
|
||||
Password string `yaml:"password" json:"password"`
|
||||
NumOfWorkers int `yaml:"concurrent_workers" json:"concurrent_workers"`
|
||||
RefreshEverySeconds int `yaml:"check_for_changes_every_secs" json:"check_for_changes_every_secs"`
|
||||
|
||||
@@ -78,6 +82,14 @@ func (z *ZurgConfig) GetPort() string {
|
||||
return z.Port
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetUsername() string {
|
||||
return z.Username
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetPassword() string {
|
||||
return z.Password
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetNumOfWorkers() int {
|
||||
if z.NumOfWorkers == 0 {
|
||||
return 50
|
||||
|
||||
17
internal/handlers/basicauth.go
Normal file
17
internal/handlers/basicauth.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package handlers
|
||||
|
||||
import "net/http"
|
||||
|
||||
func (hs *Handlers) basicAuth(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
username, password, ok := r.BasicAuth()
|
||||
if !ok || username != hs.cfg.GetUsername() || password != hs.cfg.GetPassword() {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="restricted"`)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(http.StatusText(http.StatusUnauthorized)))
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Premium</td>
|
||||
<td>%d seconds</td>
|
||||
<td>%d days</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Expiration</td>
|
||||
@@ -267,28 +267,28 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
||||
response.UserInfo.Points,
|
||||
response.UserInfo.Locale,
|
||||
response.UserInfo.Type,
|
||||
response.UserInfo.Premium,
|
||||
response.UserInfo.Expiration,
|
||||
response.UserInfo.Premium/86400,
|
||||
strings.Replace(response.UserInfo.Expiration, "Z", "+01:00", 1),
|
||||
response.Config.Version,
|
||||
strings.Replace(response.Config.Token, response.Config.Token[len(response.Config.Token)-48:], "*****", 1),
|
||||
response.Config.Host,
|
||||
response.Config.Port,
|
||||
response.Config.NumOfWorkers,
|
||||
response.Config.RefreshEverySeconds,
|
||||
response.Config.RetainRDTorrentName,
|
||||
response.Config.RetainFolderNameExtension,
|
||||
response.Config.CanRepair,
|
||||
response.Config.DeleteRarFiles,
|
||||
response.Config.RealDebridTimeout,
|
||||
response.Config.UseDownloadCache,
|
||||
response.Config.RateLimitSleepSeconds,
|
||||
response.Config.RetriesUntilFailed,
|
||||
response.Config.GetHost(),
|
||||
response.Config.GetPort(),
|
||||
response.Config.GetNumOfWorkers(),
|
||||
response.Config.GetRefreshEverySeconds(),
|
||||
response.Config.EnableRetainRDTorrentName(),
|
||||
response.Config.EnableRetainFolderNameExtension(),
|
||||
response.Config.EnableRepair(),
|
||||
response.Config.ShouldDeleteRarFiles(),
|
||||
response.Config.GetRealDebridTimeout(),
|
||||
response.Config.EnableDownloadCache(),
|
||||
response.Config.GetRateLimitSleepSeconds(),
|
||||
response.Config.GetRetriesUntilFailed(),
|
||||
strings.Join(response.Config.PreferredHosts, ", "),
|
||||
response.Config.NetworkBufferSize,
|
||||
response.Config.ServeFromRclone,
|
||||
response.Config.VerifyDownloadLink,
|
||||
response.Config.ForceIPv6,
|
||||
response.Config.OnLibraryUpdate,
|
||||
response.Config.GetNetworkBufferSize(),
|
||||
response.Config.ShouldServeFromRclone(),
|
||||
response.Config.ShouldVerifyDownloadLink(),
|
||||
response.Config.ShouldForceIPv6(),
|
||||
response.Config.GetOnLibraryUpdate(),
|
||||
)
|
||||
|
||||
fmt.Fprint(resp, out)
|
||||
|
||||
13
internal/handlers/options.go
Normal file
13
internal/handlers/options.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package handlers
|
||||
|
||||
import "net/http"
|
||||
|
||||
func (hs *Handlers) options(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -39,7 +39,10 @@ func AttachHandlers(router *chi.Mux, downloader *universal.Downloader, torMgr *t
|
||||
log: log,
|
||||
}
|
||||
|
||||
router.Use(optionsMiddleware)
|
||||
if cfg.GetUsername() != "" {
|
||||
router.Use(hs.basicAuth)
|
||||
}
|
||||
router.Use(hs.options)
|
||||
|
||||
router.Get("/", hs.handleHome)
|
||||
// version
|
||||
@@ -283,16 +286,6 @@ func (hs *Handlers) moveTorrentHandler(resp http.ResponseWriter, req *http.Reque
|
||||
resp.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func optionsMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// universal handlers
|
||||
|
||||
func (hs *Handlers) handleDownloadFile(resp http.ResponseWriter, req *http.Request) {
|
||||
|
||||
@@ -133,11 +133,11 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
||||
if t.reinsertTorrent(torrent, "") {
|
||||
t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey)
|
||||
return
|
||||
} else if !torrent.Unfixable {
|
||||
t.log.Warnf("Failed to repair by reinserting torrent %s, will only redownload broken files...", torrent.AccessKey)
|
||||
} else {
|
||||
} else if torrent.Unfixable {
|
||||
t.log.Warnf("Cannot repair torrent %s", torrent.AccessKey)
|
||||
return
|
||||
} else {
|
||||
t.log.Warnf("Failed to repair by reinserting torrent %s, will only redownload broken files...", torrent.AccessKey)
|
||||
}
|
||||
} else {
|
||||
t.log.Warnf("Torrent %s is not older than %d hours to be repaired by reinsertion, will only redownload broken files...", torrent.AccessKey, EXPIRED_LINK_TOLERANCE_HOURS)
|
||||
@@ -210,9 +210,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
||||
})
|
||||
t.log.Debugf("During repair, zurg found %d broken files for torrent %s", len(brokenFiles), torrent.AccessKey)
|
||||
|
||||
// todo: to verify removed logic when there's only 1 selected file selected and it's broken
|
||||
|
||||
if len(brokenFiles) == 1 && torrent.SelectedFiles.Count() > 1 {
|
||||
if len(brokenFiles) == 1 && torrent.SelectedFiles.Count() > 2 {
|
||||
// if we download a single file, it will be named differently
|
||||
// so we need to download 1 extra file to preserve the name
|
||||
// this is only relevant if we enable retain_rd_torrent_name
|
||||
@@ -227,7 +225,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
||||
}
|
||||
|
||||
if len(brokenFiles) > 0 {
|
||||
t.log.Infof("Redownloading the %d broken files for torrent %s", len(brokenFiles), torrent.AccessKey)
|
||||
t.log.Infof("Redownloading %dof%d files for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), torrent.AccessKey)
|
||||
brokenFileIDs := strings.Join(getFileIDs(brokenFiles), ",")
|
||||
if t.reinsertTorrent(torrent, brokenFileIDs) {
|
||||
t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey)
|
||||
|
||||
Reference in New Issue
Block a user