net.i2p.i2ptunnel

## Class I2PTunnelHTTPClientBase

- java.lang.Object
- - net.i2p.util.EventDispatcherImpl
  - - net.i2p.i2ptunnel.I2PTunnelTask
    - - net.i2p.i2ptunnel.I2PTunnelClientBase
      - - net.i2p.i2ptunnel.I2PTunnelHTTPClientBase

- All Implemented Interfaces:
    Runnable, EventDispatcher
  Direct Known Subclasses:
    I2PTunnelConnectClient, I2PTunnelHTTPClient

      public abstract class I2PTunnelHTTPClientBase
      extends I2PTunnelClientBase
      implements Runnable

  Common things for HTTPClient and ConnectClient Retrofit over them in 0.8.2

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected static class` | `I2PTunnelHTTPClientBase.AuthResult` Authentication result status for HTTP client connections
    `protected class` | `I2PTunnelHTTPClientBase.OnProxySuccess` Callback for successful proxy connections.
    `protected class` | `I2PTunnelHTTPClientBase.OnTimeout` Callback for timeout events.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected static AtomicLong` | `__requestId`
    `protected List<String>` | `_proxyList`
    `static String` | `BASIC_AUTH`
    `protected static int` | `BROWSER_READ_TIMEOUT` Failsafe
    `protected static int` | `DEFAULT_READ_TIMEOUT` -1 (forever) as of 0.9.36, so that large POSTs won't timeout on the read side
    `static String` | `DIGEST_AUTH`
    `protected static String` | `ERR_DESTINATION_UNKNOWN`
    `protected static String` | `ERR_NO_OUTPROXY`
    `protected static int` | `INITIAL_SO_TIMEOUT` This is a standard soTimeout, not a total timeout.
    `static String` | `PROP_AUTH` all auth @since 0.8.2
    `static String` | `PROP_OUTPROXY_AUTH`
    `static String` | `PROP_OUTPROXY_PW`
    `static String` | `PROP_OUTPROXY_PW_PREFIX`
    `static String` | `PROP_OUTPROXY_USER`
    `static String` | `PROP_OUTPROXY_USER_PREFIX` passwords for specific outproxies may be added with outproxyUsername.fooproxy.i2p=user and outproxyPassword.fooproxy.i2p=pw
    `static String` | `PROP_PROXY_DIGEST_PREFIX` new style MD5 auth
    `static String` | `PROP_PROXY_DIGEST_SHA256_SUFFIX`
    `static String` | `PROP_PROXY_DIGEST_SUFFIX`
    `static String` | `PROP_PW`
    `static String` | `PROP_PW_PREFIX` additional users may be added with proxyPassword.user=pw
    `static String` | `PROP_SSL_OUTPROXIES`
    `static String` | `PROP_USE_OUTPROXY_PLUGIN`
    `static String` | `PROP_USER`
    `protected static String` | `SUCCESS_RESPONSE`

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

      `_clientId, _context, _log, _ownDest, DEFAULT_CONNECT_TIMEOUT, dest, l, listenerReady, mySockets, PROP_USE_SSL, sockLock, sockMgr, ss`

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

      `open, tunnel`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2PTunnelHTTPClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName, I2PTunnel tunnel)`
    `I2PTunnelHTTPClientBase(int localPort, Logging l, I2PSocketManager sktMgr, I2PTunnel tunnel, EventDispatcher notifyThis, long clientId)` This constructor always starts the tunnel (ignoring the i2cp.delayOpen option).

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected String` | `_t(String key)` Translate
    `protected String` | `_t(String key, Object o)` Translate {0}
    `protected String` | `_t(String key, Object o, Object o2)` Translate {0} and {1}
    `protected I2PTunnelHTTPClientBase.AuthResult` | `authorize(Socket s, long requestId, String method, String authorization)` Authorization Ref: RFC 2617 If the socket is an InternalSocket, no auth required.
    `static String` | `decodeIDNHost(String host)` Decode a hostname for display.
    `protected String` | `getAuthError(boolean isStale)` What to send if digest auth fails
    `protected static String` | `getErrorPage(I2PAppContext ctx, String base, String backup)` foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht, or the backup byte array on fail.
    `protected String` | `getErrorPage(String base, String backup)` foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht, or the backup byte array on fail.
    `protected String` | `getPrefix(long requestId)` Generates a unique log prefix for request tracking.
    `protected abstract String` | `getRealm()`
    `protected void` | `handleClientException(Exception ex, OutputStream out, String targetRequest, boolean usingWWWProxy, String wwwProxy, long requestId)`
    `protected void` | `handleI2PSocketException(I2PSocketException ise, OutputStream out, String targetRequest, boolean usingWWWProxy, String wwwProxy)` Generate an error page based on the status code in our custom exception.
    `protected boolean` | `isDigestAuthRequired()` Checks if HTTP Digest authentication is required by the outproxy.
    `protected void` | `noteProxyResult(String proxy, String host, boolean isSSL, boolean ok)` Update the cache and note if failed.
    `void` | `optionsUpdated(I2PTunnel tunnel)` Update the outproxy list then call super.
    `protected String` | `selectProxy(String host)` Selects an appropriate outproxy for the given host from the proxy pool.
    `protected String` | `selectSSLProxy(String host)` Selects an SSL-capable outproxy for HTTPS connections.
    `protected void` | `writeErrorMessage(String errMessage, OutputStream out, String targetRequest, boolean usingWWWProxy, String wwwProxy)` No jump servers or extra message
    `protected void` | `writeErrorMessage(String errMessage, OutputStream out, String targetRequest, boolean usingWWWProxy, String wwwProxy, String jumpServers)` No extra message
    `protected void` | `writeErrorMessage(String errMessage, String extraMessage, OutputStream out, String targetRequest, boolean usingWWWProxy, String wwwProxy)` No jump servers
    `protected void` | `writeErrorMessage(String errMessage, String extraMessage, OutputStream outs, String targetRequest, boolean usingWWWProxy, String wwwProxy, String jumpServers)`
    `static void` | `writeFooter(OutputStream out)` Flushes.
    `static void` | `writeFooter(Writer out)` Flushes.

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

      `buildSocketManager, buildSocketManager, buildSocketManager, buildSocketManager, clientConnectionRun, close, closeSocket, createI2PSocket, createI2PSocket, createI2PSocket, destroy, getDefaultOptions, getDefaultOptions, getListenHost, getLocalPort, getSocketManager, getSocketManager, getSocketManager, killSharedClient, manageConnection, run, startRunning, verifySocketManager`

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

      `connected, disconnected, errorOccurred, getBooleanOption, getId, getTunnel, isOpen, reportAbuse, routerDisconnected, setId, setName, setTunnel, toString`

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

      `attachEventDispatcher, detachEventDispatcher, getEventDispatcher, getEvents, getEventValue, ignoreEvents, notifyEvent, unIgnoreEvents, waitEventValue`

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

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

    - ### Methods inherited from interface java.lang.Runnable

      `run`

- - ### Field Detail

    - #### __requestId

          protected static final AtomicLong __requestId

    - #### _proxyList

          protected final List<String> _proxyList

    - #### BASIC_AUTH

          public static final String BASIC_AUTH

      See Also:
        Constant Field Values

    - #### BROWSER_READ_TIMEOUT

          protected static final int BROWSER_READ_TIMEOUT

      Failsafe
      See Also:
        Constant Field Values

    - #### DEFAULT_READ_TIMEOUT

          protected static final int DEFAULT_READ_TIMEOUT

      -1 (forever) as of 0.9.36, so that large POSTs won't timeout on the read side
      See Also:
        Constant Field Values

    - #### DIGEST_AUTH

          public static final String DIGEST_AUTH

      See Also:
        Constant Field Values

    - #### ERR_DESTINATION_UNKNOWN

          protected static final String ERR_DESTINATION_UNKNOWN

      See Also:
        Constant Field Values

    - #### ERR_NO_OUTPROXY

          protected static final String ERR_NO_OUTPROXY

      See Also:
        Constant Field Values

    - #### INITIAL_SO_TIMEOUT

          protected static final int INITIAL_SO_TIMEOUT

      This is a standard soTimeout, not a total timeout. We have no slowloris protection on the client side. See I2PTunnelHTTPServer or SAM's ReadLine if we need that.
      See Also:
        Constant Field Values

    - #### PROP_AUTH

          public static final String PROP_AUTH

      all auth @since 0.8.2
      See Also:
        Constant Field Values

    - #### PROP_OUTPROXY_AUTH

          public static final String PROP_OUTPROXY_AUTH

      See Also:
        Constant Field Values

    - #### PROP_OUTPROXY_PW

          public static final String PROP_OUTPROXY_PW

      See Also:
        Constant Field Values

    - #### PROP_OUTPROXY_PW_PREFIX

          public static final String PROP_OUTPROXY_PW_PREFIX

      See Also:
        Constant Field Values

    - #### PROP_OUTPROXY_USER

          public static final String PROP_OUTPROXY_USER

      See Also:
        Constant Field Values

    - #### PROP_OUTPROXY_USER_PREFIX

          public static final String PROP_OUTPROXY_USER_PREFIX

      passwords for specific outproxies may be added with outproxyUsername.fooproxy.i2p=user and outproxyPassword.fooproxy.i2p=pw
      See Also:
        Constant Field Values

    - #### PROP_PROXY_DIGEST_PREFIX

          public static final String PROP_PROXY_DIGEST_PREFIX

      new style MD5 auth
      See Also:
        Constant Field Values

    - #### PROP_PROXY_DIGEST_SHA256_SUFFIX

          public static final String PROP_PROXY_DIGEST_SHA256_SUFFIX

      See Also:
        Constant Field Values

    - #### PROP_PROXY_DIGEST_SUFFIX

          public static final String PROP_PROXY_DIGEST_SUFFIX

      See Also:
        Constant Field Values

    - #### PROP_PW

          public static final String PROP_PW

      See Also:
        Constant Field Values

    - #### PROP_PW_PREFIX

          public static final String PROP_PW_PREFIX

      additional users may be added with proxyPassword.user=pw
      See Also:
        Constant Field Values

    - #### PROP_SSL_OUTPROXIES

          public static final String PROP_SSL_OUTPROXIES

      See Also:
        Constant Field Values

    - #### PROP_USE_OUTPROXY_PLUGIN

          public static final String PROP_USE_OUTPROXY_PLUGIN

      See Also:
        Constant Field Values

    - #### PROP_USER

          public static final String PROP_USER

      See Also:
        Constant Field Values

    - #### SUCCESS_RESPONSE

          protected static final String SUCCESS_RESPONSE

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### I2PTunnelHTTPClientBase

          public I2PTunnelHTTPClientBase(int localPort,
                                         boolean ownDest,
                                         Logging l,
                                         EventDispatcher notifyThis,
                                         String handlerName,
                                         I2PTunnel tunnel)
                                  throws IllegalArgumentException

      Throws:
        `IllegalArgumentException`

    - #### I2PTunnelHTTPClientBase

          public I2PTunnelHTTPClientBase(int localPort,
                                         Logging l,
                                         I2PSocketManager sktMgr,
                                         I2PTunnel tunnel,
                                         EventDispatcher notifyThis,
                                         long clientId)
                                  throws IllegalArgumentException

      This constructor always starts the tunnel (ignoring the i2cp.delayOpen option). It is used to add a client to an existing socket manager.
      Parameters:
        `sktMgr` - the existing socket manager
      Throws:
        `IllegalArgumentException`

  - ### Method Detail

    - #### _t

          protected String _t(String key)

      Translate

    - #### _t

          protected String _t(String key,
                              Object o)

      Translate {0}

    - #### _t

          protected String _t(String key,
                              Object o,
                              Object o2)

      Translate {0} and {1}

    - #### authorize

          protected I2PTunnelHTTPClientBase.AuthResult authorize(Socket s,
                                                                 long requestId,
                                                                 String method,
                                                                 String authorization)

      Authorization Ref: RFC 2617 If the socket is an InternalSocket, no auth required.
      Parameters:
        `method` - GET, POST, etc.
        `authorization` - may be null, the full auth line e.g. "Basic lskjlksjf"
      Returns:
        success

    - #### decodeIDNHost

          public static String decodeIDNHost(String host)

      Decode a hostname for display. Returns original string on any error.

    - #### getAuthError

          protected String getAuthError(boolean isStale)

      What to send if digest auth fails

    - #### getErrorPage

          protected static String getErrorPage(I2PAppContext ctx,
                                               String base,
                                               String backup)

      foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht, or the backup byte array on fail. .ht files must be UTF-8 encoded and use \r\n terminators so the HTTP headers are conformant. We can't use FileUtil.readFile() because it strips \r
      Returns:
        non-null

    - #### getErrorPage

          protected String getErrorPage(String base,
                                        String backup)

      foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht, or the backup byte array on fail. .ht files must be UTF-8 encoded and use \r\n terminators so the HTTP headers are conformant. We can't use FileUtil.readFile() because it strips \r
      Returns:
        non-null

    - #### getPrefix

          protected String getPrefix(long requestId)

      Generates a unique log prefix for request tracking.

      This method creates a consistent prefix string that includes the request ID for correlating log entries across multiple threads and connections.

      Parameters:
        `requestId` - the unique identifier for this request
      Returns:
        a formatted string suitable for logging

    - #### getRealm

          protected abstract String getRealm()

    - #### handleClientException

          protected void handleClientException(Exception ex,
                                               OutputStream out,
                                               String targetRequest,
                                               boolean usingWWWProxy,
                                               String wwwProxy,
                                               long requestId)

      Parameters:
        `ex` - may be null

    - #### handleI2PSocketException

          protected void handleI2PSocketException(I2PSocketException ise,
                                                  OutputStream out,
                                                  String targetRequest,
                                                  boolean usingWWWProxy,
                                                  String wwwProxy)

      Generate an error page based on the status code in our custom exception.
      Parameters:
        `ise` - may be null

    - #### isDigestAuthRequired

          protected boolean isDigestAuthRequired()

      Checks if HTTP Digest authentication is required by the outproxy.

      This method checks the configured authentication requirements and determines whether the current request requires digest authentication.

      Returns:
        true if digest authentication is required, false otherwise

    - #### noteProxyResult

          protected void noteProxyResult(String proxy,
                                         String host,
                                         boolean isSSL,
                                         boolean ok)

      Update the cache and note if failed.
      Parameters:
        `proxy` - which
        `host` - clearnet hostname targeted
        `isSSL` - set to FALSE for ConnectClient
        `ok` - success or failure

    - #### optionsUpdated

          public void optionsUpdated(I2PTunnel tunnel)

      Update the outproxy list then call super.
      Overrides:
        `optionsUpdated` in class `I2PTunnelClientBase`

    - #### selectProxy

          protected String selectProxy(String host)

      Selects an appropriate outproxy for the given host from the proxy pool.

      This method implements load balancing across multiple configured outproxies. It uses a simple round-robin or hash-based selection to distribute requests evenly across the available proxies. Failed proxies are remembered and temporarily skipped.

      Parameters:
        `host` - the target hostname to route through the outproxy (may be used for stickiness)
      Returns:
        the selected proxy destination string (Base32 address), or null if no proxies configured
      See Also:
        `_proxyList`

    - #### selectSSLProxy

          protected String selectSSLProxy(String host)

      Selects an SSL-capable outproxy for HTTPS connections.

      This method is similar to selectProxy() but only considers outproxies configured for SSL support (via i2ptunnel.httpclient.SSLOutproxies).

      Unlike selectProxy(), we parse the option on the fly so it can be changed without restart. ConnectClient should use selectProxy().

      Parameters:
        `host` - the target hostname (may be used for proxy stickiness)
      Returns:
        the selected SSL proxy destination, or null if none configured
      See Also:
        `selectProxy(String)`

    - #### writeErrorMessage

          protected void writeErrorMessage(String errMessage,
                                           OutputStream out,
                                           String targetRequest,
                                           boolean usingWWWProxy,
                                           String wwwProxy)
                                    throws IOException

      No jump servers or extra message
      Throws:
        `IOException`

    - #### writeErrorMessage

          protected void writeErrorMessage(String errMessage,
                                           OutputStream out,
                                           String targetRequest,
                                           boolean usingWWWProxy,
                                           String wwwProxy,
                                           String jumpServers)
                                    throws IOException

      No extra message
      Parameters:
        `jumpServers` - comma- or space-separated list, or null
      Throws:
        `IOException`

    - #### writeErrorMessage

          protected void writeErrorMessage(String errMessage,
                                           String extraMessage,
                                           OutputStream out,
                                           String targetRequest,
                                           boolean usingWWWProxy,
                                           String wwwProxy)
                                    throws IOException

      No jump servers
      Parameters:
        `extraMessage` - extra message or null, will be HTML-escaped
      Throws:
        `IOException`

    - #### writeErrorMessage

          protected void writeErrorMessage(String errMessage,
                                           String extraMessage,
                                           OutputStream outs,
                                           String targetRequest,
                                           boolean usingWWWProxy,
                                           String wwwProxy,
                                           String jumpServers)
                                    throws IOException

      Parameters:
        `jumpServers` - comma- or space-separated list, or null
        `extraMessage` - extra message or null, will be HTML-escaped
      Throws:
        `IOException`

    - #### writeFooter

          public static void writeFooter(OutputStream out)
                                  throws IOException

      Flushes. Public only for LocalHTTPServer, not for general use
      Throws:
        `IOException`

    - #### writeFooter

          public static void writeFooter(Writer out)
                                  throws IOException

      Flushes. Public only for LocalHTTPServer, not for general use
      Throws:
        `IOException`