Merge branch 'master' into new-torrent

This commit is contained in:
nikk gitanes
2021-09-13 04:10:04 +03:00
9 changed files with 291 additions and 28 deletions

View File

@@ -103,7 +103,7 @@ func RouteWebPages(route *gin.RouterGroup) {
}) })
` `
} }
embedStr += "}" embedStr += "}\n"
ff.WriteString(embedStr) ff.WriteString(embedStr)
} }

View File

@@ -10,9 +10,9 @@ import (
"time" "time"
"github.com/anacrolix/dms/dlna/dms" "github.com/anacrolix/dms/dlna/dms"
"github.com/anacrolix/dms/upnpav"
"server/log" "server/log"
"server/utils"
"server/web/pages/template" "server/web/pages/template"
) )
@@ -22,11 +22,16 @@ func Start() {
dmsServer = &dms.Server{ dmsServer = &dms.Server{
Interfaces: func() (ifs []net.Interface) { Interfaces: func() (ifs []net.Interface) {
var err error var err error
ifs, err = net.Interfaces() ifaces, err := net.Interfaces()
if err != nil { if err != nil {
log.TLogln(err) log.TLogln(err)
os.Exit(1) os.Exit(1)
} }
for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == net.FlagUp && element.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(element.HardwareAddr.String()) {
ifs = append(ifs, element)
}
}
return return
}(), }(),
HTTPConn: func() net.Listener { HTTPConn: func() net.Listener {
@@ -120,22 +125,10 @@ func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{},
} }
func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (ret interface{}, err error) { func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (ret interface{}, err error) {
if path == "/" { ret = getTorrentMeta(path, host)
// Root Object Meta if ret == nil {
rootObj := upnpav.Object{ err = fmt.Errorf("meta not found")
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
}
err = fmt.Errorf("not implemented")
return return
} }
@@ -172,7 +165,7 @@ func getDefaultFriendlyName() string {
var list []string var list []string
for _, i := range ifaces { for _, i := range ifaces {
addrs, _ := i.Addrs() addrs, _ := i.Addrs()
if i.Flags&net.FlagUp == net.FlagUp { if i.Flags&net.FlagLoopback == 0 && i.Flags&net.FlagUp == net.FlagUp && i.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(i.HardwareAddr.String()) {
for _, addr := range addrs { for _, addr := range addrs {
var ip net.IP var ip net.IP
switch v := addr.(type) { switch v := addr.(type) {

View File

@@ -113,6 +113,104 @@ func getTorrent(path, host string) (ret []interface{}) {
return return
} }
func getTorrentMeta(path, host string) (ret interface{}) {
if path == "/" {
rootObj := upnpav.Object{
ID: "0",
ParentID: "-1",
Restricted: 1,
Searchable: 1,
Title: "TorrServer",
Date: upnpav.Timestamp{Time: time.Now()},
Class: "object.container",
}
// add Root Object
meta := upnpav.Container{Object: rootObj}
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",
}
//vol := len(torr.ListTorrent())
meta := upnpav.Container{Object: trObj}
return meta
}
// find torrent without load
torrs := torr.ListTorrent()
var torr *torr.Torrent
for _, t := range torrs {
if strings.Contains(path, t.TorrentSpec.InfoHash.HexString()) {
torr = t
break
}
}
if torr == nil {
return nil
}
// Meta object
if isHashPath(path) {
// hash object meta
obj := upnpav.Object{
ID: "%2F" + torr.TorrentSpec.InfoHash.HexString(),
ParentID: "%2FTR",
Restricted: 1,
Title: torr.Title,
Date: upnpav.Timestamp{Time: time.Now()},
Class: "object.container",
}
meta := upnpav.Container{Object: obj}
return meta
} else if filepath.Base(path) == "LD" {
parent := url.PathEscape(filepath.Dir(path))
if settings.BTsets.EnableDebug {
log.TLogln("getTorrentMeta parent for LD", parent)
}
// LD object meta
obj := upnpav.Object{
ID: parent + "%2FLD",
ParentID: parent,
Restricted: 1,
Searchable: 1,
Title: "Load Torrents",
Date: upnpav.Timestamp{Time: time.Now()},
Class: "object.container",
}
meta := upnpav.Container{Object: obj}
return meta
} else {
file := filepath.Base(path)
id := url.PathEscape(path)
parent := url.PathEscape(filepath.Dir(path))
if settings.BTsets.EnableDebug {
log.TLogln("getTorrentMeta id:", id, "parent:", parent)
}
// file object meta
obj := upnpav.Object{
ID: id,
ParentID: parent,
Restricted: 1,
Searchable: 1,
Title: file,
Date: upnpav.Timestamp{Time: time.Now()},
Class: "object.container",
}
meta := upnpav.Container{Object: obj}
return meta
}
// for error response
return nil
}
func loadTorrent(path, host string) (ret []interface{}) { func loadTorrent(path, host string) (ret []interface{}) {
hash := filepath.Base(filepath.Dir(path)) hash := filepath.Base(filepath.Dir(path))
if hash == "/" { if hash == "/" {

View File

@@ -2,7 +2,7 @@ module server
go 1.17 go 1.17
replace github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac replace github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d
exclude ( exclude (
github.com/willf/bitset v1.2.0 github.com/willf/bitset v1.2.0

View File

@@ -719,8 +719,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.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= 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/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac h1:1JLBJz2aGJhQ6ZR+zJWl68/0DLJkr+E3E74HEzOFOjw= github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d h1:YFNG0P4SKHxOvHM3Ae+FI1/kRnhi/qyvblHOKzDgRPE=
github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=

View File

@@ -0,0 +1,38 @@
package utils
import (
"strings"
)
type PhysicalInterface struct {
MACAddress string
Name string
FriendlyName string
}
// Mac Address parts to look for, and identify non physical devices. There may be more, update me!
var macAddrPartsToFilter []string = []string{
"00:03:FF", // Microsoft Hyper-V, Virtual Server, Virtual PC
"0A:00:27", // VirtualBox
"00:00:00:00:00", // Teredo Tunneling Pseudo-Interface
"00:50:56", // VMware ESX 3, Server, Workstation, Player
"00:1C:14", // VMware ESX 3, Server, Workstation, Player
"00:0C:29", // VMware ESX 3, Server, Workstation, Player
"00:05:69", // VMware ESX 3, Server, Workstation, Player
"00:1C:42", // Microsoft Hyper-V, Virtual Server, Virtual PC
"00:0F:4B", // Virtual Iron 4
"00:16:3E", // Red Hat Xen, Oracle VM, XenSource, Novell Xen
"08:00:27", // Sun xVM VirtualBox
"7A:79", // Hamachi
}
// Filters the possible physical interface address by comparing it to known popular VM Software adresses
// and Teredo Tunneling Pseudo-Interface.
func IsPhysicalInterface(addr string) bool {
for _, macPart := range macAddrPartsToFilter {
if strings.HasPrefix(strings.ToLower(addr), strings.ToLower(macPart)) {
return false
}
}
return true
}

View File

@@ -0,0 +1,29 @@
//go:build linux || darwin
// +build linux darwin
package utils
import (
"fmt"
"net"
)
// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterfaces() []PhysicalInterface {
ifaces, err := net.Interfaces()
if err != nil {
fmt.Println(err)
return nil
}
var outInterfaces []PhysicalInterface
for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.HardwareAddr.String()) {
outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: element.HardwareAddr.String(), Name: element.Name, FriendlyName: element.Name})
}
}
return outInterfaces
}

View File

@@ -0,0 +1,105 @@
//go:build windows
// +build windows
package utils
import (
"os"
"syscall"
"unicode/utf16"
"unsafe"
"golang.org/x/sys/windows"
)
const (
IfOperStatusUp = 1
IF_TYPE_SOFTWARE_LOOPBACK = 24
IF_TYPE_TUNNEL = 131
)
const hexDigit = "0123456789abcdef"
func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
var b []byte
l := uint32(15000) // recommended initial size
for {
b = make([]byte, l)
err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
if err == nil {
if l == 0 {
return nil, nil
}
break
}
if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
if l <= uint32(len(b)) {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
}
var aas []*windows.IpAdapterAddresses
for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
aas = append(aas, aa)
}
return aas, nil
}
func bytePtrToString(p *uint8) string {
a := (*[10000]uint8)(unsafe.Pointer(p))
i := 0
for a[i] != 0 {
i++
}
return string(a[:i])
}
func physicalAddrToString(physAddr [8]byte) string {
if len(physAddr) == 0 {
return ""
}
buf := make([]byte, 0, len(physAddr)*3-1)
for i, b := range physAddr {
if i > 0 {
buf = append(buf, ':')
}
buf = append(buf, hexDigit[b>>4])
buf = append(buf, hexDigit[b&0xF])
}
return string(buf)
}
func cStringToString(cs *uint16) (s string) {
if cs != nil {
us := make([]uint16, 0, 256)
for p := uintptr(unsafe.Pointer(cs)); ; p += 2 {
u := *(*uint16)(unsafe.Pointer(p))
if u == 0 {
return string(utf16.Decode(us))
}
us = append(us, u)
}
}
return ""
}
// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterfaces() []PhysicalInterface {
aa, _ := adapterAddresses()
var outInterfaces []PhysicalInterface
for _, pa := range aa {
mac := physicalAddrToString(pa.PhysicalAddress)
name := "\\Device\\NPF_" + bytePtrToString(pa.AdapterName)
if pa.IfType != uint32(IF_TYPE_SOFTWARE_LOOPBACK) && pa.IfType != uint32(IF_TYPE_TUNNEL) &&
pa.OperStatus == uint32(IfOperStatusUp) && IsPhysicalInterface(mac) {
outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: mac, Name: name, FriendlyName: cStringToString(pa.FriendlyName)})
}
}
return outInterfaces
}