@@ -288,26 +288,27 @@ func (s *Server) newHTTPServerConn(r *http.Request, w http.ResponseWriter) Serve
288288// For error responses, it sets Content-Length and flushes to ensure the response
289289// is fully written before any HTTP server write timeout occurs.
290290func httpWriteResult (w http.ResponseWriter , data []byte , isError bool ) error {
291+ w .Header ().Set ("content-length" , strconv .Itoa (len (data )))
292+
291293 if ! isError {
294+ // Normal path, just send the response and let the HTTP server decide
295+ // when to flush.
292296 _ , err := w .Write (data )
293297 return err
294298 }
295299
296300 // It's an error response and requires special treatment.
297301 //
298302 // In case of a timeout error, the response must be written before the HTTP
299- // server's write timeout occurs. So we need to flush the response. The
300- // Content-Length header also needs to be set to ensure the client knows
301- // when it has the full response.
302- w .Header ().Set ("content-length" , strconv .Itoa (len (data )))
303-
303+ // server's write timeout occurs. So we need to flush the response.
304+ //
304305 // If this request is wrapped in a handler that might remove Content-Length (such
305306 // as the automatic gzip we do in package node), we need to ensure the HTTP server
306307 // doesn't perform chunked encoding. In case WriteTimeout is reached, the chunked
307308 // encoding might not be finished correctly, and some clients do not like it when
308- // the final chunk is missing.
309+ // the final chunk is missing. To do this, we set TE = identity, which is a signal
310+ // recognized by outer handlers to avoid compression.
309311 w .Header ().Set ("transfer-encoding" , "identity" )
310-
311312 _ , err := w .Write (data )
312313 if f , ok := w .(http.Flusher ); ok {
313314 f .Flush ()
0 commit comments