Beispiel #1
0
 /**
  * Build the announce request tracker message.
  *
  * @param event The announce event (can be <tt>NONE</tt> or <em>null</em>)
  * @return Returns an instance of a {@link HTTPAnnounceRequestMessage} that can be used to
  *     generate the fully qualified announce URL, with parameters, to make the announce request.
  * @throws UnsupportedEncodingException
  * @throws IOException
  * @throws MessageValidationException
  */
 private HTTPAnnounceRequestMessage buildAnnounceRequest(AnnounceRequestMessage.RequestEvent event)
     throws UnsupportedEncodingException, IOException, MessageValidationException {
   // Build announce request message
   return HTTPAnnounceRequestMessage.craft(
       this.torrent.getInfoHash(),
       this.peer.getPeerId().array(),
       this.peer.getPort(),
       this.torrent.getUploaded(),
       this.torrent.getDownloaded(),
       this.torrent.getLeft(),
       true,
       false,
       event,
       this.peer.getIp(),
       AnnounceRequestMessage.DEFAULT_NUM_WANT);
 }
Beispiel #2
0
  /**
   * Build, send and process a tracker announce request.
   *
   * <p>This function first builds an announce request for the specified event with all the required
   * parameters. Then, the request is made to the tracker and the response analyzed.
   *
   * <p>All registered {@link AnnounceResponseListener} objects are then fired with the decoded
   * payload.
   *
   * @param event The announce event type (can be AnnounceEvent.NONE for periodic updates).
   * @param inhibitEvents Prevent event listeners from being notified.
   */
  @Override
  public void announce(AnnounceRequestMessage.RequestEvent event, boolean inhibitEvents)
      throws AnnounceException {
    logger.info(
        "Announcing{} to tracker with {}U/{}D/{}L bytes...",
        new Object[] {
          this.formatAnnounceEvent(event),
          this.torrent.getUploaded(),
          this.torrent.getDownloaded(),
          this.torrent.getLeft()
        });

    URL target = null;
    try {
      HTTPAnnounceRequestMessage request = this.buildAnnounceRequest(event);
      target = request.buildAnnounceURL(this.tracker.toURL());
    } catch (MalformedURLException mue) {
      throw new AnnounceException("Invalid announce URL (" + mue.getMessage() + ")", mue);
    } catch (MessageValidationException mve) {
      throw new AnnounceException(
          "Announce request creation violated " + "expected protocol (" + mve.getMessage() + ")",
          mve);
    } catch (IOException ioe) {
      throw new AnnounceException(
          "Error building announce request (" + ioe.getMessage() + ")", ioe);
    }

    HttpURLConnection conn = null;
    InputStream in = null;
    try {
      conn = (HttpURLConnection) target.openConnection();
      in = conn.getInputStream();
    } catch (IOException ioe) {
      if (conn != null) {
        in = conn.getErrorStream();
      }
    }

    // At this point if the input stream is null it means we have neither a
    // response body nor an error stream from the server. No point in going
    // any further.
    if (in == null) {
      throw new AnnounceException("No response or unreachable tracker!");
    }

    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      baos.write(in);

      // Parse and handle the response
      HTTPTrackerMessage message = HTTPTrackerMessage.parse(ByteBuffer.wrap(baos.toByteArray()));
      baos.close(); // close stream
      this.handleTrackerAnnounceResponse(message, inhibitEvents);
    } catch (IOException ioe) {
      throw new AnnounceException("Error reading tracker response!", ioe);
    } catch (MessageValidationException mve) {
      throw new AnnounceException(
          "Tracker message violates expected " + "protocol (" + mve.getMessage() + ")", mve);
    } finally {
      // Make sure we close everything down at the end to avoid resource
      // leaks.
      try {
        in.close();
      } catch (IOException ioe) {
        logger.warn("Problem ensuring error stream closed!", ioe);
      }

      // This means trying to close the error stream as well.
      InputStream err = conn.getErrorStream();
      if (err != null) {
        try {
          err.close();
        } catch (IOException ioe) {
          logger.warn("Problem ensuring error stream closed!", ioe);
        }
      }
    }
  }