shams
shams

Reputation: 3518

Using HAproxy to proxy h2c requests

Is it possible to use HAproxy to proxy incoming h2c requests?

I have tried the following configuration using this tutorial:

frontend receiver
  mode http
  bind *:80
  bind *:443 ssl crt-list /some/file alpn h2,h2c,http/1.1
  default_backend processor

This configuration works for h2 (HTTP/2 secure) requests and sends HTTP/1.1 requests to the backend. However, it doesn't work for h2c (HTTP/2 cleartext) requests made via curl. I get the following error message:

$ curl --http2-prior-knowledge http://server.com/status
...
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle ...)
> GET /status HTTP/2
...
* http2 error: Remote peer returned unexpected data while we expected SETTINGS frame.  Perhaps, peer does not support HTTP/2 properly.
...
curl: (16) Error in the HTTP2 framing layer

I suspect this is because HAProxy is expecting h2 data (instead of h2c) in the response. Any suggestion on what I need to change in the HAProxy configuration to support incoming h2c requests?

Upvotes: 0

Views: 3016

Answers (2)

shams
shams

Reputation: 3518

Based on the discussion in the HAproxy channel, it is possible to proxy h2c requests using the proto h2 setting on bind. However, it is not currently possible to listen for both HTTP/1.1 and HTTP/2 requests on the same port.

Example configuration to get h2c working on HAProxy:

frontend f_h2c
    mode http
    option http-use-htx
    bind *:8080 proto h2
    default_backend local_node

backend local_node
    mode http
    option http-use-htx
    server localhost localhost:9090 proto h2

Upvotes: 2

Barry Pollard
Barry Pollard

Reputation: 46080

It is possible to proxy incoming requests in tcp mode providing your back end server supports h2c. That is what the tutorial you used did for h2 requests but no reason it wouldn’t also work for h2c.

Since that tutorial was written, HAProxy has added HTTP/2 support in v1.8, so it can also proxy h2 requests in http mode, but as far as I’m aware it is not possible to do this for h2c. The documentation is not explicitly clear on this but does state ALPN is used to negotiate HTTP/2 and this question states h2c support was not added.

HAProxy 1.9 did add h2c support in the backend, but still no note of it being supported in the front end.

To be honest h2c support in the front end is often of limited use since browsers do not support it and since it would require either an upgrade step or an assumption the server supported it (neither of which is ideal), unlike h2 which can be negotiated as part of the TLS negotiation with no extra round trips or assumptions.

Is there a particular reason you want h2c support in the front end as there may be better ways of achieving what you want.

Upvotes: 1

Related Questions