Fix webseeds when info isn't available immediately

This commit is contained in:
Matt Joiner 2020-06-02 16:18:25 +10:00
parent 72bd4f362e
commit 7909084a17
3 changed files with 23 additions and 13 deletions

View File

@ -18,6 +18,7 @@ import (
"github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/bitmap"
"github.com/anacrolix/missinggo/v2/prioritybitmap" "github.com/anacrolix/missinggo/v2/prioritybitmap"
"github.com/anacrolix/multiless" "github.com/anacrolix/multiless"
"github.com/anacrolix/torrent/metainfo"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/bencode"
@ -44,6 +45,7 @@ type PeerImpl interface {
ConnectionFlags() string ConnectionFlags() string
Close() Close()
PostCancel(request) PostCancel(request)
onGotInfo(*metainfo.Info)
Drop() Drop()
} }
@ -233,13 +235,15 @@ func (cn *peer) completedString() string {
return fmt.Sprintf("%d/%d", have, cn.bestPeerNumPieces()) return fmt.Sprintf("%d/%d", have, cn.bestPeerNumPieces())
} }
// Correct the PeerPieces slice length. Return false if the existing slice is func (cn *PeerConn) onGotInfo(info *metainfo.Info) {
// invalid, such as by receiving badly sized BITFIELD, or invalid HAVE cn.setNumPieces(info.NumPieces())
// messages. }
func (cn *PeerConn) setNumPieces(num pieceIndex) error {
// Correct the PeerPieces slice length. Return false if the existing slice is invalid, such as by
// receiving badly sized BITFIELD, or invalid HAVE messages.
func (cn *PeerConn) setNumPieces(num pieceIndex) {
cn._peerPieces.RemoveRange(bitmap.BitIndex(num), bitmap.ToEnd) cn._peerPieces.RemoveRange(bitmap.BitIndex(num), bitmap.ToEnd)
cn.peerPiecesChanged() cn.peerPiecesChanged()
return nil
} }
func eventAgeString(t time.Time) string { func eventAgeString(t time.Time) string {

View File

@ -406,13 +406,11 @@ func (t *Torrent) setInfo(info *metainfo.Info) error {
return nil return nil
} }
// This seems to be all the follow-up tasks after info is set, that can't fail.
func (t *Torrent) onSetInfo() { func (t *Torrent) onSetInfo() {
for conn := range t.conns { t.iterPeers(func(p *peer) {
if err := conn.setNumPieces(t.numPieces()); err != nil { p.onGotInfo(t.info)
t.logger.Printf("closing connection: %s", err) })
conn.close()
}
}
for i := range t.pieces { for i := range t.pieces {
t.updatePieceCompletion(pieceIndex(i)) t.updatePieceCompletion(pieceIndex(i))
p := &t.pieces[i] p := &t.pieces[i]
@ -2026,12 +2024,13 @@ func (t *Torrent) addWebSeed(url string) {
client: webseed.Client{ client: webseed.Client{
HttpClient: http.DefaultClient, HttpClient: http.DefaultClient,
Url: url, Url: url,
FileIndex: t.fileIndex,
Info: t.info,
}, },
requests: make(map[request]webseed.Request, maxRequests), requests: make(map[request]webseed.Request, maxRequests),
} }
ws.peer.PeerImpl = &ws ws.peer.PeerImpl = &ws
if t.haveInfo() {
ws.onGotInfo(t.info)
}
t.webSeeds[url] = &ws.peer t.webSeeds[url] = &ws.peer
} }

View File

@ -3,6 +3,8 @@ package torrent
import ( import (
"net/http" "net/http"
"github.com/anacrolix/torrent/common"
"github.com/anacrolix/torrent/metainfo"
pp "github.com/anacrolix/torrent/peer_protocol" pp "github.com/anacrolix/torrent/peer_protocol"
"github.com/anacrolix/torrent/segments" "github.com/anacrolix/torrent/segments"
"github.com/anacrolix/torrent/webseed" "github.com/anacrolix/torrent/webseed"
@ -31,6 +33,11 @@ type webSeed struct {
var _ PeerImpl = (*webSeed)(nil) var _ PeerImpl = (*webSeed)(nil)
func (ws *webSeed) onGotInfo(info *metainfo.Info) {
ws.client.FileIndex = segments.NewIndex(common.LengthIterFromUpvertedFiles(info.UpvertedFiles()))
ws.client.Info = info
}
func (ws *webSeed) PostCancel(r request) { func (ws *webSeed) PostCancel(r request) {
ws.Cancel(r) ws.Cancel(r)
} }