Skip to content

Commit 3c3823d

Browse files
authored
Ensure Written is set in GZIP ProxyResponseWriter (#9018) (#9026)
Fix #9001 The GZIP ProxyReponseWriter doesn't currently respond correctly to requests about its Written status - leading to #9001. This PR properly reimplements these methods.
1 parent 2f73fff commit 3c3823d

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

modules/gzip/gzip.go

+43-10
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func Middleware(options ...Options) macaron.Handler {
123123
// OK we should proxy the response writer
124124
// We are still not necessarily going to compress...
125125
proxyWriter := &ProxyResponseWriter{
126-
ResponseWriter: ctx.Resp,
126+
internal: ctx.Resp,
127127
}
128128
defer proxyWriter.Close()
129129

@@ -137,19 +137,52 @@ func Middleware(options ...Options) macaron.Handler {
137137
}
138138

139139
ctx.Next()
140+
ctx.Resp = proxyWriter.internal
140141
}
141142
}
142143

143144
// ProxyResponseWriter is a wrapped macaron ResponseWriter that may compress its contents
144145
type ProxyResponseWriter struct {
145-
writer io.WriteCloser
146-
macaron.ResponseWriter
147-
stopped bool
146+
writer io.WriteCloser
147+
internal macaron.ResponseWriter
148+
stopped bool
148149

149150
code int
150151
buf []byte
151152
}
152153

154+
// Header returns the header map
155+
func (proxy *ProxyResponseWriter) Header() http.Header {
156+
return proxy.internal.Header()
157+
}
158+
159+
// Status returns the status code of the response or 0 if the response has not been written.
160+
func (proxy *ProxyResponseWriter) Status() int {
161+
if proxy.code != 0 {
162+
return proxy.code
163+
}
164+
return proxy.internal.Status()
165+
}
166+
167+
// Written returns whether or not the ResponseWriter has been written.
168+
func (proxy *ProxyResponseWriter) Written() bool {
169+
if proxy.code != 0 {
170+
return true
171+
}
172+
return proxy.internal.Written()
173+
}
174+
175+
// Size returns the size of the response body.
176+
func (proxy *ProxyResponseWriter) Size() int {
177+
return proxy.internal.Size()
178+
}
179+
180+
// Before allows for a function to be called before the ResponseWriter has been written to. This is
181+
// useful for setting headers or any other operations that must happen before a response has been written.
182+
func (proxy *ProxyResponseWriter) Before(before macaron.BeforeFunc) {
183+
proxy.internal.Before(before)
184+
}
185+
153186
// Write appends data to the proxied gzip writer.
154187
func (proxy *ProxyResponseWriter) Write(b []byte) (int, error) {
155188
// if writer is initialized, use the writer
@@ -210,7 +243,7 @@ func (proxy *ProxyResponseWriter) startGzip() error {
210243

211244
// Write the header to gzip response.
212245
if proxy.code != 0 {
213-
proxy.ResponseWriter.WriteHeader(proxy.code)
246+
proxy.internal.WriteHeader(proxy.code)
214247
// Ensure that no other WriteHeader's happen
215248
proxy.code = 0
216249
}
@@ -220,7 +253,7 @@ func (proxy *ProxyResponseWriter) startGzip() error {
220253
// write the gzip header even if nothing was ever written.
221254
if len(proxy.buf) > 0 {
222255
// Initialize the GZIP response.
223-
proxy.writer = writerPool.Get(proxy.ResponseWriter)
256+
proxy.writer = writerPool.Get(proxy.internal)
224257

225258
return proxy.writeBuf()
226259
}
@@ -229,11 +262,11 @@ func (proxy *ProxyResponseWriter) startGzip() error {
229262

230263
func (proxy *ProxyResponseWriter) startPlain() error {
231264
if proxy.code != 0 {
232-
proxy.ResponseWriter.WriteHeader(proxy.code)
265+
proxy.internal.WriteHeader(proxy.code)
233266
proxy.code = 0
234267
}
235268
proxy.stopped = true
236-
proxy.writer = noopCloser{proxy.ResponseWriter}
269+
proxy.writer = noopCloser{proxy.internal}
237270
return proxy.writeBuf()
238271
}
239272

@@ -295,13 +328,13 @@ func (proxy *ProxyResponseWriter) Flush() {
295328
gw.Flush()
296329
}
297330

298-
proxy.ResponseWriter.Flush()
331+
proxy.internal.Flush()
299332
}
300333

301334
// Hijack implements http.Hijacker. If the underlying ResponseWriter is a
302335
// Hijacker, its Hijack method is returned. Otherwise an error is returned.
303336
func (proxy *ProxyResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
304-
hijacker, ok := proxy.ResponseWriter.(http.Hijacker)
337+
hijacker, ok := proxy.internal.(http.Hijacker)
305338
if !ok {
306339
return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
307340
}

0 commit comments

Comments
 (0)