@@ -156,7 +156,7 @@ func (enc *Encode) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyh
156
156
if _ , ok := enc .writerPools [encName ]; ! ok {
157
157
continue // encoding not offered
158
158
}
159
- w = enc .openResponseWriter (encName , w )
159
+ w = enc .openResponseWriter (encName , w , r . Method == http . MethodConnect )
160
160
defer w .(* responseWriter ).Close ()
161
161
162
162
// to comply with RFC 9110 section 8.8.3(.3), we modify the Etag when encoding
@@ -201,21 +201,22 @@ func (enc *Encode) addEncoding(e Encoding) error {
201
201
// openResponseWriter creates a new response writer that may (or may not)
202
202
// encode the response with encodingName. The returned response writer MUST
203
203
// be closed after the handler completes.
204
- func (enc * Encode ) openResponseWriter (encodingName string , w http.ResponseWriter ) * responseWriter {
204
+ func (enc * Encode ) openResponseWriter (encodingName string , w http.ResponseWriter , isConnect bool ) * responseWriter {
205
205
var rw responseWriter
206
- return enc .initResponseWriter (& rw , encodingName , w )
206
+ return enc .initResponseWriter (& rw , encodingName , w , isConnect )
207
207
}
208
208
209
209
// initResponseWriter initializes the responseWriter instance
210
210
// allocated in openResponseWriter, enabling mid-stack inlining.
211
- func (enc * Encode ) initResponseWriter (rw * responseWriter , encodingName string , wrappedRW http.ResponseWriter ) * responseWriter {
211
+ func (enc * Encode ) initResponseWriter (rw * responseWriter , encodingName string , wrappedRW http.ResponseWriter , isConnect bool ) * responseWriter {
212
212
if rww , ok := wrappedRW .(* caddyhttp.ResponseWriterWrapper ); ok {
213
213
rw .ResponseWriter = rww
214
214
} else {
215
215
rw .ResponseWriter = & caddyhttp.ResponseWriterWrapper {ResponseWriter : wrappedRW }
216
216
}
217
217
rw .encodingName = encodingName
218
218
rw .config = enc
219
+ rw .isConnect = isConnect
219
220
220
221
return rw
221
222
}
@@ -230,6 +231,7 @@ type responseWriter struct {
230
231
config * Encode
231
232
statusCode int
232
233
wroteHeader bool
234
+ isConnect bool
233
235
}
234
236
235
237
// WriteHeader stores the status to write when the time comes
@@ -245,6 +247,14 @@ func (rw *responseWriter) WriteHeader(status int) {
245
247
rw .Header ().Add ("Vary" , "Accept-Encoding" )
246
248
}
247
249
250
+ // write status immediately if status is 2xx and the request is CONNECT
251
+ // since it means the response is successful.
252
+ // see: https://github.com/caddyserver/caddy/issues/6733#issuecomment-2525058845
253
+ if rw .isConnect && 200 <= status && status <= 299 {
254
+ rw .ResponseWriter .WriteHeader (status )
255
+ rw .wroteHeader = true
256
+ }
257
+
248
258
// write status immediately when status code is informational
249
259
// see: https://caddy.community/t/disappear-103-early-hints-response-with-encode-enable-caddy-v2-7-6/23081/5
250
260
if 100 <= status && status <= 199 {
@@ -260,6 +270,12 @@ func (enc *Encode) Match(rw *responseWriter) bool {
260
270
// FlushError is an alternative Flush returning an error. It delays the actual Flush of the underlying
261
271
// ResponseWriterWrapper until headers were written.
262
272
func (rw * responseWriter ) FlushError () error {
273
+ // WriteHeader wasn't called and is a CONNECT request, treat it as a success.
274
+ // otherwise, wait until header is written.
275
+ if rw .isConnect && ! rw .wroteHeader && rw .statusCode == 0 {
276
+ rw .WriteHeader (http .StatusOK )
277
+ }
278
+
263
279
if ! rw .wroteHeader {
264
280
// flushing the underlying ResponseWriter will write header and status code,
265
281
// but we need to delay that until we can determine if we must encode and
@@ -288,6 +304,12 @@ func (rw *responseWriter) Write(p []byte) (int, error) {
288
304
return 0 , nil
289
305
}
290
306
307
+ // WriteHeader wasn't called and is a CONNECT request, treat it as a success.
308
+ // otherwise, determine if the response should be compressed.
309
+ if rw .isConnect && ! rw .wroteHeader && rw .statusCode == 0 {
310
+ rw .WriteHeader (http .StatusOK )
311
+ }
312
+
291
313
// sniff content-type and determine content-length
292
314
if ! rw .wroteHeader && rw .config .MinLength > 0 {
293
315
var gtMinLength bool
0 commit comments