java.lang.Object
net.i2p.util.EventDispatcherImpl
net.i2p.i2ptunnel.I2PTunnelTask
net.i2p.i2ptunnel.I2PTunnelServer
net.i2p.i2ptunnel.I2PTunnelHTTPServer
net.i2p.i2ptunnel.I2PTunnelHTTPBidirServer
- All Implemented Interfaces:
Runnable, EventDispatcher
Bidirectional HTTP server tunnel combining server and client functionality.
Extends I2PTunnelHTTPServer to provide both inbound and outbound HTTP connectivity through I2P. Creates a server tunnel for receiving requests and a client tunnel (proxy) for outbound requests, enabling bidirectional HTTP communication through a single I2P destination.
This class manages two tunnel components:
- Server: Incoming HTTP connections via I2PServerSocket
- Client: I2PTunnelHTTPBidirProxy for outbound HTTP requests
Useful for applications requiring both server and client HTTP capabilities through I2P, such as web applications making external API calls.
Nested Class Summary
Nested classes/interfaces inherited from class I2PTunnelHTTPServer
I2PTunnelHTTPServer.SenderModifier and TypeClassDescription(package private) static classPumps a client request body through to the I2P side and back.Field Summary
Fields inherited from class I2PTunnelHTTPServer
_stallEventCount, CONN_CLOSE, CONN_KEEPALIVE, CONN_NONE, CONN_UPGRADE, DEFAULT_HEADER_TIMEOUT_MS, DEFAULT_KEEPALIVE_TIMEOUT_MS, DEFAULT_POST_BAN_TIME, DEFAULT_POST_MAX, DEFAULT_POST_TOTAL_BAN_TIME, DEFAULT_POST_TOTAL_MAX, DEFAULT_POST_WINDOW, ERR_FORBIDDEN, ERR_NOT_FOUND, ERR_REQUEST_TIMEOUT, IO_THREADS_MAX, IO_THREADS_MIN, ioStallTimeoutMs, ioTransferThreads, MAX_HEADER_TIMEOUT_MS, MAX_KEEPALIVE_TIMEOUT_MS, MAX_STALL_WINDOW_MS, MAX_TRACKED_ERROR_CLIENTS, MIN_HEADER_TIMEOUT_MS, MIN_KEEPALIVE_TIMEOUT_MS, OPT_ADD_RESPONSE_HEADER_ALLOW, OPT_ADD_RESPONSE_HEADER_CACHE_CONTROL, OPT_ADD_RESPONSE_HEADER_NOSNIFF, OPT_ADD_RESPONSE_HEADER_REFERRER_POLICY, OPT_KEEPALIVE, OPT_POST_BAN_TIME, OPT_POST_MAX, OPT_POST_TOTAL_BAN_TIME, OPT_POST_TOTAL_MAX, OPT_POST_WINDOW, OPT_REJECT_INPROXY, OPT_REJECT_REFERER, OPT_REJECT_USER_AGENTS, OPT_USER_AGENTS, PROP_HEADER_TIMEOUT, PROP_KEEPALIVE, PROP_KEEPALIVE_TIMEOUT, REQUEST_ERROR_LOG_INTERVAL_MS, STALL_SIDE_DESTINATION, STALL_SIDE_INDETERMINATE, STALL_SIDE_SOURCE, STALL_WINDOW_FLOOR_MSModifier and TypeFieldDescription(package private) static final AtomicLongMonotonically increasing counter of stall events detected by runOnIO or the Sender.(package private) static final intConnection: close or unknown value.(package private) static final intConnection: keep-alive.(package private) static final intConnection header absent.(package private) static final intConnection: upgrade (websocket).static final longDefault first-request header timeout (ms).static final longDefault idle keepalive wait (ms); short enough to free the handler thread, long enough for a browser to reuse the connection.static final intPost throttle window (seconds).static final intDefault max posts per window.static final intDefault total ban time for excessive posts.static final intDefault max total posts before ban.static final intDefault post rate-limit window (seconds).(package private) static final String403 Forbidden error response.(package private) static final String404 Not Found error response.protected static final StringHTTP 408 Request Timeout error response.(package private) static final intMaximum global I/O budget (Tuner max must match).(package private) static final intAbsolute floor for the global I/O budget.(package private) static longCurrent stall window, adjustable by the Tuner between the floor and max.(package private) static intDefault I/O transfer threads (global budget); Tuner adjusts viaTunnelControllerGroup.static final longCeiling forI2PTunnelHTTPServer.PROP_HEADER_TIMEOUT(ms).static final longCeiling forI2PTunnelHTTPServer.PROP_KEEPALIVE_TIMEOUT(ms).(package private) static final longHard ceiling on a progress-scaled window, ms.(package private) static final intCap on distinct clients tracked for warning rate limiting, so a flood from many distinct peers cannot grow this map without bound.static final longBounds forI2PTunnelHTTPServer.PROP_HEADER_TIMEOUT(ms).static final longBounds forI2PTunnelHTTPServer.PROP_KEEPALIVE_TIMEOUT(ms).static final StringConfig key to add Allow response header.static final StringConfig key to add Cache-Control response header.static final StringConfig key to add X-Content-Type-Options: nosniff.static final StringConfig key to add Referrer-Policy response header.static final StringConfig key to enable keepalive (legacy short form; see PROP_KEEPALIVE).static final StringConfig key for post ban time.static final StringConfig key for max posts.static final StringConfig key for post total ban time.static final StringConfig key for max total posts.static final StringConfig key for post check time window.static final StringConfig key to reject requests from inproxy.static final StringConfig key to reject requests with Referer header.static final StringConfig key to reject specific User-Agents.static final StringConfig key for User-Agent reject list.static final StringConfig key for the first-request header read timeout, in ms.static final StringConfig key to enable HTTP persistent connections; live via optionsUpdated.static final StringConfig key for the idle keepalive wait before closing a persistent connection, in ms.(package private) static final longMinimum interval between per-client "Request error" warnings.(package private) static final StringStall side reported when the destination moved nothing.(package private) static final StringStall side reported when both stamps are equally stale.(package private) static final StringStall side reported when the source moved nothing and only a read blocked.(package private) static final longFloor for the configured stall window, ms.Fields inherited from class I2PTunnelServer
_clientExecutor, _log, _tcg, bidir, DEFAULT_HANDLE_MS, i2pss, l, localPort, MAX_QUEUE_DRAIN_MS, PROP_ALT_PKF, PROP_MAX_CONNECTIONS, PROP_READ_TIMEOUT, PROP_SERVER_THREADS, PROP_UNIQUE_LOCAL, PROP_USE_SSL, PROP_WRITE_TIMEOUT, readTimeout, remoteHost, remotePort, serverId, slock, sockMgr, sslLock, taskModifier and TypeFieldDescriptionprotected ThreadPoolExecutorPool running the per-connection client handlers, taken from the TunnelControllerGroup so server load stays inside its own thread budget.protected final LogLogger for this tunnel server.protected TunnelControllerGroupThe controller group that owns this tunnel's runner pool, cached fromTunnelControllerGroup.getInstance()once inI2PTunnelServer.run().protected booleanTrue for HTTP bidirectional server mode.(package private) static final longFallback average handler time (ms) when no recent blockingHandleTime sample is available for the drain estimate.protected I2PServerSocketThe listening server socket, null until the tunnel is started.protected final LoggingClient-visible log channel: every lifecycle notice and warning reported to the I2P client (bad option values, unresolvable hosts, lingering connections).protected intLocal port a HTTP bidir subclass hands to its proxy, replacing theI2PTunnelServer.DEFAULT_LOCAL_PORTplaceholder.(package private) static final longReject only when a fully busy pool would need longer than this to drain the queue.static final StringConfig key naming an alternate private key file.static final StringConfig key to cap concurrent inbound connections; 0 (default) = unlimited.static final StringConfig key to override the socket read timeout in ms; 0 (default) = shut down silent connections promptly (HTTP server falls back to SERVER_READ_TIMEOUT_GET).static final StringConfig key to cap this tunnel's private server handler pool in threads.static final StringConfig key to enable unique local address.static final StringConfig key to enable SSL.static final StringConfig key to override the outbound write timeout in ms (0 = use the streaming default, which can be the full 120s disconnect timeout with no ACK progress).protected longDefault timeout - override if desired.protected InetAddressRemote endpoint of the current connection, null for the listening server.protected intRemote port of the current connection, 0 for the listening server.protected static longServer ID for HTTP bidirectional proxies; not incremented, always 0.protected final ObjectPassed to each I2PTunnelRunner so connection teardown serializes on it.protected final I2PSocketManagerBuilds the outbound sockets used to reach each configured destination.protected final ObjectGuards lazy creation of _sslFactory.protected I2PTunnelTaskHTTP bidirectional server task, null for standard tunnel server.Constructor Summary
ConstructorsConstructorDescriptionI2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, File privkey, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel with a private key file.I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, InputStream privData, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel with an input stream for the private key.I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel.Method Summary
All MethodsModifier and TypeMethodDescriptionprivate voidfinishSetupI2PTunnelHTTPBidirServer(Logging l, int proxyport) Completes the bidirectional server setup by initializing the client proxy.Methods inherited from class I2PTunnelHTTPServer
addEntry, blockingHandle, classifyStalledSide, close, computeStallWindowMs, createIOExecutor, extractRequestUrl, getBodyAbortCount, getConnectionType, getHeaderTimeout, getIOExecutor, getIOMaxPoolUtilization, getIOStallTimeoutMs, getIOTransferActiveCount, getIOTransferThreads, getKeepAliveTimeout, getStallEventCount, handOffBody, handOffBody, hasGzipEncoding, ioPoolFloor, ioQueueCap, isBodyWatchdogStalled, isGzipAllowed, isInproxyRejection, isKeepAlive, isKeepAliveRequest, isPostThrottled, isRefererRejection, isUserAgentRejection, maxIOThreads, optionsUpdated, parseHeaderTimeout, parseKeepAlive, parseKeepAliveTimeout, readHeaders, readHeaders, readRequestHeaders, readRequestHeaders, rebalanceAllIOPools, rejectConnection, rejectConnection, resetRequestErrorLimiter, setEntry, setHeaderTimeout, setIOStallTimeoutMs, setIOTransferThreads, setKeepAlive, setKeepAliveTimeout, shouldLogRequestError, startRunning, trackedErrorClientsModifier and TypeMethodDescription(package private) static voidAdd an entry to the multimap.protected voidblockingHandle(I2PSocket socket) Called by the thread pool of I2PSocket handlers.(package private) static StringclassifyStalledSide(long readAgeMs, long writeAgeMs, long bytesTransferred) Which side of a stalled body transfer stopped making progress.booleanclose(boolean forced) Close the tunnel and stop the POST throttler.(package private) static longcomputeStallWindowMs(long baseMs, long bytesTransferred) Stall window for a body that has already movedbytesTransferred.(package private) static ThreadPoolExecutorcreateIOExecutor(int threads) Create a fixed-size I/O transfer pool.(package private) static StringextractRequestUrl(String headers) Extract the request URL from the client's headers for logging.static longCount of bodies dropped because the I/O pool had no free worker.(package private) static intgetConnectionType(Map<String, List<String>> headers) Classify the request's Connection header value.longHow long the first request's headers may take to arrive.(package private) ThreadPoolExecutorGet (creating on first use) this tunnel's private I/O pool for data transfer.static doubleThe busiest pool's utilization: its active plus queued transfers divided by its present maximum, as a rate that may exceed 1.0 when the queue is backing up past the pool's ceiling.static longGet the current I/O stall timeout in ms.static intGet the saturation pressure summed across all live I/O pools: running workers plus queued transfers.static intGet the current I/O transfer pool size.longHow long an idle keepalive connection is held before it is probed.static longGet the total number of stall events detected by Sender since router start.(package private) static booleanhandOffBody(ThreadPoolExecutor pool, I2PTunnelHTTPServer.Sender s, String desc) Hand off the response body to the I/O transfer pool, or run it inline when the pool is null or shut down.(package private) static booleanhandOffBody(ThreadPoolExecutor pool, I2PTunnelHTTPServer.Sender s, String desc, Runnable onCompletion) AsI2PTunnelHTTPServer.handOffBody(ThreadPoolExecutor, Sender, String)with a completion callback invoked after the Sender finishes (success, failure, or abort), on the pool worker when submitted and on the caller otherwise.(package private) static booleanhasGzipEncoding(String enc) Whether the Accept-Encoding value includes x-i2p-gzip.(package private) static intThe floor for one I/O pool, proportional to the budget and pool count.(package private) static intioQueueCap(int threads) Maximum queued body tasks for an I/O pool withthreadsworkers.(package private) static booleanisBodyWatchdogStalled(long lastReadNanos, long nowNanos, long stallNs) Decide whether an async body handoff has stalled.(package private) static booleanisGzipAllowed(Properties opts) Whether the tunnel allows gzip responses, from the tunnel options.(package private) booleanisInproxyRejection(Map<String, List<String>> headers, I2PSocket socket, String peerB32, Properties opts) Reject requests that contain forwarded-for headers (inproxy detection).booleanWhether a client may reuse one connection for several requests.(package private) static booleanisKeepAliveRequest(String cmd) Whether the request can keep the connection alive: GET or HEAD with HTTP/1.1.(package private) booleanisPostThrottled(StringBuilder command, Hash peerHash, I2PSocket socket, String peerB32) Check POST/PUT throttling for this peer.(package private) booleanisRefererRejection(Map<String, List<String>> headers, I2PSocket socket, String peerB32, Properties opts) Reject requests with absolute Referer URIs.(package private) booleanisUserAgentRejection(Map<String, List<String>> headers, I2PSocket socket, String peerB32, Properties opts) Reject requests with blacklisted User-Agent strings.static intHeap-derived ceiling on the I/O transfer budget.voidoptionsUpdated(I2PTunnel tunnel) Called when tunnel options are updated.(package private) static longparseHeaderTimeout(Properties opts) Parse and clamp the first-request header timeout (ms) from tunnel options.(package private) static booleanparseKeepAlive(Properties opts) Parse the keepalive enable flag from tunnel options.(package private) static longParse and clamp the idle keepalive timeout (ms) from tunnel options.readHeaders(I2PSocket socket, InputStream in, StringBuilder command, String[] skipHeaders, I2PAppContext ctx, long initialTimeout) Read headers from the input stream, using an array of skip headers.readHeaders(I2PSocket socket, InputStream in, StringBuilder command, Set<String> skipHeaders, I2PAppContext ctx, long initialTimeout) From I2P to server: socket non-null, in null.readRequestHeaders(I2PSocket socket, StringBuilder command, int requestCount, String peerB32, I2PAppContext ctx, Log log, String tunnelId) Read the request headers with the default timeouts.readRequestHeaders(I2PSocket socket, StringBuilder command, int requestCount, String peerB32, I2PAppContext ctx, Log log, String tunnelId, long headerTimeout, long keepAliveTimeout) Read the request headers, handling the specific errors that can occur by sending the appropriate error response to the client.(package private) static voidTrigger a full I/O-pool rebalance after a global budget change (Tuner).protected voidrejectConnection(I2PSocket socket) Refuse an inbound connection when the gate cap is exceeded: send a 503 (SSL port 443 resets instead) and close.protected voidrejectConnection(I2PSocket socket, boolean queueFull) Refuse an inbound connection (queue-full or connection-cap): send a 503 (SSL port 443 resets instead) and close, then log the accurate reason.(package private) static voidTest seam: clear the request-error rate limiting state.(package private) static voidRemove the other matching entries and set this entry as the only one.voidsetHeaderTimeout(long ms) Set the first-request header timeout, clamped to the configured bounds.static voidsetIOStallTimeoutMs(long val) Set the I/O stall timeout in ms (called by Tuner via reflection).static voidsetIOTransferThreads(int val) Set the I/O transfer pool size (called by Tuner via reflection).voidsetKeepAlive(boolean on) Enable/disable HTTP persistent connections without a tunnel restart.voidsetKeepAliveTimeout(long ms) Set the idle keepalive wait, clamped to the configured bounds.(package private) static booleanshouldLogRequestError(String peerB32, long now) Decide whether a request-error warning should be emitted for a client.voidStart the tunnel and initialize timing and throttling.(package private) static intTest seam: number of clients currently tracked.Methods inherited from class I2PTunnelServer
acquireConnectionSlot, destroy, effectiveWriteTimeout, getReadTimeout, getSocket, getSocket, getSocketManager, getSocketString, parseServerThreadOverride, releaseConnection, releaseConnectionSlot, run, setReadTimeout, shouldRejectOnQueue, shouldRejectOnQueue, tryAcquireConnectionModifier and TypeMethodDescription(package private) static booleanacquireConnectionSlot(int maxConnections, AtomicInteger active) Decide whether a concurrent-connection slot is available and, if so, reserve it.booleandestroy()Note that the tunnel cannot be reopened after this by calling startRunning(), as it will destroy the underlying socket manager.(package private) static longeffectiveWriteTimeout(Properties props) Determine the write timeout to bind the outbound I2P stream to, in ms.longGet the read idle timeout for newly-created connections (in milliseconds).protected SocketCreates a TCP socket connection to the configured destination.protected SocketgetSocket(Hash from, InetAddress remoteHost, int remotePort) Creates a TCP socket connection to the specified destination.Return the socket manager, or null if destroyed.protected StringgetSocketString(int incomingPort) Gets a human-readable string representation of the target socket.(package private) static intParse the per-tunnel server handler pool override.protected voidRelease a reservation taken byI2PTunnelServer.tryAcquireConnection().(package private) static voidreleaseConnectionSlot(AtomicInteger active) Release a slot reserved byI2PTunnelServer.acquireConnectionSlot(int, AtomicInteger).voidrun()Runs the I2PTunnelServer to accept and handle incoming connections asynchronously.voidsetReadTimeout(long ms) Set the read idle timeout for newly-created connections (in milliseconds).(package private) static booleanshouldRejectOnQueue(int queueDepth, int capacity, int active, int threads) Back-compat overload when the caller has no handle-time sample yet.(package private) static booleanshouldRejectOnQueue(int queueDepth, int capacity, int active, int threads, long avgHandleMs) Decide whether a connection should be rejected because the handler queue is already drowning.protected booleanTry to reserve a slot in the concurrent-connection gate.Methods inherited from class I2PTunnelTask
connected, disconnected, errorOccurred, getBooleanOption, getId, getTunnel, isOpen, reportAbuse, routerDisconnected, setId, setName, setTunnel, toStringModifier and TypeMethodDescriptionvoidconnected(I2PSession session) For tasks that don't callI2PTunnel.addSession(I2PSession)directly.voiddisconnected(I2PSession session) Called when a session is disconnected.voiderrorOccurred(I2PSession session, String message, Throwable error) Does nothing here.protected booleangetBooleanOption(String opt, boolean dflt) Read a boolean client option from the tunnel's properties.intgetId()The id of the client list entry for this task.The I2PTunnel this task runs inside.booleanisOpen()Whether the tunnel is running and accepting connections.voidreportAbuse(I2PSession session, int severity) Does nothing here.protected voidTell the tunnel that the router connection has dropped.voidsetId(int id) Record the client list entry id for this task.protected voidRecord the display name for this task.voidRebind this task to a different tunnel.toString()The display name given to this task when it was constructed.Methods inherited from class EventDispatcherImpl
attachEventDispatcher, detachEventDispatcher, getEventDispatcher, getEvents, getEventValue, ignoreEvents, notifyEvent, unIgnoreEvents, waitEventValueModifier and TypeMethodDescriptionvoidAttach an EventDispatcher object to the events dispatching chain.voidDetach the specified EventDispatcher object from the events dispatching chain.Object to be used to deliver events (usuallythis, but YMMV).Retrieve the names of all the events that have been received.getEventValue(String name) Retrieve the value currently associated with the specified event value.voidIgnore further event notifications.voidnotifyEvent(String eventName, Object args) Deliver an event.voidAlmost like the method above :-).waitEventValue(String name) Wait until the given event has received a value.
Constructor Details
I2PTunnelHTTPBidirServer
public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel.The server listens for incoming HTTP connections on the specified port, while the client proxy handles outbound requests through a separate port.
- Parameters:
host- the local InetAddress to bind the server to (usually null/0.0.0.0)port- the local port for incoming HTTP server connectionsproxyport- the local port for the outbound HTTP proxyprivData- Base64-encoded private key data for the I2P destinationspoofHost- the spoofed hostname for the server destinationl- the Logging instance for status messagesnotifyThis- the EventDispatcher for tunnel eventstunnel- the parent I2PTunnel instance- Throws:
IllegalArgumentException- if the I2CP configuration is invalid
I2PTunnelHTTPBidirServer
public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, File privkey, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel with a private key file.- Parameters:
host- the local InetAddress to bind the server toport- the local port for incoming HTTP server connectionsproxyport- the local port for the outbound HTTP proxyprivkey- File containing Base64-encoded private key dataprivkeyname- the name of the private key file (for logging)spoofHost- the spoofed hostname for the server destinationl- the Logging instance for status messagesnotifyThis- the EventDispatcher for tunnel eventstunnel- the parent I2PTunnel instance- Throws:
IllegalArgumentException- if the key file cannot be read
I2PTunnelHTTPBidirServer
public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, InputStream privData, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) Creates a bidirectional HTTP server tunnel with an input stream for the private key.- Parameters:
host- the local InetAddress to bind the server toport- the local port for incoming HTTP server connectionsproxyport- the local port for the outbound HTTP proxyprivData- InputStream containing Base64-encoded private key dataprivkeyname- the name of the private key (for logging)spoofHost- the spoofed hostname for the server destinationl- the Logging instance for status messagesnotifyThis- the EventDispatcher for tunnel eventstunnel- the parent I2PTunnel instance- Throws:
IllegalArgumentException- if the key data is invalid
Method Details
finishSetupI2PTunnelHTTPBidirServer
Completes the bidirectional server setup by initializing the client proxy.This method is called after the parent server tunnel is initialized. It creates the outbound HTTP proxy component and starts both tunnels.
- Parameters:
l- the Logging instanceproxyport- the port for the outbound HTTP proxy