@@ -156,7 +156,7 @@ func (enc *Encode) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyh
156156 if _ , ok := enc .writerPools [encName ]; ! ok {
157157 continue // encoding not offered
158158 }
159- w = enc .openResponseWriter (encName , w )
159+ w = enc .openResponseWriter (encName , w , r . Method == http . MethodConnect )
160160 defer w .(* responseWriter ).Close ()
161161
162162 // 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 {
201201// openResponseWriter creates a new response writer that may (or may not)
202202// encode the response with encodingName. The returned response writer MUST
203203// 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 {
205205 var rw responseWriter
206- return enc .initResponseWriter (& rw , encodingName , w )
206+ return enc .initResponseWriter (& rw , encodingName , w , isConnect )
207207}
208208
209209// initResponseWriter initializes the responseWriter instance
210210// 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 {
212212 if rww , ok := wrappedRW .(* caddyhttp.ResponseWriterWrapper ); ok {
213213 rw .ResponseWriter = rww
214214 } else {
215215 rw .ResponseWriter = & caddyhttp.ResponseWriterWrapper {ResponseWriter : wrappedRW }
216216 }
217217 rw .encodingName = encodingName
218218 rw .config = enc
219+ rw .isConnect = isConnect
219220
220221 return rw
221222}
@@ -230,6 +231,7 @@ type responseWriter struct {
230231 config * Encode
231232 statusCode int
232233 wroteHeader bool
234+ isConnect bool
233235}
234236
235237// WriteHeader stores the status to write when the time comes
@@ -245,6 +247,14 @@ func (rw *responseWriter) WriteHeader(status int) {
245247 rw .Header ().Add ("Vary" , "Accept-Encoding" )
246248 }
247249
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+
248258 // write status immediately when status code is informational
249259 // see: https://caddy.community/t/disappear-103-early-hints-response-with-encode-enable-caddy-v2-7-6/23081/5
250260 if 100 <= status && status <= 199 {
@@ -260,6 +270,12 @@ func (enc *Encode) Match(rw *responseWriter) bool {
260270// FlushError is an alternative Flush returning an error. It delays the actual Flush of the underlying
261271// ResponseWriterWrapper until headers were written.
262272func (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+
263279 if ! rw .wroteHeader {
264280 // flushing the underlying ResponseWriter will write header and status code,
265281 // 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) {
288304 return 0 , nil
289305 }
290306
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+
291313 // sniff content-type and determine content-length
292314 if ! rw .wroteHeader && rw .config .MinLength > 0 {
293315 var gtMinLength bool
0 commit comments