diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index 6e43f45..9bdd7e4 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -7,13 +7,12 @@ import ( "os" "os/user" "path/filepath" + "runtime" "time" "github.com/anacrolix/dms/dlna/dms" - "github.com/anacrolix/dms/upnpav" "server/log" - "server/torr" "server/web/pages/template" ) @@ -23,11 +22,18 @@ func Start() { dmsServer = &dms.Server{ Interfaces: func() (ifs []net.Interface) { var err error - ifs, err = net.Interfaces() + ifaces, err := net.Interfaces() if err != nil { log.TLogln(err) os.Exit(1) } + for _, i := range ifaces { + // interface flags seem to always be 0 on Windows + if runtime.GOOS != "windows" && (i.Flags&net.FlagLoopback != 0 || i.Flags&net.FlagUp == 0 || i.Flags&net.FlagMulticast == 0) { + continue + } + ifs = append(ifs, i) + } return }(), HTTPConn: func() net.Listener { @@ -121,34 +127,6 @@ func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{}, } func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (ret interface{}, err error) { - if path == "/" { - rootObj := upnpav.Object{ - ID: "0", - ParentID: "-1", - Restricted: 1, - Searchable: 1, - Title: "TorrServer", - Date: upnpav.Timestamp{Time: time.Now()}, - Class: "object.container.storageFolder", - } - // add Root Object - ret = upnpav.Container{Object: rootObj, ChildCount: 1} - return - } else if path == "/TR" { - // TR Object Meta - trObj := upnpav.Object{ - ID: "%2FTR", - ParentID: "0", - Restricted: 1, - Searchable: 1, - Title: "Torrents", - Date: upnpav.Timestamp{Time: time.Now()}, - Class: "object.container.storageFolder", - } - vol := len(torr.ListTorrent()) - ret = upnpav.Container{Object: trObj, ChildCount: vol} - return - } ret = getTorrentMeta(path, host) if ret == nil { err = fmt.Errorf("meta not found") @@ -188,19 +166,21 @@ func getDefaultFriendlyName() string { } var list []string for _, i := range ifaces { + // interface flags seem to always be 0 on Windows + if runtime.GOOS != "windows" && (i.Flags&net.FlagLoopback != 0 || i.Flags&net.FlagUp == 0 || i.Flags&net.FlagMulticast == 0) { + continue + } addrs, _ := i.Addrs() - if i.Flags&net.FlagUp == net.FlagUp { - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - if !ip.IsLoopback() { - list = append(list, ip.String()) - } + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + if !ip.IsLoopback() && ip.To4() != nil { + list = append(list, ip.String()) } } } diff --git a/server/dlna/list.go b/server/dlna/list.go index 962cf6b..4a4673b 100644 --- a/server/dlna/list.go +++ b/server/dlna/list.go @@ -13,6 +13,7 @@ import ( "github.com/anacrolix/dms/upnpav" "server/log" + mt "server/mimetype" "server/settings" "server/torr" "server/torr/state" @@ -72,7 +73,7 @@ func getTorrents() (ret []interface{}) { Class: "object.container.storageFolder", Date: upnpav.Timestamp{Time: time.Now()}, } - cnt := upnpav.Container{Object: obj, ChildCount: 1} + cnt := upnpav.Container{Object: obj, ChildCount: 0} ret = append(ret, cnt) } return @@ -128,7 +129,34 @@ func getTorrentMeta(path, host string) (ret interface{}) { } // Meta object - if isHashPath(path) { + if path == "/" { + // root object meta + rootObj := upnpav.Object{ + ID: "0", + ParentID: "-1", + Restricted: 1, + Searchable: 1, + Title: "TorrServer", + Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container.storageFolder", + } + meta := upnpav.Container{Object: rootObj, ChildCount: 1} + return meta + } else if path == "/TR" { + // TR Object Meta + trObj := upnpav.Object{ + ID: "%2FTR", + ParentID: "0", + Restricted: 1, + Searchable: 1, + Title: "Torrents", + Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container.storageFolder", + } + vol := len(torrs) + meta := upnpav.Container{Object: trObj, ChildCount: vol} + return meta + } else if isHashPath(path) { // hash object meta obj := upnpav.Object{ ID: "%2F" + torr.TorrentSpec.InfoHash.HexString(), @@ -224,7 +252,7 @@ func getLink(host, path string) string { func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *state.TorrentFileStat) (ret interface{}) { - mime, err := MimeTypeByPath(file.Path) + mime, err := mt.MimeTypeByPath(file.Path) if err != nil { if settings.BTsets.EnableDebug { log.TLogln("Can't detect mime type", err) diff --git a/server/go.mod b/server/go.mod index 32b8da0..df8352d 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,7 +3,7 @@ module server go 1.17 replace ( - github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d + github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 github.com/anacrolix/torrent v1.31.0 => github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 ) diff --git a/server/go.sum b/server/go.sum index 414dc69..78338e8 100644 --- a/server/go.sum +++ b/server/go.sum @@ -678,8 +678,8 @@ github.com/tinylib/msgp v1.1.1/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d h1:YFNG0P4SKHxOvHM3Ae+FI1/kRnhi/qyvblHOKzDgRPE= -github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= +github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 h1:qBZPOad8wOmvFe6rIx1d0U7VpymFalvbM5kjHeEx8Gs= +github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 h1:GHhNKxddZiYrWeiXqMQiPKcSIXKF+o/w1wrqHOgOFrk= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09/go.mod h1:E9gvoHzc58EtTudJbzZ2Ho7SKDCYk84734hB9ztBJS4= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= diff --git a/server/dlna/mimetype.go b/server/mimetype/mimetype.go similarity index 99% rename from server/dlna/mimetype.go rename to server/mimetype/mimetype.go index c6f8f1b..ebdf3f8 100644 --- a/server/dlna/mimetype.go +++ b/server/mimetype/mimetype.go @@ -1,4 +1,4 @@ -package dlna +package mimetype import ( "log" diff --git a/server/torr/stream.go b/server/torr/stream.go index da3ca3a..1bfebb3 100644 --- a/server/torr/stream.go +++ b/server/torr/stream.go @@ -12,6 +12,7 @@ import ( "github.com/anacrolix/missinggo/httptoo" "github.com/anacrolix/torrent" + mt "server/mimetype" sets "server/settings" "server/torr/state" ) @@ -61,8 +62,12 @@ func (t *Torrent) Stream(fileID int, req *http.Request, resp http.ResponseWriter resp.Header().Set("Connection", "close") resp.Header().Set("ETag", httptoo.EncodeQuotedString(fmt.Sprintf("%s/%s", t.Hash().HexString(), file.Path()))) + // DLNA headers resp.Header().Set("transferMode.dlna.org", "Streaming") - + mime, err := mt.MimeTypeByPath(file.Path()) + if err == nil && mime.IsMedia() { + resp.Header().Set("content-type", mime.String()) + } if req.Header.Get("getContentFeatures.dlna.org") != "" { resp.Header().Set("contentFeatures.dlna.org", dlna.ContentFeatures{ SupportRange: true,