Skip to content
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

Redirect fails with HTTP2 #1603

Closed
keroami opened this issue Feb 12, 2023 · 3 comments
Closed

Redirect fails with HTTP2 #1603

keroami opened this issue Feb 12, 2023 · 3 comments
Milestone

Comments

@keroami
Copy link

keroami commented Feb 12, 2023

My handler does a redirect (I can log it), but it never reaches the client.

Restricting server (which uses a ceriticate) to http/1.1 by specifiying alpn_preferred_protocols makes it all work fine.
Insecure connections seem to default to HTTP1.1 as well.
Any request that is not redirected, is fulfilled normally.

cowboy 2.9.0, as well as recent git master branch (esp including commit 105edf1).
For all I know, the problem could be in cowlib or ranch.

curl --http2 -Lv http://localhost:8080/gleam-blog
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /gleam-blog HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.87.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 101 Switching Protocols
< connection: Upgrade
< upgrade: h2c
* Received 101, Switching to HTTP/2
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=9
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
* HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Connection #0 to host localhost left intact
curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)

Calling over https to my live server shows the negotiation, the certificate, and then some, but the tail is exactly the same

PS: setting max concurrent streams explicitely, makes the value sane, but does not solve the main problem.

@essen
Copy link
Member

essen commented Feb 12, 2023

Can you provide the code for the handler?

@keroami
Copy link
Author

keroami commented Feb 12, 2023

I made a small example.
git clone git://chmeee.org/cowboy_bug_report
I ran it with rebar3 shell and then
curl --http2 -Lv localhost:8888/hello never receives the 301 redirect and has an output as above.
curl --http2 -Lv localhost:8888/world has a normal 200 response

extra info:

Erlang/OTP 25 [erts-13.1.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Eshell V13.1.4  (abort with ^G)

edit: my official server has the same erlang version, but [smp:1:1] [ds:1:1:10]

@essen essen added this to the 2.11 milestone Nov 23, 2023
@essen
Copy link
Member

essen commented Jan 5, 2024

Finally got to try this, thank you for the repository!

There's two issues with your handler. The first one is you are not returning {ok, Req, State} so that causes a crash. But that's not why curl is not happy.

Starting with HTTP/2 header names have to be all lowercase. In your code you gave Location instead of location. Cowboy will not convert the uppercase to lowercase automatically, as by convention Cowboy expects all header names you provide to be already in lowercase.

When updating your example repo to fix those two issues, everything works as intended:

$ curl --http2 -Lv localhost:8888/hello
*   Trying [::1]:8888...
* connect to ::1 port 8888 failed: Connection refused
*   Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888
> GET /hello HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/8.4.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA
> 
< HTTP/1.1 101 Switching Protocols
< connection: Upgrade
< upgrade: h2c
* Received 101, Switching to HTTP/2
< HTTP/2 301 
< content-length: 14
< date: Fri, 05 Jan 2024 12:41:05 GMT
< location: http://localhost:8888/world
< server: Cowboy
< 
* Ignoring the response-body
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8888/world'
* Found bundle for host: 0x55c45f004aa0 [can multiplex]
* Re-using existing connection with host localhost
* [HTTP/2] [3] OPENED stream for http://localhost:8888/world
* [HTTP/2] [3] [:method: GET]
* [HTTP/2] [3] [:scheme: http]
* [HTTP/2] [3] [:authority: localhost:8888]
* [HTTP/2] [3] [:path: /world]
* [HTTP/2] [3] [user-agent: curl/8.4.0]
* [HTTP/2] [3] [accept: */*]
> GET /world HTTP/2
> Host: localhost:8888
> User-Agent: curl/8.4.0
> Accept: */*
> 
< HTTP/2 200 
< content-length: 13
< date: Fri, 05 Jan 2024 12:41:05 GMT
< server: Cowboy
< 
* Connection #0 to host localhost left intact
Hello, world!

Closing, thanks!

@essen essen closed this as completed Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants