mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-25 14:46:04 +03:00
Fix connection reuse in splithttp HTTP/1.1 (#3485)
This commit is contained in:
parent
079d0bd8a9
commit
c6a57b2cc1
@ -1,6 +1,7 @@
|
||||
package splithttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
gotls "crypto/tls"
|
||||
"io"
|
||||
@ -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 {
|
||||
@ -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")
|
||||
@ -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)
|
||||
}
|
||||
}()
|
||||
|
Loading…
Reference in New Issue
Block a user