net.i2p.i2ptunnel

## Class I2PTunnelHTTPClientRunner

- java.lang.Object
- - java.lang.Thread
  - - net.i2p.util.I2PThread
    - - net.i2p.util.I2PAppThread
      - - net.i2p.i2ptunnel.I2PTunnelRunner
        - - net.i2p.i2ptunnel.I2PTunnelHTTPClientRunner

- All Implemented Interfaces:
    Runnable, I2PSocket.SocketErrorListener, LimitOutputStream.DoneCallback

      public class I2PTunnelHTTPClientRunner
      extends I2PTunnelRunner

  HTTP client runner that filters response headers to enforce the "Connection: close" header, ensuring browsers treat the connection as non-persistent, even if the server doesn't comply.

  This class is internal and not part of a stable public API.

  Implements proper resource cleanup, supports optional keep-alive for both I2P and browser sockets, and uses background threading for non-blocking socket closure when appropriate.

  Thread Safety: This class is not thread-safe. It is expected to be used by a single connection thread.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from class net.i2p.i2ptunnel.I2PTunnelRunner

      `I2PTunnelRunner.FailCallback, I2PTunnelRunner.SuccessCallback`

    - ### Nested classes/interfaces inherited from class net.i2p.util.I2PThread

      `I2PThread.OOMEventListener`

    - ### Nested classes/interfaces inherited from class java.lang.Thread

      `Thread.State, Thread.UncaughtExceptionHandler`

  - ### Field Summary

    - ### Fields inherited from class net.i2p.i2ptunnel.I2PTunnelRunner

      `_keepAliveI2P, _keepAliveSocket, _log, MAX_PACKET_SIZE, NETWORK_BUFFER_SIZE`

    - ### Fields inherited from class java.lang.Thread

      `MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2PTunnelHTTPClientRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialI2PData, List<I2PSocket> sockList, I2PTunnelRunner.FailCallback onFail, boolean allowKeepAliveI2P, boolean allowKeepAliveSocket, boolean isHead)` Constructs a new HTTP client runner.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected void` | `close(OutputStream out, InputStream in, OutputStream i2pout, InputStream i2pin, Socket s, I2PSocket i2ps, Thread t1, Thread t2)` Closes all streams and sockets, respecting keep-alive settings.
    `protected OutputStream` | `getSocketOut()` Returns a filtered HTTP response OutputStream that enforces the "Connection: close" header.

    - ### Methods inherited from class net.i2p.i2ptunnel.I2PTunnelRunner

      `getKeepAliveI2P, getKeepAliveSocket, getSocketIn, getStartedOn, run, setSuccessCallback, streamDone`

    - ### Methods inherited from class net.i2p.util.I2PAppThread

      `addOOMEventThreadListener, fireOOM, removeOOMEventThreadListener`

    - ### Methods inherited from class net.i2p.util.I2PThread

      `addOOMEventListener, removeOOMEventListener, start`

    - ### Methods inherited from class java.lang.Thread

      `activeCount, checkAccess, clone, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, stop, stop, suspend, toString, yield`

    - ### Methods inherited from class java.lang.Object

      `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

    - ### Methods inherited from interface net.i2p.client.streaming.I2PSocket.SocketErrorListener

      `errorOccurred`

- - ### Constructor Detail

    - #### I2PTunnelHTTPClientRunner

          public I2PTunnelHTTPClientRunner(Socket s,
                                           I2PSocket i2ps,
                                           Object slock,
                                           byte[] initialI2PData,
                                           List<I2PSocket> sockList,
                                           I2PTunnelRunner.FailCallback onFail,
                                           boolean allowKeepAliveI2P,
                                           boolean allowKeepAliveSocket,
                                           boolean isHead)

      Constructs a new HTTP client runner.
      Parameters:
        `s` - local socket (browser side)
        `i2ps` - connected I2P socket
        `slock` - synchronization lock for shared resources
        `initialI2PData` - initial data to send over I2P
        `sockList` - list of active I2P sockets
        `onFail` - callback for failure events
        `allowKeepAliveI2P` - if true, optionally keep I2P socket alive after response
        `allowKeepAliveSocket` - if true, optionally keep browser socket alive after response
        `isHead` - true if responding to an HTTP HEAD request (no body expected)
      Throws:
        `IllegalArgumentException` - if keep-alive I2P is requested but browser socket keep-alive is disabled

  - ### Method Detail

    - #### close

          protected void close(OutputStream out,
                               InputStream in,
                               OutputStream i2pout,
                               InputStream i2pin,
                               Socket s,
                               I2PSocket i2ps,
                               Thread t1,
                               Thread t2)
                        throws InterruptedException

      Closes all streams and sockets, respecting keep-alive settings. Optionally closes I2P socket in a background thread if keep-alive is enabled on the browser socket.
      Overrides:
        `close` in class `I2PTunnelRunner`
      Parameters:
        `out` - may be null
        `in` - may be null
        `i2pout` - may be null
        `i2pin` - may be null
        `t1` - may be null
        `t2` - may be null, ignored, we only join t1
      Throws:
        `InterruptedException`

    - #### getSocketOut

          protected OutputStream getSocketOut()
                                       throws IOException

      Returns a filtered HTTP response OutputStream that enforces the "Connection: close" header. Should be called only once per instance.
      Overrides:
        `getSocketOut` in class `I2PTunnelRunner`
      Returns:
        an output stream wrapping the socket's output stream that filters HTTP headers
      Throws:
        `IllegalStateException` - if called more than once
        `IOException` - if an I/O error occurs