diff --git a/gin.go b/gin.go index 3192f6c4..25402fe2 100644 --- a/gin.go +++ b/gin.go @@ -138,7 +138,7 @@ func (engine *Engine) Run(addr string) { func (group *RouterGroup) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context { return &Context{ - Writer: ResponseWriter{w, -1}, + Writer: ResponseWriter{w, StatusUnset}, Req: req, index: -1, engine: group.engine, @@ -327,7 +327,7 @@ func (c *Context) JSON(code int, obj interface{}) { if code >= 0 { c.Writer.WriteHeader(code) } - encoder := json.NewEncoder(c.Writer) + encoder := json.NewEncoder(&c.Writer) if err := encoder.Encode(obj); err != nil { c.Error(err, obj) http.Error(&c.Writer, err.Error(), 500) @@ -341,7 +341,7 @@ func (c *Context) XML(code int, obj interface{}) { if code >= 0 { c.Writer.WriteHeader(code) } - encoder := xml.NewEncoder(c.Writer) + encoder := xml.NewEncoder(&c.Writer) if err := encoder.Encode(obj); err != nil { c.Error(err, obj) http.Error(&c.Writer, err.Error(), 500) @@ -356,7 +356,7 @@ func (c *Context) HTML(code int, name string, data interface{}) { if code >= 0 { c.Writer.WriteHeader(code) } - if err := c.engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil { + if err := c.engine.HTMLTemplates.ExecuteTemplate(&c.Writer, name, data); err != nil { c.Error(err, map[string]interface{}{ "name": name, "data": data, diff --git a/response_writer.go b/response_writer.go index 91a4595e..ee6bbe8a 100644 --- a/response_writer.go +++ b/response_writer.go @@ -4,6 +4,10 @@ import ( "net/http" ) +const ( + StatusUnset int = -1 +) + type ResponseWriter struct { http.ResponseWriter status int @@ -14,6 +18,31 @@ func (w *ResponseWriter) WriteHeader(code int) { w.ResponseWriter.WriteHeader(code) } +func (w *ResponseWriter) Write(data []byte) (int, error) { + // net/http.Response.Write only has two options: 200 or 500 + // we will follow that lead and defer to their logic + + // check if the write gave an error and set status accordingly + size, err := w.ResponseWriter.Write(data) + if err != nil { + // error on write, we give a 500 + w.status = http.StatusInternalServerError + } else if w.WasWritten() == false { + // everything went okay and we never set a custom + // status so 200 it is + w.status = http.StatusOK + } + + // can easily tap into Content-Length here with 'size' + return size, err +} + +// returns the status of the given response func (w *ResponseWriter) Status() int { return w.status } + +// return a boolean acknowledging if a status code has all ready been set +func (w *ResponseWriter) WasWritten() bool { + return w.status == StatusUnset +}