client.go | 4 ++++ peerconn.go | 14 +++++++------- torrent.go | 36 +++++++++++++++++++++++------------- web_seed.go | 7 +++++++ diff --git a/client.go b/client.go index 646f034f397fd2d2815938a7047c90b72b13b5fe..045476484c9708bcbeb7e47a5537ce812df8de6c 100644 --- a/client.go +++ b/client.go @@ -1091,6 +1091,7 @@ networkingEnabled: true, metadataChanged: sync.Cond{ L: cl.locker(), }, + webSeeds: make(map[string]*peer), } t._pendingPieces.NewSet = priorityBitmapStableNewSet t.requestStrategy = cl.config.DefaultRequestStrategy(t.requestStrategyCallbacks(), &cl._mu) @@ -1232,6 +1233,9 @@ T, _, err = cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) var ss []string slices.MakeInto(&ss, mi.Nodes) cl.AddDHTNodes(ss) + for _, url := range mi.UrlList { + T.addWebSeed(url) + } return } diff --git a/peerconn.go b/peerconn.go index 9ec40a28d2305314f9ca92e49bcec00b6c4713ce..879ab6cef5014a7939f73352d7ffd9f17b770ede 100644 --- a/peerconn.go +++ b/peerconn.go @@ -41,7 +41,7 @@ writeInterested(interested bool) bool cancel(request) bool request(request) bool connectionFlags() string - close() + _close() postCancel(request) drop() } @@ -343,10 +343,10 @@ return } cn.discardPieceInclination() cn._pieceRequestOrder.Clear() - cn.peerImpl.close() + cn.peerImpl._close() } -func (cn *PeerConn) close() { +func (cn *PeerConn) _close() { if cn.pex.IsEnabled() { cn.pex.Close() } @@ -757,7 +757,7 @@ // fastest connection, and we have active readers that signal an ordering preference. It's // conceivable that the best connection should do this, since it's least likely to waste our time if // assigned to the highest priority pieces, and assigning more than one this role would cause // significant wasted bandwidth. -func (cn *PeerConn) shouldRequestWithoutBias() bool { +func (cn *peer) shouldRequestWithoutBias() bool { return cn.t.requestStrategy.shouldRequestWithoutBias(cn.requestStrategyConnection()) } @@ -781,7 +781,7 @@ ) } // check callers updaterequests -func (cn *PeerConn) stopRequestingPiece(piece pieceIndex) bool { +func (cn *peer) stopRequestingPiece(piece pieceIndex) bool { return cn._pieceRequestOrder.Remove(bitmap.BitIndex(piece)) } @@ -789,7 +789,7 @@ // This is distinct from Torrent piece priority, which is the user's // preference. Connection piece priority is specific to a connection and is // used to pseudorandomly avoid connections always requesting the same pieces // and thus wasting effort. -func (cn *PeerConn) updatePiecePriority(piece pieceIndex) bool { +func (cn *peer) updatePiecePriority(piece pieceIndex) bool { tpp := cn.t.piecePriority(piece) if !cn.peerHasPiece(piece) { tpp = PiecePriorityNone @@ -802,7 +802,7 @@ prio = cn.t.requestStrategy.piecePriority(cn, piece, tpp, prio) return cn._pieceRequestOrder.Set(bitmap.BitIndex(piece), prio) || cn.shouldRequestWithoutBias() } -func (cn *PeerConn) getPieceInclination() []int { +func (cn *peer) getPieceInclination() []int { if cn.pieceInclination == nil { cn.pieceInclination = cn.t.getConnPieceInclination() } diff --git a/torrent.go b/torrent.go index 3f1b8f039c333c405a684820b0c0a742479ea087..4bf04ba32a075eb4345700390fc0a417f690f300 100644 --- a/torrent.go +++ b/torrent.go @@ -944,12 +944,12 @@ } func (t *Torrent) piecePriorityChanged(piece pieceIndex) { // t.logger.Printf("piece %d priority changed", piece) - for c := range t.conns { + t.iterPeers(func(c *peer) { if c.updatePiecePriority(piece) { // log.Print("conn piece priority changed") c.updateRequests() } - } + }) t.maybeNewConns() t.publishPieceChange(piece) } @@ -1769,11 +1769,11 @@ // if c.sentHave(piece) { // c.drop() // } // } - for conn := range t.conns { + t.iterPeers(func(conn *peer) { if conn.peerHasPiece(piece) { conn.updateRequests() } - } + }) } func (t *Torrent) tryCreateMorePieceHashers() { @@ -1933,11 +1933,11 @@ func (cb torrentRequestStrategyCallbacks) requestTimedOut(r request) { torrent.Add("request timeouts", 1) cb.t.cl.lock() defer cb.t.cl.unlock() - for cn := range cb.t.conns { + cb.t.iterPeers(func(cn *peer) { if cn.peerHasPiece(pieceIndex(r.Index)) { cn.updateRequests() } - } + }) } @@ -1962,9 +1962,9 @@ func (t *Torrent) disallowDataDownloadLocked() { log.Printf("disallowing data download") t.dataDownloadDisallowed = true - for c := range t.conns { + t.iterPeers(func(c *peer) { c.updateRequests() - } + }) } func (t *Torrent) AllowDataDownload() { @@ -1972,10 +1972,9 @@ t.cl.lock() defer t.cl.unlock() log.Printf("AllowDataDownload") t.dataDownloadDisallowed = false - for c := range t.conns { + t.iterPeers(func(c *peer) { c.updateRequests() - } - + }) } func (t *Torrent) SetOnWriteChunkError(f func(error)) { @@ -1997,9 +1996,20 @@ func (t *Torrent) addWebSeed(url string) { if _, ok := t.webSeeds[url]; ok { return } - t.webSeeds[url] = &peer{ - peerImpl: &webSeed{}, + p := &peer{ + t: t, + connString: url, + outgoing: true, + network: "http", + reconciledHandshakeStats: true, + peerSentHaveAll: true, } + ws := webSeed{ + peer: p, + } + p.peerImpl = &ws + t.webSeeds[url] = p + } func (t *Torrent) peerIsActive(p *peer) (active bool) { diff --git a/web_seed.go b/web_seed.go index 2242f1c8757e1a95363490b73eddf11e1ad8d60f..c292f36c4ff50d58c667f9c3a8b0897636bf4852 100644 --- a/web_seed.go +++ b/web_seed.go @@ -7,6 +7,11 @@ type webSeed struct { peer *peer httpClient *http.Client + url string +} + +func (ws *webSeed) postCancel(r request) { + panic("implement me") } func (ws *webSeed) writeInterested(interested bool) bool { @@ -31,3 +36,5 @@ func (ws *webSeed) updateRequests() { ws.peer.doRequestState() } + +func (ws *webSeed) _close() {}