diff --git a/Dockerfile b/Dockerfile index 14fd99b..deeef2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN yarn install && yarn run build ### FRONT BUILD END ### ### BUILD TORRSERVER MULTIARCH START ### -FROM --platform=$BUILDPLATFORM golang:1.17-alpine as builder +FROM --platform=$BUILDPLATFORM golang:1.18-alpine as builder COPY . /opt/src COPY --from=front /app/build /opt/src/web/build diff --git a/server/cmd/main.go b/server/cmd/main.go index 5686239..d193748 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -32,8 +32,9 @@ type args struct { DontKill bool `arg:"-k" help:"don't kill server on signal"` UI bool `arg:"-u" help:"open torrserver page in browser"` TorrentsDir string `arg:"-t" help:"autoload torrents from dir"` - IPv4 string `arg:"-4" help:"set public IPv4 addr"` - IPv6 string `arg:"-6" help:"set public IPv6 addr"` + TorrentAddr string `default:":32000" help:"Torrent client address"` + PubIPv4 string `arg:"-4" help:"set public IPv4 addr"` + PubIPv6 string `arg:"-6" help:"set public IPv6 addr"` } func (args) Version() string { @@ -74,12 +75,16 @@ func main() { }() } - if params.IPv4 != "" { - settings.PubIPv4 = params.IPv4 + if params.TorrentAddr != "" { + settings.TorAddr = params.TorrentAddr } - if params.IPv6 != "" { - settings.PubIPv6 = params.IPv6 + if params.PubIPv4 != "" { + settings.PubIPv4 = params.PubIPv4 + } + + if params.PubIPv6 != "" { + settings.PubIPv6 = params.PubIPv6 } if params.TorrentsDir != "" { diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index 6c45aea..59a033e 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -140,6 +140,11 @@ func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (r func getDefaultFriendlyName() string { logger := log.Default.WithNames("dlna") + + if settings.BTsets.FriendlyName != "" { + return settings.BTsets.FriendlyName + } + ret := "TorrServer" userName := "" user, err := user.Current() diff --git a/server/go.mod b/server/go.mod index 5623273..445ded5 100644 --- a/server/go.mod +++ b/server/go.mod @@ -12,6 +12,7 @@ require ( github.com/anacrolix/dms v1.4.0 github.com/anacrolix/log v0.13.1 github.com/anacrolix/missinggo v1.3.0 + github.com/anacrolix/publicip v0.2.0 github.com/anacrolix/torrent v1.43.1 github.com/gin-contrib/cors v1.3.1 github.com/gin-contrib/location v0.0.2 diff --git a/server/go.sum b/server/go.sum index 442ec90..81ad4b2 100644 --- a/server/go.sum +++ b/server/go.sum @@ -50,6 +50,8 @@ github.com/anacrolix/missinggo/v2 v2.7.0 h1:4fzOAAn/VCvfWGviLmh64MPMttrlYew81JdP github.com/anacrolix/missinggo/v2 v2.7.0/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI= github.com/anacrolix/multiless v0.3.0 h1:5Bu0DZncjE4e06b9r1Ap2tUY4Au0NToBP5RpuEngSis= github.com/anacrolix/multiless v0.3.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4= +github.com/anacrolix/publicip v0.2.0 h1:n/BmRxXRlOT/wQFd6Xhu57r9uTU+Xvb9MyEkLooh3TU= +github.com/anacrolix/publicip v0.2.0/go.mod h1:67G1lVkLo8UjdEcJkwScWVTvlJ35OCDsRJoWXl/wi4g= github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg= github.com/anacrolix/stm v0.3.0 h1:peQncJSNJtk1YBrFbW0DLKYqll+sa0kOk8EvXRcO+wA= github.com/anacrolix/stm v0.3.0/go.mod h1:spImf/rXwiAUoYYJK1YCZeWkpaHZ3kzjGFjwK5OStfU= diff --git a/server/settings/btsets.go b/server/settings/btsets.go index 68a6008..bad2116 100644 --- a/server/settings/btsets.go +++ b/server/settings/btsets.go @@ -28,7 +28,8 @@ type BTSets struct { EnableDebug bool // print logs // DLNA - EnableDLNA bool + EnableDLNA bool + FriendlyName string // BT Config EnableIPv6 bool diff --git a/server/settings/settings.go b/server/settings/settings.go index 218de68..a59be07 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -15,6 +15,7 @@ var ( HttpAuth bool PubIPv4 string PubIPv6 string + TorAddr string ) func InitSets(readOnly bool) { diff --git a/server/torr/apihelper.go b/server/torr/apihelper.go index 272f654..93d9ee2 100644 --- a/server/torr/apihelper.go +++ b/server/torr/apihelper.go @@ -196,12 +196,12 @@ func SetSettings(set *sets.BTSets) { sets.SetBTSets(set) log.TLogln("drop all torrents") dropAllTorrent() - time.Sleep(time.Second * 2) + time.Sleep(time.Second * 1) log.TLogln("disconect") bts.Disconnect() log.TLogln("connect") bts.Connect() - time.Sleep(time.Second * 2) + time.Sleep(time.Second * 1) log.TLogln("end set settings") } @@ -212,12 +212,12 @@ func SetDefSettings() { sets.SetDefault() log.TLogln("drop all torrents") dropAllTorrent() - time.Sleep(time.Second * 2) + time.Sleep(time.Second * 1) log.TLogln("disconect") bts.Disconnect() log.TLogln("connect") bts.Connect() - time.Sleep(time.Second * 2) + time.Sleep(time.Second * 1) log.TLogln("end set default settings") } diff --git a/server/torr/btserver.go b/server/torr/btserver.go index 1e17772..d045daf 100644 --- a/server/torr/btserver.go +++ b/server/torr/btserver.go @@ -1,12 +1,14 @@ package torr import ( + "context" "fmt" "log" "net" "strconv" "sync" + "github.com/anacrolix/publicip" "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" @@ -58,7 +60,7 @@ func (bt *BTServer) Connect() error { bt.mu.Lock() defer bt.mu.Unlock() var err error - bt.configure() + bt.configure(context.TODO()) bt.client, err = torrent.NewClient(bt.config) bt.torrents = make(map[metainfo.Hash]*Torrent) InitApiHelper(bt) @@ -75,7 +77,7 @@ func (bt *BTServer) Disconnect() { } } -func (bt *BTServer) configure() { +func (bt *BTServer) configure(ctx context.Context) (err error) { blocklist, _ := utils.ReadBlockedIP() bt.config = torrent.NewDefaultClientConfig() @@ -121,24 +123,28 @@ func (bt *BTServer) configure() { if settings.BTsets.UploadRateLimit > 0 { bt.config.UploadRateLimiter = utils.Limit(settings.BTsets.UploadRateLimit * 1024) } - if settings.BTsets.PeersListenPort > 0 { - log.Println("Set listen port", settings.BTsets.PeersListenPort) - bt.config.ListenPort = settings.BTsets.PeersListenPort + if settings.TorAddr != "" { + bt.config.SetListenAddr(settings.TorAddr) } else { - upnpport := 32000 - for { - log.Println("Check upnp port", upnpport) - l, err := net.Listen("tcp", ":"+strconv.Itoa(upnpport)) - if l != nil { - l.Close() + if settings.BTsets.PeersListenPort > 0 { + log.Println("Set listen port", settings.BTsets.PeersListenPort) + bt.config.ListenPort = settings.BTsets.PeersListenPort + } else { + upnpport := 32000 + for { + log.Println("Check upnp port", upnpport) + l, err := net.Listen("tcp", ":"+strconv.Itoa(upnpport)) + if l != nil { + l.Close() + } + if err == nil { + break + } + upnpport++ } - if err == nil { - break - } - upnpport++ + log.Println("Set upnp port", upnpport) + bt.config.ListenPort = upnpport } - log.Println("Set upnp port", upnpport) - bt.config.ListenPort = upnpport } log.Println("Client config:", settings.BTsets) @@ -150,7 +156,10 @@ func (bt *BTServer) configure() { } } if bt.config.PublicIp4 == nil { - bt.config.PublicIp4 = getPublicIp4() + bt.config.PublicIp4, err = publicip.Get4(ctx) + if err != nil { + log.Printf("error getting public ipv4 address: %v", err) + } } if bt.config.PublicIp4 != nil { log.Println("PublicIp4:", bt.config.PublicIp4) @@ -163,11 +172,15 @@ func (bt *BTServer) configure() { } } if bt.config.PublicIp6 == nil { - bt.config.PublicIp6 = getPublicIp6() + bt.config.PublicIp6, err = publicip.Get6(ctx) + if err != nil { + log.Printf("error getting public ipv6 address: %v", err) + } } if bt.config.PublicIp6 != nil { log.Println("PublicIp6:", bt.config.PublicIp6) } + return err } func (bt *BTServer) GetTorrent(hash torrent.InfoHash) *Torrent { diff --git a/server/torr/preload.go b/server/torr/preload.go index 86bb75f..6e9a2be 100644 --- a/server/torr/preload.go +++ b/server/torr/preload.go @@ -63,17 +63,17 @@ func (t *Torrent) Preload(index int, size int64) { } }() - // mb5 -> 8/16 MB - mb5 := int64(t.Info().PieceLength) - if mb5 < 8*1024*1024 { - mb5 = 8 * 1024 * 1024 + // startend -> 8/16 MB + startend := int64(t.Info().PieceLength) + if startend < 8*1024*1024 { + startend = 8 * 1024 * 1024 } readerStart := file.NewReader() defer readerStart.Close() readerStart.SetResponsive() readerStart.SetReadahead(0) - readerStartEnd := size - mb5 + readerStartEnd := size - startend if readerStartEnd < 0 { // Если конец начального ридера оказался за началом @@ -84,7 +84,7 @@ func (t *Torrent) Preload(index int, size int64) { readerStartEnd = file.Length() } - readerEndStart := file.Length() - mb5 + readerEndStart := file.Length() - startend readerEndEnd := file.Length() var wa sync.WaitGroup diff --git a/server/torr/storage/torrstor/cache.go b/server/torr/storage/torrstor/cache.go index 1a5f56b..9326cd8 100644 --- a/server/torr/storage/torrstor/cache.go +++ b/server/torr/storage/torrstor/cache.go @@ -255,9 +255,9 @@ func (c *Cache) getRemPieces() []*Piece { readerPos := r.getReaderPiece() readerRAHPos := r.getReaderRAHPiece() end := r.getPiecesRange().End - count := int(16 * 1024 * 1024 / c.pieceLength * 5) // 80 MB - if count > 40 { - count = 40 + count := int(16 * 1024 * 1024 * 4 / c.pieceLength) // 64 MB window + if count > 64 { + count = 64 } limit := 0 for i := readerPos; i < end && limit < count; i++ { diff --git a/server/torr/stream.go b/server/torr/stream.go index 3d35cd0..8817178 100644 --- a/server/torr/stream.go +++ b/server/torr/stream.go @@ -62,7 +62,8 @@ func (t *Torrent) Stream(fileID int, req *http.Request, resp http.ResponseWriter sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileID}) resp.Header().Set("Connection", "close") - resp.Header().Set("ETag", httptoo.EncodeQuotedString(fmt.Sprintf("%s/%s", t.Hash().HexString(), hex.EncodeToString([]byte(file.Path()))))) + etag := hex.EncodeToString([]byte(fmt.Sprintf("%s/%s", t.Hash().HexString(), file.Path()))) + resp.Header().Set("ETag", httptoo.EncodeQuotedString(etag)) // DLNA headers resp.Header().Set("transferMode.dlna.org", "Streaming") mime, err := mt.MimeTypeByPath(file.Path()) diff --git a/server/torr/torrent.go b/server/torr/torrent.go index 535eaa1..7be01c4 100644 --- a/server/torr/torrent.go +++ b/server/torr/torrent.go @@ -50,8 +50,8 @@ type Torrent struct { } func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) { - // TODO panic when settings sets - if bt == nil { + // https://github.com/anacrolix/torrent/issues/747 + if bt == nil || bt.client == nil { return nil, errors.New("BT client not connected") } switch settings.BTsets.RetrackersMode { diff --git a/server/web/api/m3u.go b/server/web/api/m3u.go index 7dd6b57..afce025 100644 --- a/server/web/api/m3u.go +++ b/server/web/api/m3u.go @@ -73,7 +73,8 @@ func sendM3U(c *gin.Context, name, hash string, m3u string) { c.Header("Content-Type", "audio/x-mpegurl") c.Header("Connection", "close") if hash != "" { - c.Header("ETag", httptoo.EncodeQuotedString(fmt.Sprintf("%s/%s", hash, hex.EncodeToString([]byte(name))))) + etag := hex.EncodeToString([]byte(fmt.Sprintf("%s/%s", hash, name))) + c.Header("ETag", httptoo.EncodeQuotedString(etag)) } if name == "" { name = "playlist.m3u" diff --git a/server/web/server.go b/server/web/server.go index 1909c84..6a75da6 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -30,7 +30,7 @@ func Start(port string) { log.TLogln("Start TorrServer") ips := getLocalIps() if len(ips) > 0 { - log.TLogln("IPs:", ips) + log.TLogln("Local IPs:", ips) } err := BTS.Connect() if err != nil { @@ -102,7 +102,7 @@ func getLocalIps() []string { case *net.IPAddr: ip = v.IP } - if !ip.IsLoopback() { + if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsLinkLocalMulticast() { list = append(list, ip.String()) } } diff --git a/web/src/components/Settings/SecondarySettingsComponent.jsx b/web/src/components/Settings/SecondarySettingsComponent.jsx index 8f977a7..56d2638 100644 --- a/web/src/components/Settings/SecondarySettingsComponent.jsx +++ b/web/src/components/Settings/SecondarySettingsComponent.jsx @@ -10,8 +10,10 @@ export default function SecondarySettingsComponent({ settings, inputForm }) { const { RetrackersMode, TorrentDisconnectTimeout, + EnableDebug, EnableDLNA, EnableIPv6, + FriendlyName, ForceEncrypt, DisableTCP, DisableUTP, @@ -139,6 +141,22 @@ export default function SecondarySettingsComponent({ settings, inputForm }) { label={t('SettingsDialog.DLNA')} labelPlacement='start' /> + + } + label={t('SettingsDialog.EnableDebug')} + labelPlacement='start' + />
{t('SettingsDialog.RetrackersMode')}