@@ -1124,36 +1124,49 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
11241124 }
11251125 }
11261126
1127+ handleResponseHeaders := func () (* http.Response , error ) {
1128+ res := cs .res
1129+ if res .StatusCode > 299 {
1130+ // On error or status code 3xx, 4xx, 5xx, etc abort any
1131+ // ongoing write, assuming that the server doesn't care
1132+ // about our request body. If the server replied with 1xx or
1133+ // 2xx, however, then assume the server DOES potentially
1134+ // want our body (e.g. full-duplex streaming:
1135+ // golang.org/issue/13444). If it turns out the server
1136+ // doesn't, they'll RST_STREAM us soon enough. This is a
1137+ // heuristic to avoid adding knobs to Transport. Hopefully
1138+ // we can keep it.
1139+ cs .abortRequestBodyWrite ()
1140+ }
1141+ res .Request = req
1142+ res .TLS = cc .tlsState
1143+ if res .Body == noBody && actualContentLength (req ) == 0 {
1144+ // If there isn't a request or response body still being
1145+ // written, then wait for the stream to be closed before
1146+ // RoundTrip returns.
1147+ if err := waitDone (); err != nil {
1148+ return nil , err
1149+ }
1150+ }
1151+ return res , nil
1152+ }
1153+
11271154 for {
11281155 select {
11291156 case <- cs .respHeaderRecv :
1130- res := cs .res
1131- if res .StatusCode > 299 {
1132- // On error or status code 3xx, 4xx, 5xx, etc abort any
1133- // ongoing write, assuming that the server doesn't care
1134- // about our request body. If the server replied with 1xx or
1135- // 2xx, however, then assume the server DOES potentially
1136- // want our body (e.g. full-duplex streaming:
1137- // golang.org/issue/13444). If it turns out the server
1138- // doesn't, they'll RST_STREAM us soon enough. This is a
1139- // heuristic to avoid adding knobs to Transport. Hopefully
1140- // we can keep it.
1141- cs .abortRequestBodyWrite ()
1142- }
1143- res .Request = req
1144- res .TLS = cc .tlsState
1145- if res .Body == noBody && actualContentLength (req ) == 0 {
1146- // If there isn't a request or response body still being
1147- // written, then wait for the stream to be closed before
1148- // RoundTrip returns.
1149- if err := waitDone (); err != nil {
1150- return nil , err
1151- }
1152- }
1153- return res , nil
1157+ return handleResponseHeaders ()
11541158 case <- cs .abort :
1155- waitDone ()
1156- return nil , cs .abortErr
1159+ select {
1160+ case <- cs .respHeaderRecv :
1161+ // If both cs.respHeaderRecv and cs.abort are signaling,
1162+ // pick respHeaderRecv. The server probably wrote the
1163+ // response and immediately reset the stream.
1164+ // golang.org/issue/49645
1165+ return handleResponseHeaders ()
1166+ default :
1167+ waitDone ()
1168+ return nil , cs .abortErr
1169+ }
11571170 case <- ctx .Done ():
11581171 err := ctx .Err ()
11591172 cs .abortStream (err )
0 commit comments