@@ -117,34 +117,40 @@ func HttpHandler(svc Service) http.Handler {
117117 }
118118 rsp := svc (req )
119119
120- // If the connection was hijacked, we should not attempt to write anything out
121120 if rsp .hijacked {
122121 return
123122 }
124123
124+ // If the connection has been hijacked, the hijacker is responsible for any
125+ // resource cleanup (as per http.Hijacker)
126+ if rsp .Body != nil {
127+ defer rsp .Body .Close ()
128+ }
129+
125130 rwHeader := rw .Header ()
126131 for k , v := range rsp .Header {
127132 rwHeader [k ] = v
128133 }
129134 rw .WriteHeader (rsp .StatusCode )
130- if rsp .Body != nil && bodyAllowedForStatus (rsp .StatusCode ) {
131- defer rsp .Body .Close ()
132- buf := * httpChunkBufPool .Get ().(* []byte )
133- defer httpChunkBufPool .Put (& buf )
134- if isStreamingRsp (rsp ) {
135- // Streaming responses use copyChunked(), which takes care of flushing transparently
136- if _ , err := copyChunked (rw , rsp .Body , buf ); err != nil {
137- slog .Log (slog .Eventf (copyErrSeverity (err ), req , "Couldn't send streaming response body" , err ))
138-
139- // Prevent the client from accidentally consuming a truncated stream by aborting the response.
140- // The official way of interrupting an HTTP reply mid-stream is panic(http.ErrAbortHandler), which
141- // works for both HTTP/1.1 and HTTP.2. https://github.com/golang/go/issues/17790
142- panic (http .ErrAbortHandler )
143- }
144- } else {
145- if _ , err := io .CopyBuffer (rw , rsp .Body , buf ); err != nil {
146- slog .Log (slog .Eventf (copyErrSeverity (err ), req , "Couldn't send response body" , err ))
147- }
135+ if rsp .Body == nil || ! bodyAllowedForStatus (rsp .StatusCode ) {
136+ return
137+ }
138+
139+ buf := * httpChunkBufPool .Get ().(* []byte )
140+ defer httpChunkBufPool .Put (& buf )
141+ if isStreamingRsp (rsp ) {
142+ // Streaming responses use copyChunked(), which takes care of flushing transparently
143+ if _ , err := copyChunked (rw , rsp .Body , buf ); err != nil {
144+ slog .Log (slog .Eventf (copyErrSeverity (err ), req , "Couldn't send streaming response body" , err ))
145+
146+ // Prevent the client from accidentally consuming a truncated stream by aborting the response.
147+ // The official way of interrupting an HTTP reply mid-stream is panic(http.ErrAbortHandler), which
148+ // works for both HTTP/1.1 and HTTP.2. https://github.com/golang/go/issues/17790
149+ panic (http .ErrAbortHandler )
150+ }
151+ } else {
152+ if _ , err := io .CopyBuffer (rw , rsp .Body , buf ); err != nil {
153+ slog .Log (slog .Eventf (copyErrSeverity (err ), req , "Couldn't send response body" , err ))
148154 }
149155 }
150156 })
0 commit comments