All Implemented Interfaces:
Comparable<Peer>, EepGet.StatusListener, BandwidthListener

class WebPeerextends Peer implements EepGet.StatusListener
BEP 19. Does not have an associated PeerState. All request tracking is done here.
  • Field Details

    • _coordinator

      private final PeerCoordinator _coordinator
      The coordinator requesting the pieces.
    • _uri

      private final URI _uri
      The HTTP URL of the web seed.
    • outstandingRequests

      private final List<Request> outstandingRequests
      The requests from the coordinator awaiting their responses.
    • isMultiFile

      private final boolean isMultiFile
      True if the torrent has several files.
    • lastRequest

      private Request lastRequest
      The request most recently sent.
    • listener

      private PeerListener listener
      Listener notified of the peer's messages.
    • bitfield

      private BitField bitfield
      The pieces the seed has.
    • thread

      private Thread thread
      The thread reading from the seed.
    • connected

      private boolean connected
      True while the connection is open.
    • lastRcvd

      private long lastRcvd
      When the last data arrived.
    • maxRequests

      private int maxRequests
      Requests allowed in flight at once.
    • IDBytes

      public static final byte[] IDBytes
      The bytes identifying a BEP19 web seed, matched by the UI when it recognizes the connection.
    • HEADER_TIMEOUT

      private static final long HEADER_TIMEOUT
      Time allowed for a response header.
      See Also:
    • TOTAL_TIMEOUT

      private static final long TOTAL_TIMEOUT
      Total time allowed for one request.
      See Also:
    • INACTIVITY_TIMEOUT

      private static final long INACTIVITY_TIMEOUT
      Idle time before the seed is dropped.
      See Also:
    • TARGET_FETCH_TIME

      private static final long TARGET_FETCH_TIME
      Time a piece should be fetched within.
      See Also:
    • ZERO_BUFFER

      private static final byte[] ZERO_BUFFER
      BEP 47: zeros for serving padding ranges, written in blocks.
    • ABSOLUTE_MIN_REQUESTS

      private static final int ABSOLUTE_MIN_REQUESTS
      Fewest requests allowed in flight, 128 KB of pieces.
      See Also:
    • ABSOLUTE_MAX_REQUESTS

      private static final int ABSOLUTE_MAX_REQUESTS
      Most requests allowed in flight, 2 MB of pieces.
      See Also:
    • MIN_REQUESTS

      private final int MIN_REQUESTS
      Requests in flight we aim to keep at least.
    • MAX_REQUESTS

      private final int MAX_REQUESTS
      Requests in flight we stay below.
  • Constructor Details

    • WebPeer

      public WebPeer(PeerCoordinator coord, URI uri, PeerID peerID, MetaInfo metainfo)
      Outgoing connection. Creates a disconnected peer given a PeerID, your own id and the relevant MetaInfo.
      Parameters:
      coord - the coordinator that owns this web seed connection
      uri - must be http with .i2p host
      peerID - the 20-byte peer id this seed publishes
      metainfo - non-null
  • Method Details

    • toString

      public String toString()
      String form of the web peer.
      Overrides:
      toString in class Peer
    • getSocket

      public String getSocket()
      Socket debug string, for debug printing.
      Overrides:
      getSocket in class Peer
      Returns:
      socket debug string (for debug printing)
    • hashCode

      public int hashCode()
      The hash code of a Peer is the hash code of the peerID.
      Overrides:
      hashCode in class Peer
    • equals

      public boolean equals(Object o)
      Two Peers are equal when they have the same PeerID. All other properties are ignored.
      Overrides:
      equals in class Peer
    • runConnection

      public void runConnection(I2PSnarkUtil util, PeerListener listener, BandwidthListener bwl, BitField ignore, MagnetState mState, boolean uploadOnly)
      Runs the connection to the other peer. This method does not return until the connection is terminated.
      Overrides:
      runConnection in class Peer
      Parameters:
      util - the utility holding this client's connection settings
      listener - notified when the connection is established or ends
      bwl - the bandwidth limiter this peer's traffic is accounted against
      ignore - our bitfield, ignore
      mState - the magnet state recording this peer's piece availability
      uploadOnly - if we are complete with skipped files, i.e. a partial seed
    • fail

      private void fail(String url, int resp)
      Handle a failed fetch, banning the webseed if appropriate.
      Parameters:
      url - the URL that failed
      resp - the HTTP response code
    • getMaxPipeline

      public int getMaxPipeline()
      The max pipeline.
      Overrides:
      getMaxPipeline in class Peer
      Returns:
      maximum concurrent piece requests to this peer
    • isConnected

      public boolean isConnected()
      Whether the peer is connected.
      Overrides:
      isConnected in class Peer
      Returns:
      true if the connection to this peer is still up
    • disconnect

      void disconnect()
      Description copied from class: Peer
      Disconnects this peer, closing the socket and cleaning up state. Partial pieces are returned if deregister is true.
      Overrides:
      disconnect in class Peer
    • have

      public void have(int piece)
      Handle a have message.
      Overrides:
      have in class Peer
      Parameters:
      piece - the piece index
    • cancel

      void cancel(int piece)
      Description copied from class: Peer
      Tell the other side that we are no longer interested in any of the outstanding requests (if any) for this piece.
      Overrides:
      cancel in class Peer
      Parameters:
      piece - the piece index
    • request

      void request()
      Description copied from class: Peer
      Update the request queue. Call after adding wanted pieces.
      Overrides:
      request in class Peer
    • isInterested

      public boolean isInterested()
      Whether we are interested.
      Overrides:
      isInterested in class Peer
      Returns:
      false always; a web seed publishes no bitfield
    • isInteresting

      public boolean isInteresting()
      Whether the peer is interesting.
      Overrides:
      isInteresting in class Peer
      Returns:
      true if we want anything more from this peer
    • setChoking

      public void setChoking(boolean choke)
      Handle a choke or unchoke message.
      Overrides:
      setChoking in class Peer
      Parameters:
      choke - true to choke (stop uploading), false to unchoke (allow uploads)
    • isChoking

      public boolean isChoking()
      Whether we are choking.
      Overrides:
      isChoking in class Peer
      Returns:
      false always; we never block a web seed
    • isChoked

      public boolean isChoked()
      Whether we are choked.
      Overrides:
      isChoked in class Peer
      Returns:
      false always; choke messages are ignored
    • getInactiveTime

      public long getInactiveTime()
      The inactive time.
      Overrides:
      getInactiveTime in class Peer
      Returns:
      ms since data was last received from this peer
    • getMaxInactiveTime

      public long getMaxInactiveTime()
      The max inactive time.
      Overrides:
      getMaxInactiveTime in class Peer
      Returns:
      inactivity limit in ms before the peer is dropped
    • keepAlive

      public void keepAlive()
      Handle a keep-alive message.
      Overrides:
      keepAlive in class Peer
    • retransmitRequests

      public void retransmitRequests()
      Retransmit pending requests.
      Overrides:
      retransmitRequests in class Peer
    • completed

      public int completed()
      Handle a completed message.
      Overrides:
      completed in class Peer
      Returns:
      number of completed pieces (not bytes)
    • isCompleted

      public boolean isCompleted()
      Whether the peer completed the torrent.
      Overrides:
      isCompleted in class Peer
      Returns:
      true always; a web seed is finished as soon as it connects
    • isWebPeer

      public boolean isWebPeer()
      Returns whether this is a web peer.
      Overrides:
      isWebPeer in class Peer
      Returns:
      false (WebPeer overrides to return false for historical reasons)
    • downloaded

      public void downloaded(int size)
      BandwidthListener interface - increments the download counter for this peer. Counted in the coordinator as well, since super doesn't have a PeerState.
      Specified by:
      downloaded in interface BandwidthListener
      Overrides:
      downloaded in class Peer
      Parameters:
      size - the number of bytes downloaded
    • shouldRequest

      public boolean shouldRequest(int size)
      Should we request this many bytes?
      Overrides:
      shouldRequest in class Peer
      Parameters:
      size - the number of bytes about to be requested
      Returns:
      true if the coordinator allows this peer to request that many bytes
    • addRequest

      private void addRequest()
      Add requests for outstanding pieces, implementing part of PeerState.
    • requestNextPiece

      private boolean requestNextPiece()
      Starts requesting first chunk of next piece. Returns true if something has been added to the requests, false otherwise.
      Returns:
      true if a request for the next piece, or an adopted partial piece, was queued, false if nothing was added
    • getRequestedPieces

      private Set<Integer> getRequestedPieces()
      Returns all pieces we are currently requesting.
      Returns:
      set of piece numbers, or empty set
    • returnPartialPieces

      private List<Request> returnPartialPieces()
      Return partial pieces to the coordinator.
      Returns:
      list of partial piece requests
    • getLowestOutstandingRequest

      private Request getLowestOutstandingRequest(int piece)
      Returns the request with the lowest offset for the given piece.
      Parameters:
      piece - the piece index
      Returns:
      the lowest-offset request, or null
    • bytesTransferred

      public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url)
      This EepGet status listener helps maintain the state for the web page. Total length should be == alreadyTransferred + currentWrite + bytesRemaining for all calls.
      Specified by:
      bytesTransferred in interface EepGet.StatusListener
      Parameters:
      alreadyTransferred - total of all attempts, not including currentWrite If nonzero on the first call, a partial file of that length was found, _and_ the server supports resume. If zero on a subsequent call after some bytes are transferred (and presumably after an attemptFailed), the server does _not_ support resume and we had to start over. To track _actual_ transfer if the output file could already exist, the listener should keep its own counter, or subtract the initial alreadyTransferred value. And watch out for alreadyTransferred resetting if a resume failed...
      currentWrite - since last call to the listener
      bytesTransferred - includes headers, retries, redirects, discarded partial downloads, ...
      bytesRemaining - on this attempt only, currentWrite already subtracted - or -1 if chunked encoding or server does not return a length
      url - the URL being fetched
    • attemptFailed

      public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause)
      Attempt failed notification.
      Specified by:
      attemptFailed in interface EepGet.StatusListener
      Parameters:
      url - the address whose fetch attempt failed
      bytesTransferred - bytes received so far, counted across every attempt and including response headers
      bytesRemaining - bytes still owed, or -1 if unknown
      currentAttempt - zero-based index of the attempt that failed
      numRetries - total attempts this fetch is allowed
      cause - the exception that ended the attempt
      See Also:
    • transferComplete

      public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified)
      Transfer complete notification.
      Specified by:
      transferComplete in interface EepGet.StatusListener
      Parameters:
      alreadyTransferred - total bytes transferred
      bytesTransferred - total incl headers
      bytesRemaining - bytes still owed by the server, or -1 if chunked encoding or no Content-Length was returned
      url - the address the transfer was reading
      outputFile - null if unknown (output stream constructor)
      notModified - whether 304
      See Also:
    • transferFailed

      public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt)
      Transfer failed notification.
      Specified by:
      transferFailed in interface EepGet.StatusListener
      Parameters:
      url - the address whose transfer failed
      bytesTransferred - bytes received so far, counted across every attempt and including response headers
      bytesRemaining - bytes still owed, or -1 if unknown
      currentAttempt - zero-based index of the attempt that failed
      See Also:
    • headerReceived

      public void headerReceived(String url, int attemptNum, String key, String val)
      Note: Headers are not processed, and this is not called, for most error response codes, unless EepGet.setWriteErrorToOutput() is called before fetch(). To be changed?
      Specified by:
      headerReceived in interface EepGet.StatusListener
      Parameters:
      url - the address the header arrived on
      attemptNum - zero-based index of the attempt the header arrived on
      key - header key
      val - header value
    • attempting

      public void attempting(String url)
      Called when a new attempt to fetch the URL is starting.
      Specified by:
      attempting in interface EepGet.StatusListener
      Parameters:
      url - the URL being attempted