123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // 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"
- "io"
- "net"
- "net/http"
- )
- const (
- noWritten = -1
- defaultStatus = http.StatusOK
- )
- // ResponseWriter ...
- type ResponseWriter interface {
- http.ResponseWriter
- http.Hijacker
- http.Flusher
- http.CloseNotifier
- // Returns the HTTP response status code of the current request.
- Status() int
- // Returns the number of bytes already written into the response http body.
- // See Written()
- Size() int
- // Writes the string into the response body.
- WriteString(string) (int, error)
- // Returns true if the response body was already written.
- Written() bool
- // Forces to write the http header (status code + headers).
- WriteHeaderNow()
- // get the http.Pusher for server push
- Pusher() http.Pusher
- }
- type responseWriter struct {
- http.ResponseWriter
- size int
- status int
- }
- var _ ResponseWriter = &responseWriter{}
- 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() {
- debugPrint("[WARNING] Headers were already written. Wanted to override status code %d with %d", w.status, code)
- }
- w.status = code
- }
- }
- 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) WriteString(s string) (n int, err error) {
- w.WriteHeaderNow()
- n, err = io.WriteString(w.ResponseWriter, s)
- 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
- }
- // Hijack implements the http.Hijacker interface.
- func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- if w.size < 0 {
- w.size = 0
- }
- return w.ResponseWriter.(http.Hijacker).Hijack()
- }
- // CloseNotify implements the http.CloseNotify interface.
- func (w *responseWriter) CloseNotify() <-chan bool {
- return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
- }
- // Flush implements the http.Flush interface.
- func (w *responseWriter) Flush() {
- w.WriteHeaderNow()
- w.ResponseWriter.(http.Flusher).Flush()
- }
- func (w *responseWriter) Pusher() (pusher http.Pusher) {
- if pusher, ok := w.ResponseWriter.(http.Pusher); ok {
- return pusher
- }
- return nil
- }
|