Skip to content

Vert.x does not permit to proxy HTTP/2 requests without :authority pseudo header correctly #5553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
NilsRenaud opened this issue Apr 16, 2025 · 1 comment
Labels
Milestone

Comments

@NilsRenaud
Copy link
Contributor

Version

I used vert.x core 4.5.14

Context

The HTTP/2 RFC clearly says that an HTTP/2 request may have no :authority pseudo header:

Clients that generate HTTP/2 requests directly MUST use the ":authority" pseudo-header field to convey authority information, unless there is no authority information to convey (in which case it MUST NOT generate ":authority").

Then it also say this:

An intermediary that forwards a request over HTTP/2 MUST construct an ":authority" pseudo-header field using the authority information from the control data of the original request, unless the original request's target URI does not contain authority information (in which case it MUST NOT generate ":authority"). Note that the Host header field is not the sole source of this information; see Section 7.2 of [HTTP].

But:

  • On server side, Vert.x automatically uses the Host header as "authority" if no authority is present. Hiding the information that no authority was present in the request
  • On client side, Vert.x does not permit to generate HTTP/2 requests without authority.

These 2 points make the reverse-proxying of HTTP/2 requests without authority impossible.

Do you have a reproducer?

Not a real reproducer, but something to investigate HTTP/2 request management using Vert.x:

import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.junit.jupiter.api.Test;

import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpVersion;
import io.vertx.core.http.RequestOptions;

public class AuthorityTest {
    @Test
    void test() throws InterruptedException {
        CountDownLatch serverLatch = new CountDownLatch(1);
        Vertx vertx = Vertx.vertx();
        HttpServerOptions serverOptions = new HttpServerOptions().setAlpnVersions(List.of(HttpVersion.HTTP_2))
                .setUseAlpn(true)
                .setHttp2ClearTextEnabled(true);
        HttpServer server = vertx.createHttpServer(serverOptions)
                                 .requestHandler(req -> {
                                     System.out.println("received authority: " + req.authority());
                                     req.response().setStatusCode(200).end();
                                 });
        server.listen(8082)
              .onSuccess(unused -> serverLatch.countDown());
        serverLatch.await(); // server started
        CountDownLatch clientLatch = new CountDownLatch(1);
        HttpClientOptions clientOptions = new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_2);
        RequestOptions options = new RequestOptions()
                .setMethod(HttpMethod.GET)
                .setPort(8082)
                .setHost("localhost")
                .setURI("/");
        vertx.createHttpClient(clientOptions)
             .request(options)
             .compose(HttpClientRequest::send)
             .onSuccess(resp -> {
                 System.out.println("received response: " + resp.statusCode());
                 clientLatch.countDown();
             })
             .onFailure(Throwable::printStackTrace);
        clientLatch.await();
        server.close();
    }

Extra

This is link to a discussion on an HA proxy issue regarding HTTP/1.1 -> HTTP/2 request translation: haproxy/haproxy#2592

Which discussion led to a question raised for the W3C HTTP working group: https://lists.w3.org/Archives/Public/ietf-http-wg/2024JulSep/0258.html

@NilsRenaud NilsRenaud added the bug label Apr 16, 2025
@vietj vietj added this to the 4.5.15 milestone Apr 17, 2025
@vietj
Copy link
Member

vietj commented Apr 17, 2025

maybe there should be an option where vertx allows pseudo headers to be used in a multimap headers for HTTP/2 that would be used in such case

That would allow inspecting this map on a response and have a precise knowledge of the actual headers sent by the remote endpoint.

@vietj vietj modified the milestones: 4.5.15, 4.5.16 May 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants