Merge branch 'master' into old-engine

This commit is contained in:
nikk gitanes
2022-05-25 23:17:51 +03:00
21 changed files with 105 additions and 47 deletions

View File

@@ -7,7 +7,7 @@ RUN yarn install && yarn run build
### FRONT BUILD END ### ### FRONT BUILD END ###
### BUILD TORRSERVER MULTIARCH START ### ### 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 . /opt/src
COPY --from=front /app/build /opt/src/web/build COPY --from=front /app/build /opt/src/web/build

View File

@@ -32,8 +32,9 @@ type args struct {
DontKill bool `arg:"-k" help:"don't kill server on signal"` DontKill bool `arg:"-k" help:"don't kill server on signal"`
UI bool `arg:"-u" help:"open torrserver page in browser"` UI bool `arg:"-u" help:"open torrserver page in browser"`
TorrentsDir string `arg:"-t" help:"autoload torrents from dir"` TorrentsDir string `arg:"-t" help:"autoload torrents from dir"`
IPv4 string `arg:"-4" help:"set public IPv4 addr"` TorrentAddr string `default:":32000" help:"Torrent client address"`
IPv6 string `arg:"-6" help:"set public IPv6 addr"` PubIPv4 string `arg:"-4" help:"set public IPv4 addr"`
PubIPv6 string `arg:"-6" help:"set public IPv6 addr"`
} }
func (args) Version() string { func (args) Version() string {
@@ -74,12 +75,16 @@ func main() {
}() }()
} }
if params.IPv4 != "" { if params.TorrentAddr != "" {
settings.PubIPv4 = params.IPv4 settings.TorAddr = params.TorrentAddr
} }
if params.IPv6 != "" { if params.PubIPv4 != "" {
settings.PubIPv6 = params.IPv6 settings.PubIPv4 = params.PubIPv4
}
if params.PubIPv6 != "" {
settings.PubIPv6 = params.PubIPv6
} }
if params.TorrentsDir != "" { if params.TorrentsDir != "" {

View File

@@ -140,6 +140,11 @@ func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (r
func getDefaultFriendlyName() string { func getDefaultFriendlyName() string {
logger := log.Default.WithNames("dlna") logger := log.Default.WithNames("dlna")
if settings.BTsets.FriendlyName != "" {
return settings.BTsets.FriendlyName
}
ret := "TorrServer" ret := "TorrServer"
userName := "" userName := ""
user, err := user.Current() user, err := user.Current()

View File

@@ -12,6 +12,7 @@ require (
github.com/anacrolix/dms v1.4.0 github.com/anacrolix/dms v1.4.0
github.com/anacrolix/log v0.13.1 github.com/anacrolix/log v0.13.1
github.com/anacrolix/missinggo v1.3.0 github.com/anacrolix/missinggo v1.3.0
github.com/anacrolix/publicip v0.2.0
github.com/anacrolix/torrent v1.43.1 github.com/anacrolix/torrent v1.43.1
github.com/gin-contrib/cors v1.3.1 github.com/gin-contrib/cors v1.3.1
github.com/gin-contrib/location v0.0.2 github.com/gin-contrib/location v0.0.2

View File

@@ -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/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 h1:5Bu0DZncjE4e06b9r1Ap2tUY4Au0NToBP5RpuEngSis=
github.com/anacrolix/multiless v0.3.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4= 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.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
github.com/anacrolix/stm v0.3.0 h1:peQncJSNJtk1YBrFbW0DLKYqll+sa0kOk8EvXRcO+wA= github.com/anacrolix/stm v0.3.0 h1:peQncJSNJtk1YBrFbW0DLKYqll+sa0kOk8EvXRcO+wA=
github.com/anacrolix/stm v0.3.0/go.mod h1:spImf/rXwiAUoYYJK1YCZeWkpaHZ3kzjGFjwK5OStfU= github.com/anacrolix/stm v0.3.0/go.mod h1:spImf/rXwiAUoYYJK1YCZeWkpaHZ3kzjGFjwK5OStfU=

View File

@@ -28,7 +28,8 @@ type BTSets struct {
EnableDebug bool // print logs EnableDebug bool // print logs
// DLNA // DLNA
EnableDLNA bool EnableDLNA bool
FriendlyName string
// BT Config // BT Config
EnableIPv6 bool EnableIPv6 bool

View File

@@ -15,6 +15,7 @@ var (
HttpAuth bool HttpAuth bool
PubIPv4 string PubIPv4 string
PubIPv6 string PubIPv6 string
TorAddr string
) )
func InitSets(readOnly bool) { func InitSets(readOnly bool) {

View File

@@ -196,12 +196,12 @@ func SetSettings(set *sets.BTSets) {
sets.SetBTSets(set) sets.SetBTSets(set)
log.TLogln("drop all torrents") log.TLogln("drop all torrents")
dropAllTorrent() dropAllTorrent()
time.Sleep(time.Second * 2) time.Sleep(time.Second * 1)
log.TLogln("disconect") log.TLogln("disconect")
bts.Disconnect() bts.Disconnect()
log.TLogln("connect") log.TLogln("connect")
bts.Connect() bts.Connect()
time.Sleep(time.Second * 2) time.Sleep(time.Second * 1)
log.TLogln("end set settings") log.TLogln("end set settings")
} }
@@ -212,12 +212,12 @@ func SetDefSettings() {
sets.SetDefault() sets.SetDefault()
log.TLogln("drop all torrents") log.TLogln("drop all torrents")
dropAllTorrent() dropAllTorrent()
time.Sleep(time.Second * 2) time.Sleep(time.Second * 1)
log.TLogln("disconect") log.TLogln("disconect")
bts.Disconnect() bts.Disconnect()
log.TLogln("connect") log.TLogln("connect")
bts.Connect() bts.Connect()
time.Sleep(time.Second * 2) time.Sleep(time.Second * 1)
log.TLogln("end set default settings") log.TLogln("end set default settings")
} }

View File

@@ -1,12 +1,14 @@
package torr package torr
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"net" "net"
"strconv" "strconv"
"sync" "sync"
"github.com/anacrolix/publicip"
"github.com/anacrolix/torrent" "github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
@@ -58,7 +60,7 @@ func (bt *BTServer) Connect() error {
bt.mu.Lock() bt.mu.Lock()
defer bt.mu.Unlock() defer bt.mu.Unlock()
var err error var err error
bt.configure() bt.configure(context.TODO())
bt.client, err = torrent.NewClient(bt.config) bt.client, err = torrent.NewClient(bt.config)
bt.torrents = make(map[metainfo.Hash]*Torrent) bt.torrents = make(map[metainfo.Hash]*Torrent)
InitApiHelper(bt) 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() blocklist, _ := utils.ReadBlockedIP()
bt.config = torrent.NewDefaultClientConfig() bt.config = torrent.NewDefaultClientConfig()
@@ -121,24 +123,28 @@ func (bt *BTServer) configure() {
if settings.BTsets.UploadRateLimit > 0 { if settings.BTsets.UploadRateLimit > 0 {
bt.config.UploadRateLimiter = utils.Limit(settings.BTsets.UploadRateLimit * 1024) bt.config.UploadRateLimiter = utils.Limit(settings.BTsets.UploadRateLimit * 1024)
} }
if settings.BTsets.PeersListenPort > 0 { if settings.TorAddr != "" {
log.Println("Set listen port", settings.BTsets.PeersListenPort) bt.config.SetListenAddr(settings.TorAddr)
bt.config.ListenPort = settings.BTsets.PeersListenPort
} else { } else {
upnpport := 32000 if settings.BTsets.PeersListenPort > 0 {
for { log.Println("Set listen port", settings.BTsets.PeersListenPort)
log.Println("Check upnp port", upnpport) bt.config.ListenPort = settings.BTsets.PeersListenPort
l, err := net.Listen("tcp", ":"+strconv.Itoa(upnpport)) } else {
if l != nil { upnpport := 32000
l.Close() 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 { log.Println("Set upnp port", upnpport)
break bt.config.ListenPort = upnpport
}
upnpport++
} }
log.Println("Set upnp port", upnpport)
bt.config.ListenPort = upnpport
} }
log.Println("Client config:", settings.BTsets) log.Println("Client config:", settings.BTsets)
@@ -150,7 +156,10 @@ func (bt *BTServer) configure() {
} }
} }
if bt.config.PublicIp4 == nil { 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 { if bt.config.PublicIp4 != nil {
log.Println("PublicIp4:", bt.config.PublicIp4) log.Println("PublicIp4:", bt.config.PublicIp4)
@@ -163,11 +172,15 @@ func (bt *BTServer) configure() {
} }
} }
if bt.config.PublicIp6 == nil { 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 { if bt.config.PublicIp6 != nil {
log.Println("PublicIp6:", bt.config.PublicIp6) log.Println("PublicIp6:", bt.config.PublicIp6)
} }
return err
} }
func (bt *BTServer) GetTorrent(hash torrent.InfoHash) *Torrent { func (bt *BTServer) GetTorrent(hash torrent.InfoHash) *Torrent {

View File

@@ -63,17 +63,17 @@ func (t *Torrent) Preload(index int, size int64) {
} }
}() }()
// mb5 -> 8/16 MB // startend -> 8/16 MB
mb5 := int64(t.Info().PieceLength) startend := int64(t.Info().PieceLength)
if mb5 < 8*1024*1024 { if startend < 8*1024*1024 {
mb5 = 8 * 1024 * 1024 startend = 8 * 1024 * 1024
} }
readerStart := file.NewReader() readerStart := file.NewReader()
defer readerStart.Close() defer readerStart.Close()
readerStart.SetResponsive() readerStart.SetResponsive()
readerStart.SetReadahead(0) readerStart.SetReadahead(0)
readerStartEnd := size - mb5 readerStartEnd := size - startend
if readerStartEnd < 0 { if readerStartEnd < 0 {
// Если конец начального ридера оказался за началом // Если конец начального ридера оказался за началом
@@ -84,7 +84,7 @@ func (t *Torrent) Preload(index int, size int64) {
readerStartEnd = file.Length() readerStartEnd = file.Length()
} }
readerEndStart := file.Length() - mb5 readerEndStart := file.Length() - startend
readerEndEnd := file.Length() readerEndEnd := file.Length()
var wa sync.WaitGroup var wa sync.WaitGroup

View File

@@ -255,9 +255,9 @@ func (c *Cache) getRemPieces() []*Piece {
readerPos := r.getReaderPiece() readerPos := r.getReaderPiece()
readerRAHPos := r.getReaderRAHPiece() readerRAHPos := r.getReaderRAHPiece()
end := r.getPiecesRange().End end := r.getPiecesRange().End
count := int(16 * 1024 * 1024 / c.pieceLength * 5) // 80 MB count := int(16 * 1024 * 1024 * 4 / c.pieceLength) // 64 MB window
if count > 40 { if count > 64 {
count = 40 count = 64
} }
limit := 0 limit := 0
for i := readerPos; i < end && limit < count; i++ { for i := readerPos; i < end && limit < count; i++ {

View File

@@ -62,7 +62,8 @@ func (t *Torrent) Stream(fileID int, req *http.Request, resp http.ResponseWriter
sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileID}) sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileID})
resp.Header().Set("Connection", "close") 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 // DLNA headers
resp.Header().Set("transferMode.dlna.org", "Streaming") resp.Header().Set("transferMode.dlna.org", "Streaming")
mime, err := mt.MimeTypeByPath(file.Path()) mime, err := mt.MimeTypeByPath(file.Path())

View File

@@ -50,8 +50,8 @@ type Torrent struct {
} }
func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) { func NewTorrent(spec *torrent.TorrentSpec, bt *BTServer) (*Torrent, error) {
// TODO panic when settings sets // https://github.com/anacrolix/torrent/issues/747
if bt == nil { if bt == nil || bt.client == nil {
return nil, errors.New("BT client not connected") return nil, errors.New("BT client not connected")
} }
switch settings.BTsets.RetrackersMode { switch settings.BTsets.RetrackersMode {

View File

@@ -73,7 +73,8 @@ func sendM3U(c *gin.Context, name, hash string, m3u string) {
c.Header("Content-Type", "audio/x-mpegurl") c.Header("Content-Type", "audio/x-mpegurl")
c.Header("Connection", "close") c.Header("Connection", "close")
if hash != "" { 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 == "" { if name == "" {
name = "playlist.m3u" name = "playlist.m3u"

View File

@@ -30,7 +30,7 @@ func Start(port string) {
log.TLogln("Start TorrServer") log.TLogln("Start TorrServer")
ips := getLocalIps() ips := getLocalIps()
if len(ips) > 0 { if len(ips) > 0 {
log.TLogln("IPs:", ips) log.TLogln("Local IPs:", ips)
} }
err := BTS.Connect() err := BTS.Connect()
if err != nil { if err != nil {
@@ -102,7 +102,7 @@ func getLocalIps() []string {
case *net.IPAddr: case *net.IPAddr:
ip = v.IP ip = v.IP
} }
if !ip.IsLoopback() { if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsLinkLocalMulticast() {
list = append(list, ip.String()) list = append(list, ip.String())
} }
} }

View File

@@ -10,8 +10,10 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
const { const {
RetrackersMode, RetrackersMode,
TorrentDisconnectTimeout, TorrentDisconnectTimeout,
EnableDebug,
EnableDLNA, EnableDLNA,
EnableIPv6, EnableIPv6,
FriendlyName,
ForceEncrypt, ForceEncrypt,
DisableTCP, DisableTCP,
DisableUTP, DisableUTP,
@@ -139,6 +141,22 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
label={t('SettingsDialog.DLNA')} label={t('SettingsDialog.DLNA')}
labelPlacement='start' labelPlacement='start'
/> />
<TextField
onChange={inputForm}
margin='normal'
id='FriendlyName'
label={t('SettingsDialog.FriendlyName')}
helperText={t('SettingsDialog.FriendlyNameHint')}
value={FriendlyName}
type='text'
variant='outlined'
fullWidth
/>
<FormControlLabel
control={<Switch checked={EnableDebug} onChange={inputForm} id='EnableDebug' color='secondary' />}
label={t('SettingsDialog.EnableDebug')}
labelPlacement='start'
/>
<br /> <br />
<InputLabel htmlFor='RetrackersMode'>{t('SettingsDialog.RetrackersMode')}</InputLabel> <InputLabel htmlFor='RetrackersMode'>{t('SettingsDialog.RetrackersMode')}</InputLabel>
<Select <Select

View File

@@ -61,7 +61,7 @@ export default function SettingsDialog({ handleClose }) {
) )
sets[id] = Boolean(!checked) sets[id] = Boolean(!checked)
else sets[id] = Boolean(checked) else sets[id] = Boolean(checked)
} else if (type === 'url') { } else if (type === 'url' || type === 'text') {
sets[id] = value sets[id] = value
} }
setSettings(sets) setSettings(sets)

View File

@@ -14,6 +14,7 @@ export default {
DownloadRateLimit: 0, DownloadRateLimit: 0,
EnableDebug: false, EnableDebug: false,
EnableIPv6: false, EnableIPv6: false,
FriendlyName: '',
ForceEncrypt: false, ForceEncrypt: false,
PeersListenPort: 0, PeersListenPort: 0,
PreloadCache: 50, PreloadCache: 50,

View File

@@ -100,7 +100,10 @@
"DLNA": "DLNA Media Server", "DLNA": "DLNA Media Server",
"DontAddRetrackers": "Don`t add retrackers", "DontAddRetrackers": "Don`t add retrackers",
"DownloadRateLimit": "Download Rate Limit", "DownloadRateLimit": "Download Rate Limit",
"EnableDebug": "Enable Debug Server Log",
"ForceEncrypt": "Force Encrypt Headers", "ForceEncrypt": "Force Encrypt Headers",
"FriendlyName": "DLNA Server Name",
"FriendlyNameHint": "Leave blank to use default",
"PeersListenPort": "Peers Listen Port", "PeersListenPort": "Peers Listen Port",
"PeersListenPortHint": "1024 - 65535, 0 - auto", "PeersListenPortHint": "1024 - 65535, 0 - auto",
"PreloadCache": "Preload Cache Before Play", "PreloadCache": "Preload Cache Before Play",

View File

@@ -100,7 +100,10 @@
"DLNA": "DLNA-медиасервер", "DLNA": "DLNA-медиасервер",
"DontAddRetrackers": "Ничего не делать", "DontAddRetrackers": "Ничего не делать",
"DownloadRateLimit": "Ограничение скорости загрузки", "DownloadRateLimit": "Ограничение скорости загрузки",
"EnableDebug": "Включить подробный журнал сервера",
"ForceEncrypt": "Принудительное шифрование заголовков", "ForceEncrypt": "Принудительное шифрование заголовков",
"FriendlyName": "Имя сервера DLNA",
"FriendlyNameHint": "Оставьте пустым, чтобы использовать значение по умолчанию.",
"PeersListenPort": "Порт для входящих подключений", "PeersListenPort": "Порт для входящих подключений",
"PeersListenPortHint": "1024 - 65535, 0 - авто", "PeersListenPortHint": "1024 - 65535, 0 - авто",
"PreloadCache": "Буфер предзагрузки", "PreloadCache": "Буфер предзагрузки",

View File

@@ -100,7 +100,10 @@
"DLNA": "DLNA-медиасервер", "DLNA": "DLNA-медиасервер",
"DontAddRetrackers": "Нічого не робити", "DontAddRetrackers": "Нічого не робити",
"DownloadRateLimit": "Обмеження швидкості завантаження", "DownloadRateLimit": "Обмеження швидкості завантаження",
"EnableDebug": "Увімкнути журнал налагодження сервера",
"ForceEncrypt": "Примусово шифрувати заголовки", "ForceEncrypt": "Примусово шифрувати заголовки",
"FriendlyName": "Ім'я сервера DLNA",
"FriendlyNameHint": "Залиште порожнім, щоб використовувати значення за промовчанням.",
"PeersListenPort": "Порт для вхідних з'єднань", "PeersListenPort": "Порт для вхідних з'єднань",
"PeersListenPortHint": "1024 - 65535, 0 - авто", "PeersListenPortHint": "1024 - 65535, 0 - авто",
"PreloadCache": "Буфер попер. завантаження", "PreloadCache": "Буфер попер. завантаження",