Skip to content

Validate h2c break the RFC as don't permit http/1.1 #1201

Description

@joanhey

Allowing HTTP/1.1 on the same port as h2c (HTTP/2 Cleartext) is necessary to support clients that do not use "prior knowledge" and instead rely on the HTTP/1.1 Upgrade: h2c mechanism.

  • Protocol Negotiation: Clients without prior knowledge initiate an HTTP/1.1 request with Upgrade: h2c and HTTP2-Settings. The server must accept this HTTP/1.1 request and respond with a 101 Switching Protocols status to switch to HTTP/2.

  • Fallback Support: If a client sends a standard HTTP/1.1 request without the upgrade header, the server must still serve the request over HTTP/1.1 rather than returning binary HTTP/2 data, which would cause a connection error for HTTP/1.1 clients.

  • Configuration: Most modern servers (like Apache with Protocols h2 h2c http/1.1 and Nginx with updated versions supporting simultaneous handling) require explicit configuration to permit both protocols on a single cleartext socket.

Without HTTP/1.1 support, only clients that explicitly know the server supports HTTP/2 beforehand (via "prior knowledge") can connect successfully.

Nginx fail

In #1200 that add h2c to nginx, fail the validation because return an http/1.1.

FAIL [h2c-only]: port 8082 also answered HTTP/1.1 with 200 — dual-serving lets the benchmark measure h1 throughput instead of h2c. The h2c listener must refuse HTTP/1.1 requests.

In reallity nginx 11 years ago was working so, but later need to change it to support the RFC.
Defining http2 without ssl leads to HTTP/1.1 client failure
Allow h2c and HTTP/1.1 support on the same listening socket

A fix was merged in 2023 and released in Nginx 1.25.1 (and subsequently in all stable branches, including 1.27+ and 1.31). This update allows HTTP/1.1 and HTTP/2 (h2c) to coexist on the same listening socket.

Nginx now inspects the request line. If it detects the HTTP/2 connection preface, it selects HTTP/2; otherwise, it defaults to HTTP/1.1.

RFC info:

The clients need to use http2 prior knowledge to receive an h2c directly, or the server need to respond to any http1.1 request.

Example with curl:

The --http2-prior-knowledge flag is a curl command-line option that forces the use of HTTP/2 without first attempting to negotiate an upgrade via HTTP/1.1. This feature allows users to shortcut the HTTP/2 negotiation process, which is particularly useful in controlled environments where the server's HTTP/2 capability is already known.

Key characteristics of this flag include:

  • Bypasses Upgrade: It skips the standard HTTP/1.1 Upgrade mechanism, sending the HTTP/2 connection preface immediately.

  • Supports Cleartext (H2C): It is often required to use HTTP/2 over plain text (non-TLS) connections, known as h2c with prior knowledge, as standard HTTP/2 typically requires TLS.

  • Avoids Method Restrictions: In some server implementations (like Spring Boot or Jetty), using the standard --http2 flag with POST/PUT requests may fail due to upgrade limitations, whereas --http2-prior-knowledge succeeds because it does not perform an upgrade.

  • Client Support: Beyond curl, other clients like Go and .NET require specific configuration (e.g., http2.Transport with AllowHTTP: true or Http2UnencryptedSupport switch) to mimic this behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    platformEverything related to benchmark exection, including the PR workflow.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions