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

abort directive returns http/500 on http/3 #5125

Closed
emilylange opened this issue Oct 6, 2022 · 23 comments · Fixed by quic-go/quic-go#3950
Closed

abort directive returns http/500 on http/3 #5125

emilylange opened this issue Oct 6, 2022 · 23 comments · Fixed by quic-go/quic-go#3950
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed upstream ⬆️ Relates to some dependency of this project

Comments

@emilylange
Copy link
Member

I think the easiest way to show what I mean by that is with an example:

localhost {
	abort
}
❯ curl -kI https://localhost
curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)

The connection via http/2 gets closed immediately, which is expected when using the abort directive.
Excerpt from the docs (permalink):

Prevents any response to the client by immediately aborting the HTTP handler chain and closing the connection. Any concurrent, active HTTP streams on the same connection are interrupted.

The same config on http/3 however, yields a 500 Internal Server Error

❯ curl -kI https://localhost --http3
HTTP/3 500 
server: Caddy
alt-svc: h3=":443"; ma=2592000

Running Caddy with debug doesn't return any meaningful insights this time, but QUIC_GO_LOG_LEVEL=INFO (as documented in https://github.com/lucas-clemente/quic-go/wiki/Logging) does:

2022/10/06 19:15:03.320	INFO	server HEAD localhost/
2022/10/06 19:15:03.320	INFO	server http: panic serving: net/http: abort Handler
goroutine 68 [running]:
github.com/lucas-clemente/quic-go/http3.(*Server).handleRequest.func2.1()
	github.com/lucas-clemente/[email protected]/http3/server.go:583 +0x6f
panic({0x17e0de0, 0xc00007cbb0})
	runtime/panic.go:838 +0x207
github.com/caddyserver/caddy/v2/modules/caddyhttp.StaticResponse.ServeHTTP({{0x0, 0x0}, 0x0, {0x0, 0x0}, 0x0, 0x1}, {0x1dcc2e0?, 0xc00058ea00?}, 0xc00065c200, ...)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/staticresp.go:183 +0xa3d
github.com/caddyserver/caddy/v2/modules/caddyhttp.wrapMiddleware.func1.1({0x1dcc2e0?, 0xc00058ea00?}, 0x1dc27a0?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go:290 +0x42
github.com/caddyserver/caddy/v2/modules/caddyhttp.HandlerFunc.ServeHTTP(0x1dc27a0?, {0x1dcc2e0?, 0xc00058ea00?}, 0x0?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyhttp.go:58 +0x2f
github.com/caddyserver/caddy/v2/modules/caddyhttp.wrapRoute.func1.1({0x1dcc2e0, 0xc00058ea00}, 0xc00065c200)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go:259 +0x3a8
github.com/caddyserver/caddy/v2/modules/caddyhttp.HandlerFunc.ServeHTTP(0xc0003f8000?, {0x1dcc2e0?, 0xc00058ea00?}, 0x1dc27a0?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyhttp.go:58 +0x2f
github.com/caddyserver/caddy/v2/modules/caddyhttp.(*Subroute).ServeHTTP(0xc00062b920, {0x1dcc2e0, 0xc00058ea00}, 0x178b301?, {0x1dc27a0, 0x1b55740})
	github.com/caddyserver/caddy/v2/modules/caddyhttp/subroute.go:74 +0x6d
github.com/caddyserver/caddy/v2/modules/caddyhttp.wrapMiddleware.func1.1({0x1dcc2e0?, 0xc00058ea00?}, 0x1dc27a0?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go:290 +0x42
github.com/caddyserver/caddy/v2/modules/caddyhttp.HandlerFunc.ServeHTTP(0x1dc27a0?, {0x1dcc2e0?, 0xc00058ea00?}, 0x7dc5ed?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyhttp.go:58 +0x2f
github.com/caddyserver/caddy/v2/modules/caddyhttp.wrapRoute.func1.1({0x1dcc2e0, 0xc00058ea00}, 0xc00065c200)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go:259 +0x3a8
github.com/caddyserver/caddy/v2/modules/caddyhttp.HandlerFunc.ServeHTTP(0xc0005e6400?, {0x1dcc2e0?, 0xc00058ea00?}, 0x1995920?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyhttp.go:58 +0x2f
github.com/caddyserver/caddy/v2/modules/caddyhttp.(*Server).enforcementHandler(0x0?, {0x1dcc2e0?, 0xc00058ea00?}, 0xc000622ea0?, {0x1dc27a0?, 0xc00062b9a0?})
	github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go:370 +0x252
github.com/caddyserver/caddy/v2/modules/caddyhttp.(*Server).wrapPrimaryRoute.func1({0x1dcc2e0?, 0xc00058ea00?}, 0x4c7297?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go:346 +0x3b
github.com/caddyserver/caddy/v2/modules/caddyhttp.HandlerFunc.ServeHTTP(0xc0001f0750?, {0x1dcc2e0?, 0xc00058ea00?}, 0xc00065c200?)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyhttp.go:58 +0x2f
github.com/caddyserver/caddy/v2/modules/caddyhttp.(*Server).ServeHTTP(0xc000345680, {0x1dcc2e0, 0xc00058ea00}, 0xc00065c200)
	github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go:282 +0xb46
github.com/lucas-clemente/quic-go/http3.(*Server).handleRequest.func2(0x1dcf398?, 0xc0005bf080?, {0x1dbcbe0?, 0xc000345680?}, 0x1930460?, 0xc0005bf0b0?)
	github.com/lucas-clemente/[email protected]/http3/server.go:588 +0x7d
github.com/lucas-clemente/quic-go/http3.(*Server).handleRequest(0xc000134a50, {0x1ddb720?, 0xc0004d8600}, {0x7f32a148c288, 0xc000352000}, 0x0?, 0xc000116810)
	github.com/lucas-clemente/[email protected]/http3/server.go:589 +0xbd0
github.com/lucas-clemente/quic-go/http3.(*Server).handleConn.func1()
	github.com/lucas-clemente/[email protected]/http3/server.go:432 +0xfd
created by github.com/lucas-clemente/quic-go/http3.(*Server).handleConn
	github.com/lucas-clemente/[email protected]/http3/server.go:431 +0x1d7
2022/10/06 19:15:03.320	INFO	server Responding with 500
2022/10/06 19:15:03.321	INFO	server Peer closed connection with error: NO_ERROR
2022/10/06 19:15:03.321	INFO	server Connection 66dbb88190861fcb30249402ddbf06a8bd8165f3 closed.

The relevant code snippets seem to be:

// close the connection immediately
if s.Abort {
panic(http.ErrAbortHandler)
}
and https://github.com/lucas-clemente/quic-go/blob/424a66389c01d10678bfb980cfe6faa8524b42b6/http3/server.go#L575-L595


My curl version, though browsers will run into that too and the curl version doesn't really matter:

❯ curl --version
curl 7.85.0 (x86_64-pc-linux-gnu) libcurl/7.85.0 OpenSSL/3.0.5 zlib/1.2.12 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.2 libssh2/1.10.0 nghttp2/1.49.0 ngtcp2/0.9.0 nghttp3/0.7.0
Release-Date: 2022-08-31
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

A slightly modified version for plain http

http://http1.localhost {
	abort
}

yields

❯ curl -I http://http1.localhost
curl: (52) Empty reply from server

As far as I am aware, this has been the case since essentially ever.
I went as far back as v2.4.6, which might not seem that far. But I only stopped because my curl version dropped support for the old quic-draft versions.
I use the abort directive for my wildcard domains (just like the example here) and only noticed it when I did a little typo, to which my browser greeted me with a blank http/500 page instead of the usual and expected connection reset.

@francislavoie francislavoie added the bug 🐞 Something isn't working label Oct 6, 2022
@francislavoie
Copy link
Member

/cc @marten-seemann I think that quic-go isn't handling http.ErrAbortHandler the same way as stdlib, i.e. https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/net/http/server.go;l=1835;drc=cbd931c9c2705e0e3a44c3b299ac2bd3369f5eb5

@marten-seemann
Copy link
Contributor

That seems like a really simple fix. A PR would be appreciated :)

@francislavoie francislavoie added the good first issue 🐤 Good for newcomers label Oct 6, 2022
@francislavoie
Copy link
Member

Marking it as "good first issue", hopefully someone would like to take this on on our behalf 😁

@marten-seemann
Copy link
Contributor

I opened quic-go/quic-go#3572. @IndeedNotJames, do you want to contribute a fix?

@francislavoie francislavoie added the upstream ⬆️ Relates to some dependency of this project label Oct 7, 2022
@shade34321
Copy link

I wouldn't mind taking a crack at this, but might need some help.

@marten-seemann
Copy link
Contributor

Please see the quic-go issue. It has all the details.

@marten-seemann
Copy link
Contributor

quic-go/quic-go#3575 was merged. Thank you @shade34321 for your contribution.
This issue will be resolved with the next quic-go update (once we cut a release containing this fix).

@francislavoie
Copy link
Member

@shade34321 feel free to make a PR to Caddy updating the quic-go version once released, to make sure it fixes the issue in Caddy 👍

@shade34321
Copy link

Ok, sounds good.

@francislavoie
Copy link
Member

Matt ended up bumping the quic-go version in #5120

@francislavoie francislavoie added this to the v2.6.2 milestone Oct 13, 2022
@mholt
Copy link
Member

mholt commented Oct 13, 2022

But does https://github.com/lucas-clemente/quic-go/releases/tag/v0.29.2 contain the fix? 🤔 I don't see it in the diff.

@shade34321
Copy link

Ok, sounds good. I didn't realize they had updated the quic version. If it turns out that version doesn't have the fix just let me know and I'll keep an eye out for a release with my fix. Thanks!

@francislavoie
Copy link
Member

@mholt oh, I guess it doesn't. Looks like v0.29.2 was a hotfix release off a separate branch, and didn't include the rest of the stuff on master.

@francislavoie francislavoie reopened this Oct 13, 2022
@francislavoie francislavoie modified the milestones: v2.6.2, v2.6.3 Oct 13, 2022
@emilylange
Copy link
Member Author

Wait no 😅

The current master returns the following:

❯ curl -kI https://localhost/ --http3
HTTP/3 500 
server: Caddy

(basically the same, but without alt-svc: h3=":443"; ma=2592000)

@mholt
Copy link
Member

mholt commented Oct 13, 2022

Darn. @marten-seemann I guess this patch wasn't included, and unfortunately missed our 2.6.2 tag today. We can get it in the next one though.

(And that's correct, Caddy 2.6.2 no longer advertises HTTP/3 over HTTP/3, as there is no need.)

@marten-seemann
Copy link
Contributor

Indeed, quic-go v0.29.2 only contains the standard library crypto/tls fix, as well as a fix for a busy-looping which would occur under rare circumstances.

quic-go/quic-go#3575 will be shipped as part of the v0.30 release.

@bt90
Copy link
Contributor

bt90 commented Dec 8, 2022

Should be fixed with the current master?

@mholt
Copy link
Member

mholt commented Dec 8, 2022

Oh! Yes, we are now pinned to v0.31.0 which should be more than new enough to contain the fix.

It will go out with 2.6.3. Thanks everyone!

@mholt mholt closed this as completed Dec 8, 2022
@emilylange
Copy link
Member Author

I'm afraid this didn't fix it 👀

Built against master with go 1.19.3

❯ ./caddy version
v2.6.3-0.20221208155504-fac35db9dcbf h1:kNGT9DX89a3ir8wWCN2BzqAXArQC5aZ014wiUD5V7OE=
❯ cat Caddyfile
localhost {
    abort
}
❯ curl -kI https://localhost --http3
HTTP/3 500 
server: Caddy

@francislavoie francislavoie reopened this Dec 8, 2022
@bt90
Copy link
Contributor

bt90 commented Dec 19, 2022

@IndeedNotJames anything in the (QUIC) logs?

@mholt mholt added help wanted 🆘 Extra attention is needed and removed good first issue 🐤 Good for newcomers labels Dec 19, 2022
@mholt mholt modified the milestones: v2.6.3, v2.7.0 Feb 6, 2023
@mholt mholt modified the milestones: v2.7.0, v2.8.0 May 13, 2023
@WeidiDeng
Copy link
Member

I fixed it in the pr, which also fixes some of the difference between stdlib and http3.

@mholt
Copy link
Member

mholt commented Jun 28, 2023

Thanks so much @WeidiDeng 😃

@WeidiDeng
Copy link
Member

Fixed in the upstream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed upstream ⬆️ Relates to some dependency of this project
Projects
None yet
7 participants