Merge remote-tracking branch 'origin/master'

This commit is contained in:
YouROK
2021-03-08 21:08:00 +03:00
6 changed files with 158 additions and 18 deletions

View File

@@ -76,6 +76,10 @@ func loadBTSets() {
log.TLogln("Error unmarshal btsets", err) log.TLogln("Error unmarshal btsets", err)
} }
SetDefault()
}
func SetDefault() {
sets := new(BTSets) sets := new(BTSets)
sets.EnableDebug = false sets.EnableDebug = false
sets.DisableUTP = true sets.DisableUTP = true

View File

@@ -73,6 +73,7 @@ func GetTorrent(hashHex string) *Torrent {
if tr != nil { if tr != nil {
tr.Title = tor.Title tr.Title = tor.Title
tr.Poster = tor.Poster tr.Poster = tor.Poster
tr.Data = tor.Data
tr.Size = tor.Size tr.Size = tor.Size
tr.Timestamp = tor.Timestamp tr.Timestamp = tor.Timestamp
tr.GotInfo() tr.GotInfo()
@@ -128,6 +129,15 @@ func SetSettings(set *sets.BTSets) {
bts.Connect() bts.Connect()
} }
func SetDefSettings() {
if sets.ReadOnly {
return
}
bts.Disconnect()
sets.SetDefault()
bts.Connect()
}
func Shutdown() { func Shutdown() {
bts.Disconnect() bts.Disconnect()
sets.CloseDB() sets.CloseDB()

View File

@@ -46,20 +46,6 @@ func (t *Torrent) Stream(fileID int, req *http.Request, resp http.ResponseWriter
reader := t.NewReader(file) reader := t.NewReader(file)
//off := int64(0)
//buf := make([]byte, 32*1024)
//for true {
// n, err := reader.Read(buf)
// if err != nil {
// fmt.Println("error read", err)
// break
// }
// off = off + int64(n)
// if off%(200*1024*1024) == 0 {
// time.Sleep(time.Second * 15)
// }
//}
log.Println("Connect client") log.Println("Connect client")
sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileID}) sets.SetViewed(&sets.Viewed{t.Hash().HexString(), fileID})

View File

@@ -10,7 +10,7 @@ import (
"server/torr" "server/torr"
) )
//Action: get, set //Action: get, set, def
type setsReqJS struct { type setsReqJS struct {
requestI requestI
Sets *sets.BTSets `json:"sets,omitempty"` Sets *sets.BTSets `json:"sets,omitempty"`
@@ -27,11 +27,14 @@ func settings(c *gin.Context) {
if req.Action == "get" { if req.Action == "get" {
c.JSON(200, sets.BTsets) c.JSON(200, sets.BTsets)
return return
} } else if req.Action == "set" {
if req.Action == "set" {
torr.SetSettings(req.Sets) torr.SetSettings(req.Sets)
c.Status(200) c.Status(200)
return return
} else if req.Action == "def" {
torr.SetDefSettings()
c.Status(200)
return
} }
c.AbortWithError(http.StatusBadRequest, errors.New("action is empty")) c.AbortWithError(http.StatusBadRequest, errors.New("action is empty"))
} }

View File

@@ -36,6 +36,17 @@ func stream(c *gin.Context) {
_, play := c.GetQuery("play") _, play := c.GetQuery("play")
title := c.Query("title") title := c.Query("title")
poster := c.Query("poster") poster := c.Query("poster")
notAuth := c.GetBool("not_auth")
if notAuth && play {
streamNoAuth(c)
return
}
if notAuth {
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
c.AbortWithStatus(http.StatusUnauthorized)
return
}
if link == "" { if link == "" {
c.AbortWithError(http.StatusBadRequest, errors.New("link should not be empty")) c.AbortWithError(http.StatusBadRequest, errors.New("link should not be empty"))
@@ -111,3 +122,65 @@ func stream(c *gin.Context) {
return return
} }
} }
func streamNoAuth(c *gin.Context) {
link := c.Query("link")
indexStr := c.Query("index")
_, preload := c.GetQuery("preload")
title := c.Query("title")
poster := c.Query("poster")
if link == "" {
c.AbortWithError(http.StatusBadRequest, errors.New("link should not be empty"))
return
}
if title == "" {
title = c.Param("fname")
title, _ = url.PathUnescape(title)
title = strings.TrimLeft(title, "/")
} else {
title, _ = url.QueryUnescape(title)
}
link, _ = url.QueryUnescape(link)
poster, _ = url.QueryUnescape(poster)
spec, err := utils.ParseLink(link)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
tor := torr.GetTorrent(spec.InfoHash.HexString())
if tor == nil {
c.AbortWithError(http.StatusNotFound, errors.New("Torrent not found"))
return
}
if !tor.GotInfo() {
c.AbortWithError(http.StatusInternalServerError, errors.New("timeout connection torrent"))
return
}
// find file
index := -1
if len(tor.Files()) == 1 {
index = 1
} else {
ind, err := strconv.Atoi(indexStr)
if err == nil {
index = ind
}
}
if index == -1 { // if file index not set and play file exec
c.AbortWithError(http.StatusBadRequest, errors.New("\"index\" is empty or wrong"))
return
}
// preload torrent
if preload {
torr.Preload(tor, index)
}
tor.Stream(index, c.Request, c.Writer)
}

View File

@@ -1,9 +1,14 @@
package auth package auth
import ( import (
"encoding/base64"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"path/filepath" "path/filepath"
"reflect"
"strings"
"unsafe"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -19,7 +24,7 @@ func SetupAuth(engine *gin.Engine) *gin.RouterGroup {
if accs == nil { if accs == nil {
return nil return nil
} }
return engine.Group("/", gin.BasicAuth(accs)) return engine.Group("/", BasicAuth(accs))
} }
func getAccounts() gin.Accounts { func getAccounts() gin.Accounts {
@@ -34,3 +39,62 @@ func getAccounts() gin.Accounts {
} }
return accs return accs
} }
type authPair struct {
value string
user string
}
type authPairs []authPair
func (a authPairs) searchCredential(authValue string) (string, bool) {
if authValue == "" {
return "", false
}
for _, pair := range a {
if pair.value == authValue {
return pair.user, true
}
}
return "", false
}
func BasicAuth(accounts gin.Accounts) gin.HandlerFunc {
pairs := processAccounts(accounts)
return func(c *gin.Context) {
user, found := pairs.searchCredential(c.Request.Header.Get("Authorization"))
if !found {
if strings.HasPrefix(c.FullPath(), "/stream") {
c.Set("not_auth", true)
return
}
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Set(gin.AuthUserKey, user)
}
}
func processAccounts(accounts gin.Accounts) authPairs {
pairs := make(authPairs, 0, len(accounts))
for user, password := range accounts {
value := authorizationHeader(user, password)
pairs = append(pairs, authPair{
value: value,
user: user,
})
}
return pairs
}
func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString(StringToBytes(base))
}
func StringToBytes(s string) (b []byte) {
sh := *(*reflect.StringHeader)(unsafe.Pointer(&s))
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
bh.Data, bh.Len, bh.Cap = sh.Data, sh.Len, sh.Len
return b
}