quic-go: http3 post request with body failed
this problem origin publish in caddy issue, but i think it is a quic go problems, more info:https://github.com/caddyserver/caddy/issues/3429
post request has body so can not return response. you can reference this link: https://github.com/caddyserver/caddy/issues/3429
i am a co-worker with @majc08149 , i find problem reason and code. But I do not know how to modify? @mholt
I paste problem code : file->net/http/transfer.go:371
if t.BodyCloser != nil { if err := t.BodyCloser.Close(); err != nil { return err } } the function BodyCloser.Close() call quic-go->http3->body.go Close() like : ` func (r *body) Close() error { // quic.Stream.Close() closes the write side, not the read side if r.isRequest { return r.str.Close() } r.requestDone() r.str.CancelRead(quic.ErrorCode(errorRequestCanceled)) return nil }
`
this call quic-go->stream.go function 👍 func (s *stream) Close() error { if err := s.sendStream.Close(); err != nil { return err } return nil }
the function s.sendStream.Close() will call func (s *sendStream) Close() error , this function call s.ctxCancel() to cancel context. so the request reverseproxy will be canceled.
please help me how to fix this bug?
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 53 (31 by maintainers)
you can use quiche client to reproduce it. the quiche link : https://github.com/cloudflare/quiche, it is a http3 library and include http3 client tool @mholt @marten-seemann
use caddy version:2.0.0 caddy file:
Yeah right, if you remove the call to
Close()
, then the stream doesn’t get closed. But that’s not a solution. The stream will never get garbage-collected and your connection will stop working once the stream limit is reached…@marten-seemann Thanks for doing this, I’ll try to take a look after the holiday!
I wrote a client to reproduce the bug in Go, so we don’t have to rely on quiche here. I don’t know how sophisticated their client implementation is - there’s no reason to time out on in the situation, and in fact quic-go wouldn’t do that.
The client is here: https://gist.github.com/marten-seemann/1cb0d87a43935c377c9e59a49c3dbc71. You should be able to just
go run
this file.Usage:
Performs a POST request via HTTP/2 / HTTP/1.1.
Performs the same POST request via HTTP/3. It also outputs a qlog. qlogs can be loaded in qvis to inspect the trace. Not sure if that really helps us debug this issue though, all I see is the client sending the request (on stream 0) and then sending a FIN, whereas the server sends a FIN at offset 0.
@mholt Any idea how to further debug this?
@marten-seemann you are right. So I need your help to fix . Maybe close quic-go stream later.
file: go/src/net/http/transfer.go
@mholt if I remove the extra call to Close() in quic-go, it be fine. and I solve my problems.
Please go read https://guides.github.com/features/mastering-markdown/ this is killing me
You’re using > for quotes. Don’t do that. Quotes don’t preserve whitespace. Use ``` for code blocks.