diff --git a/internal/protocol/bt/fetcher.go b/internal/protocol/bt/fetcher.go index 1a45a6f93..3244be1a7 100644 --- a/internal/protocol/bt/fetcher.go +++ b/internal/protocol/bt/fetcher.go @@ -11,7 +11,9 @@ import ( "github.com/GopeedLab/gopeed/pkg/util" "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" + "io" "net/url" + "os" "path/filepath" "strings" "sync" @@ -359,17 +361,27 @@ func (f *Fetcher) addTorrent(req *base.Request, fromUpload bool) (err error) { schema := util.ParseSchema(req.URL) if schema == "MAGNET" { f.torrent, err = client.AddMagnet(req.URL) - } else if schema == "DATA" { - _, data := util.ParseDataUri(req.URL) - buf := bytes.NewBuffer(data) + } else { + var reader io.Reader + if schema == "DATA" { + _, data := util.ParseDataUri(req.URL) + reader = bytes.NewBuffer(data) + } else { + reader, err = os.Open(req.URL) + if err != nil { + return + } + defer reader.(io.Closer).Close() + } + var metaInfo *metainfo.MetaInfo - metaInfo, err = metainfo.Load(buf) - if err != nil { + metaInfo, err = metainfo.Load(reader) + // Hotfix for https://github.com/anacrolix/torrent/issues/992, ignore "expected EOF" error + // TODO remove this after the issue is fixed + if err != nil && !strings.Contains(err.Error(), "expected EOF") { return err } f.torrent, err = client.AddTorrent(metaInfo) - } else { - f.torrent, err = client.AddTorrentFromFile(req.URL) } if err != nil { return diff --git a/internal/protocol/bt/fetcher_test.go b/internal/protocol/bt/fetcher_test.go index 012c4134a..250f4c4c9 100644 --- a/internal/protocol/bt/fetcher_test.go +++ b/internal/protocol/bt/fetcher_test.go @@ -96,7 +96,7 @@ func doResolve(t *testing.T, fetcher fetcher.Fetcher) { Hash: "8a55cfbd5ca5d11507364765936c4f9e55b253ed", } if !reflect.DeepEqual(want, fetcher.Meta().Res) { - t.Errorf("Resolve() got = %v, want %v", fetcher.Meta().Res, want) + t.Errorf("Resolve Single File Resolve() got = %v, want %v", fetcher.Meta().Res, want) } }) @@ -136,7 +136,16 @@ func doResolve(t *testing.T, fetcher fetcher.Fetcher) { Hash: "ccbc92b0cd8deec16a2ef4be242a8c9243b1cedb", } if !reflect.DeepEqual(want, fetcher.Meta().Res) { - t.Errorf("Resolve() got = %v, want %v", fetcher.Meta().Res, want) + t.Errorf("Resolve Multi Files Resolve() got = %v, want %v", fetcher.Meta().Res, want) + } + }) + + t.Run("Resolve Unclean Torrent", func(t *testing.T) { + err := fetcher.Resolve(&base.Request{ + URL: "./testdata/test.unclean.torrent", + }) + if err != nil { + t.Errorf("Resolve Unclean Torrent Resolve() got = %v, want nil", err) } }) diff --git a/internal/protocol/bt/testdata/test.unclean.torrent b/internal/protocol/bt/testdata/test.unclean.torrent new file mode 100644 index 000000000..bd7d71e36 Binary files /dev/null and b/internal/protocol/bt/testdata/test.unclean.torrent differ