Class NettyRequest


  • public final class NettyRequest
    extends Object
    • Method Detail

      • getHttpRequest

        public io.netty.handler.codec.http.HttpRequest getHttpRequest()
      • release

        public void release()
        Releases the underlying HTTP/1.1 HttpRequest (and the request-body ByteBuf it holds) — but only while AsyncHttpClient still owns it (it was never handed to a channel write). Once markHandedToChannel() has claimed it, Netty's encoder owns the release and this becomes a no-op, so the two can never double-free. The atomic CAS also closes the check-then-release TOCTOU an external isHandedToChannel() test would leave between an abort thread and the event-loop write.

        In the HTTP/2 path the httpRequest object is never written to a channel — its content is re-encoded as HTTP/2 frames — so AHC always owns its release and this performs it. The early-abort paths (a draining/closed/queued-then-dropped connection, or a crashing onRequestSend) call it too. Idempotent and thread-safe — extra calls are no-ops.

      • markHandedToChannel

        public boolean markHandedToChannel()
        Atomically claims getHttpRequest() for a channel write (the HTTP/1.1 path), after which Netty's encoder owns its release. Returns true if the caller may proceed with the write; returns false when a concurrent abort/cancel/timeout has ALREADY released the request body — in which case the caller MUST NOT write the now-freed buffer. This single CAS resolves the double-free/use-after-free race a separate handedToChannel flag plus a non-atomic release() would otherwise allow (e.g. a setBody(ByteBuf) request cancelled on one thread while the event loop writes it).
      • isHandedToChannel

        public boolean isHandedToChannel()