net/http: ResponseController limitations #63656
Labels
FrozenDueToAge
WaitingForInfo
Issue is not actionable because of missing required information, which needs to be provided.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I've add the ResponseController as given in this example: https://www.alexedwards.net/blog/how-to-use-the-http-responsecontroller-type.
Only difference is that I'm read the request before creating the ResponseController.
I'm using the golang http server + gorilla multiplexer including a middleware handler.
I have a connection state change listener, which shows connection changes when I use the old flusher technique.
I don't see state changes when I use the ResponseController.
Some logging during test:
2023-10-21T14:00:28.453+0200 INFO ResponseWriter before creating Controller: *http.response &http.response{conn:(*http.conn)(0xc00017b320), req:(*http.Request)(0xc000188600), reqBody:(*http.body)(0xc0 0020e500), cancelCtx:(context.CancelFunc)(0xa66820), wroteHeader:false, wroteContinue:false, wants10KeepAlive:false, wantsClose:false, canWriteContinue:atomic.Bool{_:atomic.noCopy{}, v:0x0}, writeContinueMu :sync.Mutex{state:0, sema:0x0}, w:(*bufio.Writer)(0xc00020e540), cw:http.chunkWriter{res:(*http.response)(0xc0002121c0), header:http.Header(nil), wroteHeader:false, chunking:false}, handlerHeader:http.Heade r{}, calledHeader:false, written:0, contentLength:-1, status:0, closeAfterReply:false, requestBodyLimitHit:false, trailers:[]string(nil), handlerDone:atomic.Bool{_:atomic.noCopy{}, v:0x0}, dateBuf:[29]uint8 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, clenBuf:[10]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, statusBuf:[3]uint8{0x0, 0x0, 0x0}, closeNotifyCh:(chan bool)(0xc0001c4380), didCloseNotify:atomic.Bool{_:atomic.noCopy{}, v:0x0}}
2023-10-21T14:00:28.453+0200 INFO Created ResponseController: *http.ResponseController &http.ResponseController{rw:(*http.response)(0xc0002121c0)}
2023-10-21T14:00:28.453+0200 INFO ResponseWriter after creating Controller: *http.response &http.response{conn:(*http.conn)(0xc00017b320), req:(*http.Request)(0xc000188600), reqBody:(*http.body)(0xc00 020e500), cancelCtx:(context.CancelFunc)(0xa66820), wroteHeader:false, wroteContinue:false, wants10KeepAlive:false, wantsClose:false, canWriteContinue:atomic.Bool{_:atomic.noCopy{}, v:0x0}, writeContinueMu: sync.Mutex{state:0, sema:0x0}, w:(*bufio.Writer)(0xc00020e540), cw:http.chunkWriter{res:(*http.response)(0xc0002121c0), header:http.Header(nil), wroteHeader:false, chunking:false}, handlerHeader:http.Header {}, calledHeader:false, written:0, contentLength:-1, status:0, closeAfterReply:false, requestBodyLimitHit:false, trailers:[]string(nil), handlerDone:atomic.Bool{_:atomic.noCopy{}, v:0x0}, dateBuf:[29]uint8{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, clenBuf:[10]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, statusBuf:[3]uint8{0x0, 0x0, 0x0}, closeNotifyCh:(chan bool)(0xc0001c4380), didCloseNotify:atomic.Bool{_:atomic.noCopy{}, v:0x0}} 2
What did you expect to see?
I was hoping the whole issue with connections being closed would be solved for my streaming case.
What did you see instead?
Bytes were succesfully written but not received by client (client does work with other streams), no errors what so ever from fmt or the response controller.
As the ResponseController is very silent not giving any clue of what is going wrong, I currently am working to reproduce this issue migrating step-by-step from example to my own setup to isolate the cause.
Question
Not sure if this is a bug or whether there are limitations on using the ResponseController.
It is nice that there is a ResponseController to manipulate the connection.
So far I've seen a limitation documented to create the controller before first write (including headers I presume), are there other limitations which I could not find in the documentation but are suffering from?
For instance should the ResponseController be created before reading the request?
My code is working with the old flush workaround, but then the connection closes after being idle for about 30-60 sec.
If there are, please share.
The text was updated successfully, but these errors were encountered: