Fix infohash decoding (#813)
Calculate the info hash of the uploaded torrent file instead of the re-encoded torrent file. The re-encoded torrent files only contain a subset of the original info values and thus have a different hash.
Cette révision appartient à :
Parent
49e4b800b0
révision
b31e77be2e
3 fichiers modifiés avec 42 ajouts et 21 suppressions
|
@ -1,7 +1,6 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -172,12 +171,17 @@ func (f *uploadForm) ExtractInfo(r *http.Request) error {
|
|||
if len(f.Magnet) != 0 {
|
||||
return errTorrentPlusMagnet
|
||||
}
|
||||
binInfohash, err := torrent.Infohash()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
_, seekErr = tfile.Seek(0, io.SeekStart)
|
||||
if seekErr != nil {
|
||||
return seekErr
|
||||
}
|
||||
f.Infohash = strings.ToUpper(hex.EncodeToString(binInfohash[:]))
|
||||
f.Magnet = util.InfoHashToMagnet(f.Infohash, f.Name, trackers...)
|
||||
infohash, err := metainfo.DecodeInfohash(tfile)
|
||||
if err != nil {
|
||||
return metainfo.ErrInvalidTorrentFile
|
||||
}
|
||||
f.Infohash = infohash
|
||||
f.Magnet = util.InfoHashToMagnet(infohash, f.Name, trackers...)
|
||||
|
||||
// extract filesize
|
||||
f.Filesize = int64(torrent.TotalSize())
|
||||
|
|
|
@ -198,11 +198,15 @@ func (r *TorrentRequest) ValidateMultipartUpload(req *http.Request) (int64, erro
|
|||
r.Name = torrent.TorrentName()
|
||||
}
|
||||
|
||||
binInfohash, err := torrent.Infohash()
|
||||
_, err = tfile.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return 0, err, http.StatusInternalServerError
|
||||
}
|
||||
r.Hash = strings.ToUpper(hex.EncodeToString(binInfohash[:]))
|
||||
infohash, err := metainfo.DecodeInfohash(tfile)
|
||||
if err != nil {
|
||||
return 0, err, http.StatusInternalServerError
|
||||
}
|
||||
r.Hash = infohash
|
||||
|
||||
// extract filesize
|
||||
filesize := int64(torrent.TotalSize())
|
||||
|
|
|
@ -4,9 +4,11 @@ package metainfo
|
|||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/zeebo/bencode"
|
||||
)
|
||||
|
@ -120,19 +122,6 @@ func (tf *TorrentFile) IsPrivate() bool {
|
|||
return tf.Info.Private != nil && *tf.Info.Private == 1
|
||||
}
|
||||
|
||||
// Infohash : calculate infohash
|
||||
func (tf *TorrentFile) Infohash() (ih [20]byte, err error) {
|
||||
s := sha1.New()
|
||||
enc := bencode.NewEncoder(s)
|
||||
err = enc.Encode(&tf.Info)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
d := s.Sum(nil)
|
||||
copy(ih[:], d[:])
|
||||
return
|
||||
}
|
||||
|
||||
// IsSingleFile : return true if this torrent is for a single file
|
||||
func (tf *TorrentFile) IsSingleFile() bool {
|
||||
return tf.Info.Length > 0
|
||||
|
@ -151,3 +140,27 @@ func (tf *TorrentFile) Decode(r io.Reader) (err error) {
|
|||
err = dec.Decode(tf)
|
||||
return
|
||||
}
|
||||
|
||||
type torrentRaw struct {
|
||||
InfoRaw bencode.RawMessage `bencode:"info"`
|
||||
}
|
||||
|
||||
// DecodeInfohash : Decode and calculate the info hash
|
||||
func DecodeInfohash(r io.Reader) (hash string, err error) {
|
||||
var t torrentRaw
|
||||
d := bencode.NewDecoder(r)
|
||||
err = d.Decode(&t)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s := sha1.New()
|
||||
_, err = s.Write(t.InfoRaw)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rawHash := s.Sum(nil)
|
||||
|
||||
hash = strings.ToUpper(hex.EncodeToString(rawHash))
|
||||
return
|
||||
}
|
||||
|
|
Référencer dans un nouveau ticket