// Copyright 2014 Manu Martinez-Almeida. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. package gin import ( "bufio" "log" "net" "net/http" ) const ( noWritten = -1 defaultStatus = 200 ) type ( ResponseWriter interface { http.ResponseWriter http.Hijacker http.Flusher http.CloseNotifier Status() int Size() int Written() bool WriteHeaderNow() } responseWriter struct { http.ResponseWriter size int status int } ) func (w *responseWriter) reset(writer http.ResponseWriter) { w.ResponseWriter = writer w.size = noWritten w.status = defaultStatus } func (w *responseWriter) WriteHeader(code int) { if code > 0 { w.status = code if w.Written() { log.Println("[GIN] WARNING. Headers were already written!") } } } func (w *responseWriter) WriteHeaderNow() { if !w.Written() { w.size = 0 w.ResponseWriter.WriteHeader(w.status) } } func (w *responseWriter) Write(data []byte) (n int, err error) { w.WriteHeaderNow() n, err = w.ResponseWriter.Write(data) w.size += n return } func (w *responseWriter) Status() int { return w.status } func (w *responseWriter) Size() int { return w.size } func (w *responseWriter) Written() bool { return w.size != noWritten } // Implements the http.Hijacker interface func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { w.size = 0 // this prevents Gin to write the HTTP headers return w.ResponseWriter.(http.Hijacker).Hijack() } // Implements the http.CloseNotify interface func (w *responseWriter) CloseNotify() <-chan bool { return w.ResponseWriter.(http.CloseNotifier).CloseNotify() } // Implements the http.Flush interface func (w *responseWriter) Flush() { w.ResponseWriter.(http.Flusher).Flush() }