diff --git a/router/upload.go b/router/upload.go index 9176f03c..c27f206e 100644 --- a/router/upload.go +++ b/router/upload.go @@ -1,6 +1,7 @@ package router import ( + "encoding/base32" "encoding/hex" "errors" "fmt" @@ -158,24 +159,38 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error { f.Filesize = int64(torrent.TotalSize()) } else { // No torrent file provided - magnetURL, parseErr := url.Parse(f.Magnet) - if parseErr != nil { - return metainfo.ErrInvalidTorrentFile - } - exactTopic := magnetURL.Query().Get("xt") - if !strings.HasPrefix(exactTopic, "urn:btih:") { - return metainfo.ErrInvalidTorrentFile - } - exactTopic = strings.SplitAfter(exactTopic, ":")[2] - f.Infohash = strings.ToUpper(strings.Split(exactTopic, "&")[0]) - base16, err := regexp.MatchString("^[0-9A-F]{40}$", f.Infohash) + magnetUrl, err := url.Parse(string(f.Magnet)) //? if err != nil { return err } - base32, err := regexp.MatchString("^[2-7A-Z]{32}$", f.Infohash) - if !base16 && !base32 { + xt := magnetUrl.Query().Get("xt") + if !strings.HasPrefix(xt, "urn:btih:") { + return errors.New("incorrect magnet") + } + xt = strings.SplitAfter(xt, ":")[2] + f.Infohash = strings.ToUpper(strings.Split(xt, "&")[0]) + isBase32, err := regexp.MatchString("^[2-7A-Z]{32}$", f.Infohash) + if err != nil { return err } + if !isBase32 { + isBase16, err := regexp.MatchString("^[0-9A-F]{40}$", f.Infohash) + if err != nil { + return err + } + if !isBase16 { + return errors.New("incorrect hash") + } + } else { + //convert to base16 + data, err := base32.StdEncoding.DecodeString(f.Infohash) + if err != nil { + return err + } + hash16 := make([]byte, hex.EncodedLen(len(data))) + hex.Encode(hash16, data) + f.Infohash = string(hash16) + } f.Filesize = 0 f.Filepath = "" diff --git a/service/api/api.go b/service/api/api.go index 9fd32ae8..417f3242 100644 --- a/service/api/api.go +++ b/service/api/api.go @@ -1,6 +1,7 @@ package apiService import ( + "encoding/base32" "encoding/hex" "errors" "fmt" @@ -92,26 +93,39 @@ func validateMagnet(r *TorrentRequest) (error, int) { if err != nil { return err, http.StatusInternalServerError } - exactTopic := magnetUrl.Query().Get("xt") - fmt.Println(exactTopic) - if !strings.HasPrefix(exactTopic, "urn:btih:") { + xt := magnetUrl.Query().Get("xt") + if !strings.HasPrefix(xt, "urn:btih:") { return ErrMagnet, http.StatusNotAcceptable } - exactTopic = strings.SplitAfter(exactTopic, ":")[2] - r.Hash = strings.ToUpper(strings.Split(exactTopic, "&")[0]) + xt = strings.SplitAfter(xt, ":")[2] + r.Hash = strings.ToUpper(strings.Split(xt, "&")[0]) fmt.Println(r.Hash) return nil, http.StatusOK } func validateHash(r *TorrentRequest) (error, int) { r.Hash = strings.ToUpper(r.Hash) - base16, err := regexp.MatchString("^[0-9A-F]{40}$", r.Hash) + isBase32, err := regexp.MatchString("^[2-7A-Z]{32}$", r.Hash) if err != nil { return err, http.StatusInternalServerError } - base32, err := regexp.MatchString("^[2-7A-Z]{32}$", r.Hash) - if !base16 && !base32 { - return ErrHash, http.StatusNotAcceptable + if !isBase32 { + isBase16, err := regexp.MatchString("^[0-9A-F]{40}$", r.Hash) + if err != nil { + return err, http.StatusInternalServerError + } + if !isBase16 { + return ErrHash, http.StatusNotAcceptable + } + } else { + //convert to base16 + data, err := base32.StdEncoding.DecodeString(r.Hash) + if err != nil { + return err, http.StatusInternalServerError + } + hash16 := make([]byte, hex.EncodedLen(len(data))) + hex.Encode(hash16, data) + r.Hash = string(hash16) } return nil, http.StatusOK }