diff --git a/client.go b/client.go index 646f034f..04547648 100644 --- a/client.go +++ b/client.go @@ -1091,6 +1091,7 @@ func (cl *Client) newTorrent(ih metainfo.Hash, specStorage storage.ClientImpl) ( 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 @@ func (cl *Client) AddTorrent(mi *metainfo.MetaInfo) (T *Torrent, err error) { 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 9ec40a28..879ab6ce 100644 --- a/peerconn.go +++ b/peerconn.go @@ -41,7 +41,7 @@ type peerImpl interface { cancel(request) bool request(request) bool connectionFlags() string - close() + _close() postCancel(request) drop() } @@ -343,10 +343,10 @@ func (cn *peer) close() { } 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 @@ func iterUnbiasedPieceRequestOrder(cn requestStrategyConnection, f func(piece pi // 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 @@ func (cn *peer) iterPendingRequests(piece pieceIndex, f func(request) bool) bool } // 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 @@ func (cn *PeerConn) stopRequestingPiece(piece pieceIndex) bool { // 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 @@ func (cn *PeerConn) updatePiecePriority(piece pieceIndex) bool { 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 3f1b8f03..4bf04ba3 100644 --- a/torrent.go +++ b/torrent.go @@ -944,12 +944,12 @@ func (t *Torrent) maybeNewConns() { 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 @@ func (t *Torrent) onIncompletePiece(piece pieceIndex) { // 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) DisallowDataDownload() { 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 @@ func (t *Torrent) AllowDataDownload() { 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 2242f1c8..c292f36c 100644 --- a/web_seed.go +++ b/web_seed.go @@ -7,6 +7,11 @@ import ( 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) drop() { func (ws *webSeed) updateRequests() { ws.peer.doRequestState() } + +func (ws *webSeed) _close() {}