gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
76.77k stars 7.92k forks source link

serveError does not call WriteHeader() before calling Write() #3284

Open melugoyal opened 1 year ago

melugoyal commented 1 year ago

Description

Gin should call c.Writer.WriteHeader(code) before calling c.Writer.Write(defaultMessage) when handling errors here: https://github.com/gin-gonic/gin/blob/b04917c53e310e3746ec90cd93106cda8c956211/gin.go#L658

from the documentation of the Write() function in net/http's ResponseWriter interface:

If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) before writing the data

This is an issue when injecting a custom response writer into Gin that needs to know the status that was written before Write is called. Otherwise the custom response writer defaults to 200 OK per the documentation above, then Gin later tries writing a different header with WriteHeaderNow().

Environment

mstmdev commented 1 year ago

To my understanding, the implementation of c.Writer is responseWriter, the responseWriter.Write will call the WriteHeader first.

melugoyal commented 1 year ago

Right, but i am using a custom ResponseWriter with Gin (injected into the context), and when doing so, expect Gin to call WriteHeader before calling Write, as is documented in the interface godoc:

If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes

mstmdev commented 1 year ago

I get it. It looks like it will break some existing conventions.