java.lang.Object
net.i2p.i2ptunnel.I2PTunnelHTTPServer.CompressedRequestor
- All Implemented Interfaces:
Runnable
- Enclosing class:
I2PTunnelHTTPServer
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PSocketThe browser's I2P socket.private final I2PAppContextThe app context.private final StringThe request headers to forward.private final java.util.function.Supplier<ThreadPoolExecutor> Supplier of the shared IO pool.private booleanWhether the browser connection stays open.private final LogLogger, shadows the one in the superclass.private final booleanTrue when the request is gzipped.private final ThreadPoolExecutorThe executor running this task.private final StringFar-side label for transfer logs, e.g.private final booleanTrue for an upgrade request.private final AtomicIntegerWaiter count for the IO pool.private final SocketThe web server socket.private static final intCopy buffer size.Constructor Summary
ConstructorsConstructorDescriptionCompressedRequestor(Socket webserver, I2PSocket browser, String headers, I2PAppContext ctx, Log log, boolean shouldCompress, boolean upgrade, ThreadPoolExecutor tpe, boolean keepalive, AtomicInteger waiter, java.util.function.Supplier<ThreadPoolExecutor> ioPool) Serves a gzipped response from the web server to the browser.CompressedRequestor(Socket webserver, I2PSocket browser, String headers, I2PAppContext ctx, Log log, boolean shouldCompress, boolean upgrade, ThreadPoolExecutor tpe, boolean keepalive, AtomicInteger waiter, java.util.function.Supplier<ThreadPoolExecutor> ioPool, String tunnelId) Serves a gzipped response, with an optional stall watchdog.Method Summary
Modifier and TypeMethodDescriptionprivate voidfinishTransfer(AtomicBoolean finished, I2PTunnelHTTPServer.Sender body, I2PTunnelHTTPServer.Sender reqSender, OutputStream serverout, OutputStream browserout, I2PTunnelHTTPServer.CompressedResponseOutputStream compressedout, InputStream browserin, InputStream serverin, String req) Tear down a completed (or failed) request exactly once.private voidpropagateFailure(IOException ioex, String req) On failure, propagate a reset to the other end of the connection, simplified from I2PTunnelRunner.(package private) static StringreadAndRewriteServerResponse(InputStream serverin, int timeout, I2PAppContext ctx) Read the server response headers, filter them for security, and re-format them for the client.voidrun()This thread handles the response from the server back to the browser.private voidrunOnIO(I2PTunnelHTTPServer.Sender s, String desc) Run a Sender on the dedicated I/O pool with idle-based stall detection.private voidscheduleBodyWatchdog(I2PTunnelHTTPServer.Sender body, AtomicBoolean finished, Runnable finish, InputStream browserin, OutputStream browserout, InputStream serverin, OutputStream serverout) Attach aI2PTunnelHTTPServer.BodyWatchdogto a detached async body.private static StringReturns the URL suffix of a request line.
Field Details
_tunnelId
Far-side label for transfer logs, e.g.[skank / aanoquc2]. Null when the caller did not supply one._webserver
The web server socket._browser
The browser's I2P socket._headers
The request headers to forward._ctx
The app context._log
Logger, shadows the one in the superclass._shouldCompress
private final boolean _shouldCompressTrue when the request is gzipped._upgrade
private final boolean _upgradeTrue for an upgrade request._tpe
The executor running this task._keepalive
private volatile boolean _keepaliveWhether the browser connection stays open._waiter
Waiter count for the IO pool._ioPool
Supplier of the shared IO pool.BUF_SIZE
Constructor Details
CompressedRequestor
public CompressedRequestor(Socket webserver, I2PSocket browser, String headers, I2PAppContext ctx, Log log, boolean shouldCompress, boolean upgrade, ThreadPoolExecutor tpe, boolean keepalive, AtomicInteger waiter, java.util.function.Supplier<ThreadPoolExecutor> ioPool) Serves a gzipped response from the web server to the browser.- Parameters:
webserver- the web server socket to read the response frombrowser- the browser socket to send the response toheaders- the request headers to forward to the web serverctx- the application context, used to schedule the stall watchdoglog- the logger for the transfer logsshouldCompress- if false, don't compress, just filter server headersupgrade- true if the request is a protocol upgrade, which disables keepalivetpe- the thread pool that runs the inline server-to-browser senderkeepalive- true if the browser connection may be reused afterwardswaiter- to notify when done, if non-null; will set value to 1: not keepalive-able response, or 2: keepaliveioPool- resolves the owning tunnel's I/O transfer pool (never returns null in production)
CompressedRequestor
public CompressedRequestor(Socket webserver, I2PSocket browser, String headers, I2PAppContext ctx, Log log, boolean shouldCompress, boolean upgrade, ThreadPoolExecutor tpe, boolean keepalive, AtomicInteger waiter, java.util.function.Supplier<ThreadPoolExecutor> ioPool, String tunnelId) Serves a gzipped response, with an optional stall watchdog.- Parameters:
webserver- the web server socket to read the response frombrowser- the browser socket to send the response toheaders- the request headers to forward to the web serverctx- the application context, used to schedule the stall watchdoglog- the logger for the transfer logsshouldCompress- if false, don't compress, just filter server headersupgrade- true if the request is a protocol upgrade, which disables keepalivetpe- the thread pool that runs the inline server-to-browser senderkeepalive- true if the browser connection may be reused afterwardswaiter- to notify when done, if non-null; will set value to 1: not keepalive-able response, or 2: keepaliveioPool- resolves the owning tunnel's I/O transfer pool (never returns null in production)tunnelId- far-side label for transfer logs, e.g.[skank / aanoquc2]; may be null
Method Details
urlSuffix
runOnIO
Run a Sender on the dedicated I/O pool with idle-based stall detection. The handler thread pollsFuture.get()in short slices and cancels only afterI2PTunnelHTTPServer.ioStallTimeoutMswith no read progress. A total-timeout Future.get would kill any transfer longer than the stall window (a multi-minute I2P download at hundreds of KB/s), which is expected latency — not a stall. On true idle the Sender thread is interrupted (breaking any blockingread()), and an IOException propagates to the finally-block cleanup.Used for keepalive responses (must wait before the next request) and as a fallback when async handoff is not taken.
- Parameters:
s- the Sender to rundesc- descriptive name for error messages- Throws:
IOException- if the transfer goes idle for the stall timeout, fails, or the pool rejects the task
run
scheduleBodyWatchdog
private void scheduleBodyWatchdog(I2PTunnelHTTPServer.Sender body, AtomicBoolean finished, Runnable finish, InputStream browserin, OutputStream browserout, InputStream serverin, OutputStream serverout) Attach aI2PTunnelHTTPServer.BodyWatchdogto a detached async body. The poll interval is fixed atI2PTunnelHTTPServer.BodyWatchdog.POLL_MS(the SimpleTimer2 5s minimum); the stall window itself isI2PTunnelHTTPServer.ioStallTimeoutMs. The watchdog cancels itself on the next tick after finishTransfer sets the finished flag, so it never outlives the connection.- Parameters:
body- detached Server-to-Client Senderfinished- request-wide finish-once flagfinish- idempotent finish shared with the handoffbrowserin- browser-side request stream; may be nullbrowserout- browser-side response stream; may be nullserverin- I2P-side response body stream; may be nullserverout- I2P-side request stream; may be null
finishTransfer
private void finishTransfer(AtomicBoolean finished, I2PTunnelHTTPServer.Sender body, I2PTunnelHTTPServer.Sender reqSender, OutputStream serverout, OutputStream browserout, I2PTunnelHTTPServer.CompressedResponseOutputStream compressedout, InputStream browserin, InputStream serverin, String req) Tear down a completed (or failed) request exactly once. Invoked from the handler finally when the body ran on this thread, or from the I/O pool worker after an async body handoff.- Parameters:
finished- CAS flag; first caller performs cleanupbody- Server→Client Sender (may be null)reqSender- Client→Server Sender (may be null)serverout- local webserver output (may be null)browserout- browser-side output (may be null)compressedout- gzip wrapper (may be null)browserin- local webserver input (may be null)serverin- I2P-side response body (may be null)req- request URL for logging (may be null)
readAndRewriteServerResponse
static String readAndRewriteServerResponse(InputStream serverin, int timeout, I2PAppContext ctx) throws IOException Read the server response headers, filter them for security, and re-format them for the client.- Parameters:
serverin- stream from the webservertimeout- timeout for the header readctx- the I2P app context- Returns:
- the formatted, filtered headers
- Throws:
IOException- if the webserver stream fails
propagateFailure
On failure, propagate a reset to the other end of the connection, simplified from I2PTunnelRunner.- Parameters:
ioex- the failure that triggered the resetreq- the request URL for logging