diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 5fe3e6ebb49..e41b20a15ba 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -606,6 +606,9 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { } else if !pconn.shouldRetryRequest(req, err) { // Issue 16465: return underlying net.Conn.Read error from peek, // as we've historically done. + if e, ok := err.(nothingWrittenError); ok { + err = e.error + } if e, ok := err.(transportReadFromServerError); ok { err = e.err } @@ -2032,6 +2035,9 @@ func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritte } if _, ok := err.(transportReadFromServerError); ok { + if pc.nwrite == startBytesWritten { + return nothingWrittenError{err} + } // Don't decorate return err } diff --git a/src/net/http/transport_internal_test.go b/src/net/http/transport_internal_test.go index 1cce27235df..2ed637e9f03 100644 --- a/src/net/http/transport_internal_test.go +++ b/src/net/http/transport_internal_test.go @@ -52,8 +52,8 @@ func TestTransportPersistConnReadLoopEOF(t *testing.T) { conn.Close() // simulate the server hanging up on the client _, err = pc.roundTrip(treq) - if !isTransportReadFromServerError(err) && err != errServerClosedIdle { - t.Errorf("roundTrip = %#v, %v; want errServerClosedIdle or transportReadFromServerError", err, err) + if !isNothingWrittenError(err) && !isTransportReadFromServerError(err) && err != errServerClosedIdle { + t.Errorf("roundTrip = %#v, %v; want errServerClosedIdle, transportReadFromServerError, or nothingWrittenError", err, err) } <-pc.closech @@ -63,6 +63,11 @@ func TestTransportPersistConnReadLoopEOF(t *testing.T) { } } +func isNothingWrittenError(err error) bool { + _, ok := err.(nothingWrittenError) + return ok +} + func isTransportReadFromServerError(err error) bool { _, ok := err.(transportReadFromServerError) return ok