diff --git a/.env.example b/.env.example index 57f8c4f9..782c794a 100644 --- a/.env.example +++ b/.env.example @@ -21,6 +21,7 @@ TS_TORR_DIR=/opt/ts/torrents # Feature flags — set to 1 to enable TS_HTTPAUTH=0 +TS_STREAMWA=0 TS_RDB=0 TS_DONTKILL=0 diff --git a/docker-compose.yml b/docker-compose.yml index d3342450..e4fd60ae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,7 @@ services: # Feature flags — set to "1" to enable (see docker-entrypoint.sh) TS_HTTPAUTH: ${TS_HTTPAUTH:-0} # basic auth; place auth file in TS_CONF_PATH + TS_STREAMWA: ${TS_STREAMWA:-0} # allow /stream play and /play without auth TS_RDB: ${TS_RDB:-0} # remote debug (`--rdb`) TS_DONTKILL: ${TS_DONTKILL:-0} # keep torrents after last client disconnects diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 8450a9f0..f30132c1 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,6 +3,7 @@ FLAGS="--path $TS_CONF_PATH --logpath $TS_LOG_PATH --port $TS_PORT --torrentsdir $TS_TORR_DIR" if [ -n "$TS_IP" ]; then FLAGS="${FLAGS} -i ${TS_IP}"; fi if [ "$TS_HTTPAUTH" = "1" ]; then FLAGS="${FLAGS} --httpauth"; fi +if [ "$TS_STREAMWA" = "1" ]; then FLAGS="${FLAGS} --streamwa"; fi if [ "$TS_RDB" = "1" ]; then FLAGS="${FLAGS} --rdb"; fi if [ "$TS_DONTKILL" = "1" ]; then FLAGS="${FLAGS} --dontkill"; fi if [ "$TS_EN_SSL" = "1" ]; then FLAGS="${FLAGS} --ssl"; fi diff --git a/server/cmd/main.go b/server/cmd/main.go index 587221ba..2107b646 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -45,6 +45,7 @@ type args struct { PubIPv4 string `arg:"-4" help:"set public IPv4 addr"` PubIPv6 string `arg:"-6" help:"set public IPv6 addr"` SearchWA bool `arg:"-s" help:"search without auth"` + StreamWA bool `arg:"--streamwa" help:"stream play and m3u without auth (auto-add torrents for external players)"` MaxSize string `arg:"-m" help:"max allowed stream size (in Bytes)"` TGToken string `arg:"-T" help:"telegram bot token"` FusePath string `arg:"-f" help:"fuse mount path"` @@ -82,6 +83,9 @@ func main() { if params.HttpAuth { log.TLogln("Use HTTP Auth file", settings.Path+"/accs.db") } + if params.StreamWA { + log.TLogln("Stream play/m3u allowed without auth (streamwa)") + } if params.RDB { log.TLogln("Running in Read-only DB mode!") } @@ -167,6 +171,7 @@ func main() { PubIPv4: params.PubIPv4, PubIPv6: params.PubIPv6, SearchWA: params.SearchWA, + StreamWA: params.StreamWA, MaxSize: params.MaxSize, TGToken: params.TGToken, FusePath: params.FusePath, diff --git a/server/server.go b/server/server.go index 2c487a30..d3802a65 100644 --- a/server/server.go +++ b/server/server.go @@ -16,7 +16,7 @@ import ( ) func Start() { - settings.InitSets(settings.Args.RDB, settings.Args.SearchWA) + settings.InitSets(settings.Args.RDB, settings.Args.SearchWA, settings.Args.StreamWA) // https checks if settings.Args.Ssl { // set settings ssl enabled diff --git a/server/settings/args.go b/server/settings/args.go index eea82775..f4cbb8c8 100644 --- a/server/settings/args.go +++ b/server/settings/args.go @@ -19,6 +19,7 @@ type ExecArgs struct { PubIPv4 string PubIPv6 string SearchWA bool + StreamWA bool MaxSize string TGToken string FusePath string diff --git a/server/settings/settings.go b/server/settings/settings.go index 982c9ea5..395968c2 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -31,15 +31,17 @@ var ( ReadOnly bool HttpAuth bool SearchWA bool + StreamWA bool PubIPv4 string PubIPv6 string TorAddr string MaxSize int64 ) -func InitSets(readOnly, searchWA bool) { +func InitSets(readOnly, searchWA, streamWA bool) { ReadOnly = readOnly SearchWA = searchWA + StreamWA = streamWA bboltDB := NewTDB() if bboltDB == nil { diff --git a/server/web/api/play.go b/server/web/api/play.go index 153a0485..256d825b 100644 --- a/server/web/api/play.go +++ b/server/web/api/play.go @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" + sets "server/settings" "server/torr" "server/torr/state" "server/web/api/utils" @@ -43,9 +44,16 @@ func play(c *gin.Context) { tor := torr.GetTorrent(spec.InfoHash.HexString()) if tor == nil && notAuth { - c.Header("WWW-Authenticate", "Basic realm=Authorization Required") - c.AbortWithStatus(http.StatusUnauthorized) - return + if !sets.StreamWA { + c.Header("WWW-Authenticate", "Basic realm=Authorization Required") + c.AbortWithStatus(http.StatusUnauthorized) + return + } + tor, err = torr.AddTorrent(spec, "", "", "", "") + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return + } } if tor == nil { diff --git a/server/web/api/stream.go b/server/web/api/stream.go index 14d9f7b2..4fe666dc 100644 --- a/server/web/api/stream.go +++ b/server/web/api/stream.go @@ -10,6 +10,7 @@ import ( "server/torr" "server/torr/state" + sets "server/settings" utils2 "server/utils" "server/web/api/utils" @@ -250,9 +251,16 @@ func streamNoAuth(c *gin.Context) { tor := torr.GetTorrent(spec.InfoHash.HexString()) if tor == nil { - c.Header("WWW-Authenticate", "Basic realm=Authorization Required") - c.AbortWithStatus(http.StatusUnauthorized) - return + if !sets.StreamWA { + c.Header("WWW-Authenticate", "Basic realm=Authorization Required") + c.AbortWithStatus(http.StatusUnauthorized) + return + } + tor, err = torr.AddTorrent(spec, title, poster, "", category) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return + } } if title == "" {