Skip to content

Commit

Permalink
Fix connection reuse in splithttp HTTP/1.1 (#3485)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmmray committed Jul 1, 2024
1 parent 079d0bd commit c6a57b2
Showing 1 changed file with 23 additions and 10 deletions.
33 changes: 23 additions & 10 deletions transport/internet/splithttp/dialer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package splithttp

import (
"bytes"
"context"
gotls "crypto/tls"
"io"
Expand Down Expand Up @@ -263,6 +264,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
return
}

req.ContentLength = int64(chunk.Len())
req.Header = transportConfiguration.GetRequestHeader()

if httpClient.isH2 {
Expand All @@ -280,11 +282,19 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
return
}
} else {
var err error
var uploadConn any
for i := 0; i < 5; i++ {

// stringify the entire HTTP/1.1 request so it can be
// safely retried. if instead req.Write is called multiple
// times, the body is already drained after the first
// request
requestBytes := new(bytes.Buffer)
common.Must(req.Write(requestBytes))

for {
uploadConn = httpClient.uploadRawPool.Get()
if uploadConn == nil {
newConnection := uploadConn == nil
if newConnection {
uploadConn, err = httpClient.dialUploadConn(context.WithoutCancel(ctx))
if err != nil {
errors.LogInfoInner(ctx, err, "failed to connect upload")
Expand All @@ -293,18 +303,21 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
}
}

err = req.Write(uploadConn.(net.Conn))
_, err = uploadConn.(net.Conn).Write(requestBytes.Bytes())

// if the write failed, we try another connection from
// the pool, until the write on a new connection fails.
// failed writes to a pooled connection are normal when
// the connection has been closed in the meantime.
if err == nil {
break
} else if newConnection {
errors.LogInfoInner(ctx, err, "failed to send upload")
uploadPipeReader.Interrupt()
return
}
}

if err != nil {
errors.LogInfoInner(ctx, err, "failed to send upload")
uploadPipeReader.Interrupt()
return
}

httpClient.uploadRawPool.Put(uploadConn)
}
}()
Expand Down

0 comments on commit c6a57b2

Please sign in to comment.