Class Http2Headers

java.lang.Object
io.github.mahmoudimus.http2.Http2Headers

public final class Http2Headers extends Object
HTTP semantics of HTTP/2 field sections (RFC 9113 §8.2, §8.3): validating decoded header lists into RequestHeaders and ResponseHeaders, and building header lists from HTTP/1-style messages.

A request or response that breaks these rules is malformed, which is a stream error of type PROTOCOL_ERROR (§8.1.1); the validators throw exactly that. They check:

  • names: not empty, no upper-case letters, no octets 0x00-0x20 or 0x7f-0xff, and no colon except as the first character of a pseudo-header;
  • values: no NUL, CR or LF, and no leading or trailing space or tab;
  • no connection-specific fields (CONNECTION_SPECIFIC), and te only with the value trailers;
  • pseudo-headers: only the defined ones for the message kind, each at most once, all before the regular fields, and the required ones present; none in trailers;
  • content-length: digits only, and every value the same.
  • Field Details

    • CONNECTION_SPECIFIC

      public static final Set<String> CONNECTION_SPECIFIC
      Fields that are specific to an HTTP/1 connection and must not appear in HTTP/2 (§8.2.2).
  • Method Details

    • toRequest

      public static RequestHeaders toRequest(int streamId, List<HeaderField> fields) throws Http2Exception
      Validates a decoded request header section.
      Parameters:
      streamId - the stream identifier used for protocol errors
      fields - the decoded fields in wire order
      Returns:
      the validated request control data and regular fields
      Throws:
      Http2Exception - if the field section is malformed
    • toResponse

      public static ResponseHeaders toResponse(int streamId, List<HeaderField> fields) throws Http2Exception
      Validates a decoded response header section (final or 1xx).
      Parameters:
      streamId - the stream identifier used for protocol errors
      fields - the decoded fields in wire order
      Returns:
      the validated response status and regular fields
      Throws:
      Http2Exception - if the field section is malformed
    • validateTrailers

      public static List<HeaderField> validateTrailers(int streamId, List<HeaderField> fields) throws Http2Exception
      Validates a trailer section: regular fields only.
      Parameters:
      streamId - the stream identifier used for protocol errors
      fields - the decoded fields in wire order
      Returns:
      an immutable copy of the validated trailers
      Throws:
      Http2Exception - if the field section is malformed
    • checkContentLength

      public static void checkContentLength(int streamId, long declared, long received, boolean endStream) throws Http2Exception
      Checks DATA received against a declared content-length (§8.1.1). Call it after each DATA frame with the running total of data octets (padding excluded). Skip it where the content is empty whatever the field says: responses to HEAD, and 204 and 304 responses.
      Parameters:
      streamId - the stream identifier used for protocol errors
      declared - the content length, or -1 if none was declared (then nothing is checked)
      received - the running content octet count, excluding padding
      endStream - whether the stream has ended
      Throws:
      Http2Exception - if the received content exceeds the declaration or ends with a different length
    • fromHttp1Request

      public static List<HeaderField> fromHttp1Request(String method, String scheme, String authority, String path, Collection<? extends Map.Entry<String,String>> headers)
      An HTTP/2 request header list for an HTTP/1-style request: pseudo-headers first, then the fields with lower-cased names, minus connection-specific fields (and any named in connection), host (carried by :authority) and a te other than trailers; cookie is split into crumbs (§8.2.3), which compress better.
      Parameters:
      method - the HTTP request method
      scheme - the URI scheme, ignored for CONNECT
      authority - the target authority, or null to take it from the host field
      path - the request target path, ignored for CONNECT
      headers - the HTTP/1-style fields in order
      Returns:
      the HTTP/2 fields, beginning with the request pseudo-headers
      Throws:
      IllegalArgumentException - if a name or value cannot be sent in HTTP/2
    • fromHttp1Response

      public static List<HeaderField> fromHttp1Response(int status, Collection<? extends Map.Entry<String,String>> headers)
      Parameters:
      status - the response status from 100 to 999
      headers - the HTTP/1-style fields in order
      Returns:
      the HTTP/2 fields, beginning with :status