Class Http2

java.lang.Object
com.codename1.backend.Http2

public final class Http2 extends Object

One HTTP/2 connection, on nghttp2.

The framing is not implemented here and should not be: HPACK alone is a static table, a dynamic table with eviction and Huffman coding, and flow control, stream state, CONTINUATION reassembly and GOAWAY are all their own problems. nghttp2 owns those. This class owns the shape of the boundary.

Java PULLS from the session rather than being called back into. nghttp2 is callback-driven, but a C callback that reaches into the VM has to survive dead-code elimination and must not run while the collector is moving; the callbacks instead accumulate completed requests and this class takes them.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    One request, once the client has finished sending it.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The ALPN identifier.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
     
    int[]
    The streams that have closed since the last call, as (stream id, HTTP/2 error code) pairs; null when none have.
    static Http2
    A new server session, with the SETTINGS preface already queued.
    byte[]
    Runs the session's output side and returns the bytes to put on the wire.
    boolean
    False once the session is finished and the connection can be closed.
    The next completed request, or null.
    long
    Heap held by response bodies that have been submitted and not yet fully written, which is NOT what drain() empties: that buffer is what nghttp2 has already serialised.
    static long
    Response-body heap outstanding across the PROCESS rather than this session.
    static int
    File-backed response bodies outstanding across the PROCESS, not this session.
    void
    receive(byte[] buffer, int offset, int length)
    Feeds received bytes to the session.
    boolean
    respond(int streamId, int status, String contentType, List extraHeaders, byte[] body)
    • extraHeaders: "name: value" strings.
    boolean
    respondFile(int streamId, int status, String contentType, List extraHeaders, int fd, long offset, long length)
    Responds with a range of an open file, without reading it into the heap.
    static void
    setMaxBodyBytes(long limit)
    The ceiling for outstanding response bodies across the process.
    static void
    setMaxFileBodies(int limit)
    The ceiling for outstanding FILE-backed bodies across the process.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • ALPN

      public static final String ALPN
      The ALPN identifier. There is no upgrade handshake for h2 over TLS.
      See Also:
  • Method Details

    • create

      public static Http2 create() throws IOException
      A new server session, with the SETTINGS preface already queued.
      Throws:
      IOException
    • receive

      public void receive(byte[] buffer, int offset, int length) throws IOException
      Feeds received bytes to the session.
      Throws:
      IOException
    • nextRequest

      public Http2.Stream nextRequest()
      The next completed request, or null. A stream is complete only when END_STREAM arrives -- on the HEADERS frame for a request with no body, on the last DATA frame otherwise.
    • respond

      public boolean respond(int streamId, int status, String contentType, List extraHeaders, byte[] body) throws IOException
      • extraHeaders: "name: value" strings. Connection-specific headers are dropped, because HTTP/2 forbids them, and names are lower-cased, because a capital letter is a protocol error the peer resets the stream over.
      Throws:
      IOException
    • setMaxBodyBytes

      public static void setMaxBodyBytes(long limit)

      The ceiling for outstanding response bodies across the process.

      Set once, and enforced natively where the memory is actually taken.

    • setMaxFileBodies

      public static void setMaxFileBodies(int limit)

      The ceiling for outstanding FILE-backed bodies across the process.

      Enforced natively for the same reason as the byte ceiling: the slot has to be taken in the same step as the descriptor, or every worker finishing at once passes the check before any of them counts.

    • respondFile

      public boolean respondFile(int streamId, int status, String contentType, List extraHeaders, int fd, long offset, long length) throws IOException

      Responds with a range of an open file, without reading it into the heap.

      HTTP/2 cannot use sendfile -- the bytes have to become DATA frames -- but that is not a reason to materialise the whole file first. Reading it in cost the file's size in Java plus the same again in the native copy, so a large enough public file turned one request into an OutOfMemoryError, which the handler's catch (Exception) does not catch. The provider reads each frame straight out of the descriptor instead, so the memory is one frame regardless of size, and nghttp2's flow control decides the pace.

      The descriptor is owned by the session from here: it is closed when the stream reaches EOF, when it is reset early, and when the session is torn down.

      Throws:
      IOException
    • drain

      public byte[] drain() throws IOException
      Runs the session's output side and returns the bytes to put on the wire. Empty when there is nothing pending.
      Throws:
      IOException
    • closedStreams

      public int[] closedStreams()
      The streams that have closed since the last call, as (stream id, HTTP/2 error code) pairs; null when none have. Code 0 is a stream whose response was sent in full; anything else is one reset before it was. A reset the PEER sent with NO_ERROR is reported as -1, not 0: it closes with code 0 too, and is no proof the response arrived. The server ends a request's span here, since a body the peer's flow-control window holds back is sent turns after it was submitted.
    • isAlive

      public boolean isAlive()
      False once the session is finished and the connection can be closed.
    • pendingBodyBytes

      public long pendingBodyBytes()
      Heap held by response bodies that have been submitted and not yet fully written, which is NOT what drain() empties: that buffer is what nghttp2 has already serialised. nghttp2 pulls from a submitted body only as the peer's flow-control window allows, so a client that stops sending WINDOW_UPDATE leaves every body it asked for sitting here. A caller that keeps submitting has to look at this figure rather than at what it just handed over, because a flush that could write nothing frees nothing.
    • pendingBodyFiles

      public static int pendingBodyFiles()
      File-backed response bodies outstanding across the PROCESS, not this session. Such a body holds a descriptor and no heap, so it is invisible to pendingBodyBytes, and descriptors are a process resource: bounding them per connection still multiplies by the connection count, and exhausting them stops the process opening sockets or files at all.
    • pendingBodyBytesAll

      public static long pendingBodyBytesAll()
      Response-body heap outstanding across the PROCESS rather than this session. The per-session figure says what one connection holds; a limit on that is a limit per connection, and the connection ceiling is in the thousands, so it bounds nothing about the machine.
    • close

      public void close()