github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/response_writer.go (about) 1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package gin 6 7 import ( 8 "bufio" 9 "github.com/hellobchain/newcryptosm/http" 10 "io" 11 "net" 12 ) 13 14 const ( 15 noWritten = -1 16 defaultStatus = http.StatusOK 17 ) 18 19 // ResponseWriter ... 20 type ResponseWriter interface { 21 http.ResponseWriter 22 http.Hijacker 23 http.Flusher 24 http.CloseNotifier 25 26 // Returns the HTTP response status code of the current request. 27 Status() int 28 29 // Returns the number of bytes already written into the response http body. 30 // See Written() 31 Size() int 32 33 // Writes the string into the response body. 34 WriteString(string) (int, error) 35 36 // Returns true if the response body was already written. 37 Written() bool 38 39 // Forces to write the http header (status code + headers). 40 WriteHeaderNow() 41 42 // get the http.Pusher for server push 43 Pusher() http.Pusher 44 } 45 46 type responseWriter struct { 47 http.ResponseWriter 48 size int 49 status int 50 } 51 52 var _ ResponseWriter = &responseWriter{} 53 54 func (w *responseWriter) reset(writer http.ResponseWriter) { 55 w.ResponseWriter = writer 56 w.size = noWritten 57 w.status = defaultStatus 58 } 59 60 func (w *responseWriter) WriteHeader(code int) { 61 if code > 0 && w.status != code { 62 if w.Written() { 63 debugPrint("[WARNING] Headers were already written. Wanted to override status code %d with %d", w.status, code) 64 } 65 w.status = code 66 } 67 } 68 69 func (w *responseWriter) WriteHeaderNow() { 70 if !w.Written() { 71 w.size = 0 72 w.ResponseWriter.WriteHeader(w.status) 73 } 74 } 75 76 func (w *responseWriter) Write(data []byte) (n int, err error) { 77 w.WriteHeaderNow() 78 n, err = w.ResponseWriter.Write(data) 79 w.size += n 80 return 81 } 82 83 func (w *responseWriter) WriteString(s string) (n int, err error) { 84 w.WriteHeaderNow() 85 n, err = io.WriteString(w.ResponseWriter, s) 86 w.size += n 87 return 88 } 89 90 func (w *responseWriter) Status() int { 91 return w.status 92 } 93 94 func (w *responseWriter) Size() int { 95 return w.size 96 } 97 98 func (w *responseWriter) Written() bool { 99 return w.size != noWritten 100 } 101 102 // Hijack implements the http.Hijacker interface. 103 func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { 104 if w.size < 0 { 105 w.size = 0 106 } 107 return w.ResponseWriter.(http.Hijacker).Hijack() 108 } 109 110 // CloseNotify implements the http.CloseNotify interface. 111 func (w *responseWriter) CloseNotify() <-chan bool { 112 return w.ResponseWriter.(http.CloseNotifier).CloseNotify() 113 } 114 115 // Flush implements the http.Flush interface. 116 func (w *responseWriter) Flush() { 117 w.WriteHeaderNow() 118 w.ResponseWriter.(http.Flusher).Flush() 119 } 120 121 func (w *responseWriter) Pusher() (pusher http.Pusher) { 122 if pusher, ok := w.ResponseWriter.(http.Pusher); ok { 123 return pusher 124 } 125 return nil 126 }