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

Server-Sent-Events not working through HTTP/1.1 #690

Open
ninsuo opened this issue Mar 28, 2024 · 9 comments · May be fixed by #692
Open

Server-Sent-Events not working through HTTP/1.1 #690

ninsuo opened this issue Mar 28, 2024 · 9 comments · May be fixed by #692
Labels
bug Something isn't working

Comments

@ninsuo
Copy link

ninsuo commented Mar 28, 2024

What happened?

Following days of investigations on load-balancing problems, we've found out that SSEs seem not working over HTTP/1 with frankenphp.

Using caddy along with php-fpm works well (wait 30s to get a ping):

# OK
curl -kNvs --http1.1 'https://api.draft.wetransform.com/events?channels[]=test'
# OK
curl -kNvs --http2 'https://api.draft.wetransform.com/events?channels[]=test'

But using frankenphp, it doesn't seem to work:

# NOK
curl -kNvs --http1.1 'https://api.wetransform.com/events?channels[]=test'
# OK
curl -kNvs --http2 'https://api.wetransform.com/events?channels[]=test'

Reproduction

I've developed a simple controller that streams a response through SSEs.

You can reproduce and run the following project (you may need to install php and composer):

git clone git@github.com:ninsuo/frankenphp-sse-http1.git test
cd test
composer install
docker run -v $PWD:/app/public -p 80:80 -p 443:443 -p 443:443/udp dunglas/frankenphp

The following command works as expected:

curl -kNvs --http2 'https://localhost/public/index.php/demo'

The following command does not work (response seems buffered):

curl -kNvs --http1.1 'https://localhost/public/index.php/demo'

Credits

Credits for finding the bug go to @Tharyrok

Relevant log output

http 1

$ curl -kNvs --http1.1 'https://localhost/public/index.php/demo'
*   Trying 127.0.0.1:443...
* Connected to localhost (127.0.0.1) port 443 (#0)
* ALPN: offers http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: [NONE]
*  start date: Mar 28 09:05:40 2024 GMT
*  expire date: Mar 28 21:05:40 2024 GMT
*  issuer: CN=Caddy Local Authority - ECC Intermediate
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* using HTTP/1.1
> GET /public/index.php/demo HTTP/1.1
> Host: localhost
> User-Agent: curl/8.1.2
> Accept: */*
> 

^C⏎                            

http 2

$ curl -kNvs --http2 'https://localhost/public/index.php/demo'
*   Trying 127.0.0.1:443...
* Connected to localhost (127.0.0.1) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: [NONE]
*  start date: Mar 28 09:05:40 2024 GMT
*  expire date: Mar 28 21:05:40 2024 GMT
*  issuer: CN=Caddy Local Authority - ECC Intermediate
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: localhost]
* h2 [:path: /public/index.php/demo]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x139011e00)
> GET /public/index.php/demo HTTP/2
> Host: localhost
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/2 200 
< access-control-allow-origin: *
< alt-svc: h3=":443"; ma=2592000
< cache-control: no-cache, private
< content-type: text/event-stream; charset=UTF-8
< date: Thu, 28 Mar 2024 09:28:48 GMT
< server: Caddy
< x-accel-buffering: no
< x-powered-by: PHP/8.3.4
< x-robots-tag: noindex
< 
data:{"time":"09:28:48"}

data:{"time":"09:28:49"}

data:{"time":"09:28:50"}

^C⏎                            
@ninsuo ninsuo added the bug Something isn't working label Mar 28, 2024
@ninsuo ninsuo changed the title Server-Sent-Events not working in HTTP/1.1 Server-Sent-Events not working through HTTP/1.1 Mar 28, 2024
@withinboredom
Copy link
Collaborator

withinboredom commented Mar 28, 2024

You don't mention which version: standalone binary, i.e., the one from the downloads page, or the docker image.

One is a static build of PHP that has it's own php.ini, and the other is a more traditional shared lib build that uses the regular docker php.ini.

Regardless, I have a suspicion on the issue; I'll take a look.

@withinboredom
Copy link
Collaborator

I found the issue, and I'm creating a PR.

@withinboredom withinboredom linked a pull request Mar 28, 2024 that will close this issue
2 tasks
@ninsuo
Copy link
Author

ninsuo commented Mar 28, 2024

Thank you @withinboredom , I only tried using Docker.

@LukeAbell
Copy link

@withinboredom Any idea when we can get #692 merged? I'm pretty sure it's causing our issues with SSEs in our laravel application on production using the docker container.

@LukeAbell
Copy link

Scratch that, I might be experiencing a different problem. It's working locally on my M1 mac using http2, but not on production using http3. (Laravel Octane)

@dunglas
Copy link
Owner

dunglas commented Apr 18, 2024

@LukeAbell Indeed, this problem le should only occur when using HTTP/1, not when using 2 or 3.

We're waiting for a new Caddy release to merge #692. The Caddy team is working on it.

@LukeAbell
Copy link

@dunglas Got it. Any idea what would cause it to work locally but not on prod using docker? I've confirmed the PHP config is the same. I can open a different ticket if that's better.

@dunglas
Copy link
Owner

dunglas commented Apr 18, 2024

To be honest I've no idea. A reproducer would be great!

@dunglas
Copy link
Owner

dunglas commented Apr 18, 2024

And yes, please open another issue as this one will be closed when we will merge the current fix, that is unlikely to fix the issue you're describing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants