Home > Software engineering >  Why response code is set firstly in method *Context.Render(code int, r render.Render) of gin?
Why response code is set firstly in method *Context.Render(code int, r render.Render) of gin?

Time:09-17

Gin has encapsulated some methods for constructing response, such as methods *Context.JSON(code int, obj interface{}) and *Context.String(code int, format string, values ...interface{}). These methods all call the method *Context.Render(code int, r render.Render).

// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
    c.Status(code)

    if !bodyAllowedForStatus(code) {
        r.WriteContentType(c.Writer)
        c.Writer.WriteHeaderNow()
        return
    }

    if err := r.Render(c.Writer); err != nil {
        panic(err)
    }
}

I wonder why the Render method call the method Status which will set the HTTP response code by calling the method ResponseWriter.WriterHeader(statusCode int) firstly.

r.Render(c.Writer) will write Corresponding Content-Type to the response. Apparently it occurs after setting the status code (after calling method WriterHeader). According to the comment on method ResponseWriter.Header(), changing the header map after a call to WriteHeader (or Write) has no effect unless the modified headers are trailers. But setting Content-Type works in Gin.

func writeContentType(w http.ResponseWriter, value []string) {
    header := w.Header()
    if val := header["Content-Type"]; len(val) == 0 {
        header["Content-Type"] = value
    }
}

CodePudding user response:

c.Writer is a gin.ResponseWriter (probably the concrete type gin.responseWriter), not an http.ResponseWriter. While it implements the same interface, it doesn't do it in an identical way. Gin's WriteHeader doesn't send the headers immediately; it just stores the code internally in the writer, and WriteHeaderNow calls the "real" WriteHeader from net/http with the stored code.

WriteHeaderNow is called directly by the function you quoted in the case where there's no body; if there is a body, then WriteHeaderNow gets called on the first Write to the body.

  • Related