@@ -1033,36 +1033,49 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
1033
1033
}
1034
1034
}
1035
1035
1036
+ handleResponseHeaders := func () (* http.Response , error ) {
1037
+ res := cs .res
1038
+ if res .StatusCode > 299 {
1039
+ // On error or status code 3xx, 4xx, 5xx, etc abort any
1040
+ // ongoing write, assuming that the server doesn't care
1041
+ // about our request body. If the server replied with 1xx or
1042
+ // 2xx, however, then assume the server DOES potentially
1043
+ // want our body (e.g. full-duplex streaming:
1044
+ // golang.org/issue/13444). If it turns out the server
1045
+ // doesn't, they'll RST_STREAM us soon enough. This is a
1046
+ // heuristic to avoid adding knobs to Transport. Hopefully
1047
+ // we can keep it.
1048
+ cs .abortRequestBodyWrite ()
1049
+ }
1050
+ res .Request = req
1051
+ res .TLS = cc .tlsState
1052
+ if res .Body == noBody && actualContentLength (req ) == 0 {
1053
+ // If there isn't a request or response body still being
1054
+ // written, then wait for the stream to be closed before
1055
+ // RoundTrip returns.
1056
+ if err := waitDone (); err != nil {
1057
+ return nil , err
1058
+ }
1059
+ }
1060
+ return res , nil
1061
+ }
1062
+
1036
1063
for {
1037
1064
select {
1038
1065
case <- cs .respHeaderRecv :
1039
- res := cs .res
1040
- if res .StatusCode > 299 {
1041
- // On error or status code 3xx, 4xx, 5xx, etc abort any
1042
- // ongoing write, assuming that the server doesn't care
1043
- // about our request body. If the server replied with 1xx or
1044
- // 2xx, however, then assume the server DOES potentially
1045
- // want our body (e.g. full-duplex streaming:
1046
- // golang.org/issue/13444). If it turns out the server
1047
- // doesn't, they'll RST_STREAM us soon enough. This is a
1048
- // heuristic to avoid adding knobs to Transport. Hopefully
1049
- // we can keep it.
1050
- cs .abortRequestBodyWrite ()
1051
- }
1052
- res .Request = req
1053
- res .TLS = cc .tlsState
1054
- if res .Body == noBody && actualContentLength (req ) == 0 {
1055
- // If there isn't a request or response body still being
1056
- // written, then wait for the stream to be closed before
1057
- // RoundTrip returns.
1058
- if err := waitDone (); err != nil {
1059
- return nil , err
1060
- }
1061
- }
1062
- return res , nil
1066
+ return handleResponseHeaders ()
1063
1067
case <- cs .abort :
1064
- waitDone ()
1065
- return nil , cs .abortErr
1068
+ select {
1069
+ case <- cs .respHeaderRecv :
1070
+ // If both cs.respHeaderRecv and cs.abort are signaling,
1071
+ // pick respHeaderRecv. The server probably wrote the
1072
+ // response and immediately reset the stream.
1073
+ // golang.org/issue/49645
1074
+ return handleResponseHeaders ()
1075
+ default :
1076
+ waitDone ()
1077
+ return nil , cs .abortErr
1078
+ }
1066
1079
case <- ctx .Done ():
1067
1080
err := ctx .Err ()
1068
1081
cs .abortStream (err )
0 commit comments