-
-
Notifications
You must be signed in to change notification settings - Fork 36
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
rpxy accepts HTTP2 when force_http11_upstream is set, request fails #184
Comments
In my understanding, your setting seems as below.
But it is weird that your application returns 500 when clients send request with HTTP/2. The setting seems that |
Sorry, I missed to paste rpxy log because the error message in rpxy log seemed like http2 forwarding to http1 was not possible. I think the relevant part is:
More specifically
P.S. the upstream service is OpenWRT whatever its configuration interface uses as a web server. But should be pretty simple software because these devices are resources constraint. I expect something that adheres to as few modern specifications as possible. |
OpenWRT uses uhttpd by default. But I assume the result would be the same with any other web server that doesn't support HTTP2. Another thing I notice though is that this only is a problem with |
Thanks for the investigation! Actually, seems weird. I will check but needs time for a while. For now I am guessing this is due to the configuration of |
I just tested on localhost and my Flow:
Curl: $ curl https://localhost:4433 -v -i --insecure --http2 -I
$ curl https://localhost:4433 -v -i --insecure --http3 -I
The log are as below, which are actually for proxied requests to HTTP/3
HTTP/2
So, mine works flawlessly actually. very weird... I will investigate more |
I see. I tried this. The difference is that in your example, you don't use HTTPS to the downstream, only to the upstream. So this worked for me:
And the result was:
And rpxy logs:
But if I add https to the downstream as well with:
Then the result is:
And rpxy log is:
In both cases request passes through because the upstream apparently supports HTTP2. But in the second example the upstream request is HTTP2 instead of HTTP1.1 which should have been enforced. |
Haha! I found the reason! This [apps.testdomain]
server_name = 'exampledomain.ddnsgeek.com'
tls = { https_redirection = true, acme = true }
reverse_proxy = [{ upstream = [{ location = 'whoami-1.rpxy.net', tls = true }] }]
upstream_options = [
"force_http11_upstream",
] must be changed to [apps.testdomain]
server_name = 'exampledomain.ddnsgeek.com'
tls = { https_redirection = true, acme = true }
reverse_proxy = [
{
upstream = [
{ location = 'whoami-1.rpxy.net', tls = true }
],
upstream_options = [
"force_http11_upstream",
]
}
] This is because options for upstream requests should be configured for each backend app! In your original configuration, options for upstream request were configured for the domain! |
So I also really confirmed that we need more friendly configuration documentation. Current config-example.toml and README.md are really unfriendly. |
It doesn't look like a valid configuration. When I copy/paste the above configuration snippet in my toml I see
|
Well it should be a typo. Anyways [apps."whoami-1.rpxy.net"]
server_name = 'whoami-1.rpxy.net'
reverse_proxy = [
{ upstream = [
{ location = 'whoami-1:8000', tls = false },
], upstream_options = ['keep_original_host'] }
]
tls = { https_redirection = true, acme = true } The above is actually the configuration for |
Or, please prepare the separated [apps.testdomain]
server_name = 'exampledomain.ddnsgeek.com'
tls = { https_redirection = true, acme = true }
[[apps.testdomain.reverse_proxy]]
upstream = [{ location = 'whoami-1.rpxy.net', tls = true }]
upstream_options = [
"force_http11_upstream",
] |
This separate configuration works! Really thanks a lot! But I think it is not a typo. There seems to be some magic related to parsing of stuff. This fails:
This works:
The difference is that I've put But thanks again that it is now working as expected! |
So this can be closed. Unless you want to keep it open to implement auto-detection of HTTP2 support. Or for whatever reason. |
Good to hear that! Honestly, the auto-detection of HTTP/2 (or 3) is quite tough. The client library using to issue request to backends supports auto negotiation. It works as follows: initial requests are usually sent over HTTP/1.1 and then subsequent requests would be updated to HTTP/2 or 3 according to responses's ALT-SVC field. In `rpxy, that is totally overridden and the same HTTP version as original requests would be used by default (unless the backend connection is over plantext HTTP) to remove such the overhead of upgrading. This is from my concept that the backend connection should be controlled by the deployer (but not sticked to this). If we try to auto-detect, we need to periodically issue a kind of |
It makes sense for performance reasons to make user specify the connection type. But it has to be well documented what would be the default behavior. I didn't see this when reading the readme or the example config. HTTP2 upgrading when using HTTPS on the upstream should be straightforward because that negotiation happens within the TLS handshake. I think that auto-detection is no issue. More of an issue is the HTTP3 upgrade. Actually the ideal approach would be for rpxy to negotiate HTTP version automatically but then keep the highest negotiated version in memory so that subsequent connections will directly use that version instead of the auto-negotiation algorithm. For the time being though, just documenting this would be super helpful for new users. |
Don't know if this is related to #77 or not. But I have an upstream that only supports HTTP 1.1
Like this:
But when running curl:
So basically TLS handshake appears to incorrectly accept
h2
when it should accepthttp/1.1
because of the upstream server.P.S. Request works with
curl --http1.1
but there is no such option for normal browsers.The text was updated successfully, but these errors were encountered: