...
1
2
3
4
5 package gin
6
7 import (
8 "bufio"
9 "io"
10 "net"
11 "net/http"
12 )
13
14 const (
15 noWritten = -1
16 defaultStatus = http.StatusOK
17 )
18
19
20 type ResponseWriter interface {
21 http.ResponseWriter
22 http.Hijacker
23 http.Flusher
24 http.CloseNotifier
25
26
27 Status() int
28
29
30
31 Size() int
32
33
34 WriteString(string) (int, error)
35
36
37 Written() bool
38
39
40 WriteHeaderNow()
41
42
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)(nil)
53
54 func (w *responseWriter) Unwrap() http.ResponseWriter {
55 return w.ResponseWriter
56 }
57
58 func (w *responseWriter) reset(writer http.ResponseWriter) {
59 w.ResponseWriter = writer
60 w.size = noWritten
61 w.status = defaultStatus
62 }
63
64 func (w *responseWriter) WriteHeader(code int) {
65 if code > 0 && w.status != code {
66 if w.Written() {
67 debugPrint("[WARNING] Headers were already written. Wanted to override status code %d with %d", w.status, code)
68 return
69 }
70 w.status = code
71 }
72 }
73
74 func (w *responseWriter) WriteHeaderNow() {
75 if !w.Written() {
76 w.size = 0
77 w.ResponseWriter.WriteHeader(w.status)
78 }
79 }
80
81 func (w *responseWriter) Write(data []byte) (n int, err error) {
82 w.WriteHeaderNow()
83 n, err = w.ResponseWriter.Write(data)
84 w.size += n
85 return
86 }
87
88 func (w *responseWriter) WriteString(s string) (n int, err error) {
89 w.WriteHeaderNow()
90 n, err = io.WriteString(w.ResponseWriter, s)
91 w.size += n
92 return
93 }
94
95 func (w *responseWriter) Status() int {
96 return w.status
97 }
98
99 func (w *responseWriter) Size() int {
100 return w.size
101 }
102
103 func (w *responseWriter) Written() bool {
104 return w.size != noWritten
105 }
106
107
108 func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
109 if w.size < 0 {
110 w.size = 0
111 }
112 return w.ResponseWriter.(http.Hijacker).Hijack()
113 }
114
115
116 func (w *responseWriter) CloseNotify() <-chan bool {
117 return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
118 }
119
120
121 func (w *responseWriter) Flush() {
122 w.WriteHeaderNow()
123 w.ResponseWriter.(http.Flusher).Flush()
124 }
125
126 func (w *responseWriter) Pusher() (pusher http.Pusher) {
127 if pusher, ok := w.ResponseWriter.(http.Pusher); ok {
128 return pusher
129 }
130 return nil
131 }
132
View as plain text