java.lang.Object
net.i2p.i2ptunnel.I2PTunnelHTTPServer.Sender
All Implemented Interfaces:
Runnable
Enclosing class:
I2PTunnelHTTPServer

static class I2PTunnelHTTPServer.Senderextends Object implements Runnable
Pumps a client request body through to the I2P side and back.
  • Constructor Details

    • Sender

      public Sender(OutputStream out, InputStream in, String name, Log log)
      Create a Sender to copy data from input to output streams. Caller MUST close streams after Sender completes.
      Parameters:
      out - the output stream to write to
      in - the input stream to read from
      name - descriptive name for logging
      log - the logging instance
    • Sender

      public Sender(OutputStream out, InputStream in, String name, String targetLabel, Log log)
      Create a Sender with an explicit far-side label.
      Parameters:
      out - the output stream to write to
      in - the input stream to read from
      name - descriptive name for logging
      targetLabel - far-side identity, e.g. [skank / aanoquc2]; may be null or empty
      log - the logging instance
  • Method Details

    • setTargetLabel

      void setTargetLabel(String label)
      Set the far-side label. The request direction constructs the Sender before the request line is parsed, so the label is applied once it is known rather than at construction.
      Parameters:
      label - far-side identity, or null/empty to leave unset
    • setRequestLabel

      void setRequestLabel(String request)
      Set the parsed request line once it is known.
      Parameters:
      request - request line or path; null/empty/"Unknown request" leaves it unset
    • describeTarget

      static String describeTarget(String label, String request)
      Describe the far side for a log line: label plus optional request target, e.g. [skank / aanoquc2] GET /installers/i2pinstall.exe. Pure and static so the formatting is testable without streams.
      Parameters:
      label - far-side identity; may be null
      request - parsed request line or path; may be null
      Returns:
      the suffix to append to a transfer name, "" if neither is known
    • formatTransferRate

      static String formatTransferRate(long bytes, double secs)
      Format a transfer rate as 10.5K/s / 1.2M/s, in bytes per second using 1000-based units. Suffixes are B/s below 1 KB/s, K/s below 1 MB/s, and M/s above, so a rate never reads as a bare number with an ambiguous "kbps" that is easy to mistake for bits per second.
      Parameters:
      bytes - total bytes transferred, negative if the count is not trusted
      secs - elapsed seconds; a value of 0 or less formats as "0.0B/s"
      Returns:
      formatted rate, e.g. 60.6K/s; "0.0B/s" if secs <= 0
    • run

      public void run()
      Copy data from the input stream to the output stream, flushing after each write to push data through any intermediate buffers (e.g. GZIP or MessageOutputStream). Without explicit flushes, data can accumulate in GZIP's deflater buffer or the streaming layer's MessageOutputStream buffer, causing sawtooth throughput patterns and intermittent stalls on the receiving end.

      Tracks bytes transferred and detects stalls: if no data is read for I2PTunnelHTTPServer.ioStallTimeoutMs, the loop breaks and the partial transfer is logged. This prevents a dead peer from holding a handler or I/O thread indefinitely.

      Specified by:
      run in interface Runnable
    • getFailure

      public IOException getFailure()
      Get any IOException that occurred during the copy.
      Returns:
      the failure exception, or null if successful
    • getBytesTransferred

      public long getBytesTransferred()
      Total bytes successfully transferred (read from input, written to output).
      Returns:
      bytes transferred, updated live during the transfer
    • getName

      public String getName()
      The label this transfer is logged and reported under.
      Returns:
      the transfer description ("Server -> Client ..."); never null
    • getLastReadNanos

      public long getLastReadNanos()
      NanoTime of the last successful read. Used by callers to detect stalls without interrupting the Sender thread.
      Returns:
      System.nanoTime() of the last successful read
    • getLastWriteNanos

      public long getLastWriteNanos()
      NanoTime of the last completed write. Compared against getLastReadNanos() to tell a silent local source from a congested I2P destination.
      Returns:
      System.nanoTime() of the last completed write
    • abort

      public void abort(IOException cause)
      Abort this transfer without ever running it, closing both ends so the connection is torn down promptly.

      Used when the body cannot be handed to the I/O pool. Running the body on the caller's handler thread instead would pin that thread for the whole transfer, which is how one saturated body starves the runner pool and takes the entire service offline; a client that gets a fast close retries, while one that gets a pinned thread waits indefinitely.

      Parameters:
      cause - recorded as the transfer failure, propagated to the caller