Deferring WriteHeader. Part 1
This commit is contained in:
		
							
								
								
									
										10
									
								
								gin.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								gin.go
									
									
									
									
									
								
							@ -45,10 +45,15 @@ type (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
 | 
					func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
	c := engine.createContext(w, req, nil, engine.finalNoRoute)
 | 
						c := engine.createContext(w, req, nil, engine.finalNoRoute)
 | 
				
			||||||
	c.Writer.setStatus(404)
 | 
						// set 404 by default, useful for logging
 | 
				
			||||||
 | 
						c.Writer.WriteHeader(404)
 | 
				
			||||||
	c.Next()
 | 
						c.Next()
 | 
				
			||||||
	if !c.Writer.Written() {
 | 
						if !c.Writer.Written() {
 | 
				
			||||||
		c.Data(404, MIMEPlain, []byte("404 page not found"))
 | 
							if c.Writer.Status() == 404 {
 | 
				
			||||||
 | 
								c.Data(-1, MIMEPlain, []byte("404 page not found"))
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								c.Writer.WriteHeaderNow()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	engine.cache.Put(c)
 | 
						engine.cache.Put(c)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -166,6 +171,7 @@ func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
 | 
				
			|||||||
	group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
 | 
						group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
 | 
				
			||||||
		c := group.engine.createContext(w, req, params, handlers)
 | 
							c := group.engine.createContext(w, req, params, handlers)
 | 
				
			||||||
		c.Next()
 | 
							c.Next()
 | 
				
			||||||
 | 
							c.Writer.WriteHeaderNow()
 | 
				
			||||||
		group.engine.cache.Put(c)
 | 
							group.engine.cache.Put(c)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,6 @@ func Logger() HandlerFunc {
 | 
				
			|||||||
		if len(requester) == 0 {
 | 
							if len(requester) == 0 {
 | 
				
			||||||
			requester = c.Request.Header.Get("X-Forwarded-For")
 | 
								requester = c.Request.Header.Get("X-Forwarded-For")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// if the requester is still empty, use the hard-coded address from the socket
 | 
							// if the requester is still empty, use the hard-coded address from the socket
 | 
				
			||||||
		if len(requester) == 0 {
 | 
							if len(requester) == 0 {
 | 
				
			||||||
			requester = c.Request.RemoteAddr
 | 
								requester = c.Request.RemoteAddr
 | 
				
			||||||
 | 
				
			|||||||
@ -35,11 +35,9 @@ var (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func writeHeader(w http.ResponseWriter, code int, contentType string) {
 | 
					func writeHeader(w http.ResponseWriter, code int, contentType string) {
 | 
				
			||||||
	if code >= 0 {
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", contentType)
 | 
						w.Header().Set("Content-Type", contentType)
 | 
				
			||||||
	w.WriteHeader(code)
 | 
						w.WriteHeader(code)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
	writeHeader(w, code, "application/json")
 | 
						writeHeader(w, code, "application/json")
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
package gin
 | 
					package gin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -9,9 +10,7 @@ type (
 | 
				
			|||||||
		http.ResponseWriter
 | 
							http.ResponseWriter
 | 
				
			||||||
		Status() int
 | 
							Status() int
 | 
				
			||||||
		Written() bool
 | 
							Written() bool
 | 
				
			||||||
 | 
							WriteHeaderNow()
 | 
				
			||||||
		// private
 | 
					 | 
				
			||||||
		setStatus(int)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	responseWriter struct {
 | 
						responseWriter struct {
 | 
				
			||||||
@ -27,14 +26,30 @@ func (w *responseWriter) reset(writer http.ResponseWriter) {
 | 
				
			|||||||
	w.written = false
 | 
						w.written = false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (w *responseWriter) setStatus(code int) {
 | 
					func (w *responseWriter) WriteHeader(code int) {
 | 
				
			||||||
 | 
						if code != 0 {
 | 
				
			||||||
		w.status = code
 | 
							w.status = code
 | 
				
			||||||
 | 
							if w.written {
 | 
				
			||||||
 | 
								log.Println("[GIN] WARNING. Headers were already written!")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (w *responseWriter) WriteHeader(code int) {
 | 
					func (w *responseWriter) WriteHeaderNow() {
 | 
				
			||||||
	w.status = code
 | 
						if !w.written {
 | 
				
			||||||
		w.written = true
 | 
							w.written = true
 | 
				
			||||||
	w.ResponseWriter.WriteHeader(code)
 | 
							w.ResponseWriter.WriteHeader(w.status)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *responseWriter) Write(data []byte) (n int, err error) {
 | 
				
			||||||
 | 
						if !w.written {
 | 
				
			||||||
 | 
							if w.status != 0 {
 | 
				
			||||||
 | 
								w.ResponseWriter.WriteHeader(w.status)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							w.written = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return w.ResponseWriter.Write(data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (w *responseWriter) Status() int {
 | 
					func (w *responseWriter) Status() int {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user