mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-22 12:49:20 +02: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
|
package splithttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
gotls "crypto/tls"
|
gotls "crypto/tls"
|
||||||
"io"
|
"io"
|
||||||
|
@ -263,6 +264,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.ContentLength = int64(chunk.Len())
|
||||||
req.Header = transportConfiguration.GetRequestHeader()
|
req.Header = transportConfiguration.GetRequestHeader()
|
||||||
|
|
||||||
if httpClient.isH2 {
|
if httpClient.isH2 {
|
||||||
|
@ -280,11 +282,19 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var err error
|
|
||||||
var uploadConn any
|
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()
|
uploadConn = httpClient.uploadRawPool.Get()
|
||||||
if uploadConn == nil {
|
newConnection := uploadConn == nil
|
||||||
|
if newConnection {
|
||||||
uploadConn, err = httpClient.dialUploadConn(context.WithoutCancel(ctx))
|
uploadConn, err = httpClient.dialUploadConn(context.WithoutCancel(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors.LogInfoInner(ctx, err, "failed to connect upload")
|
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 {
|
if err == nil {
|
||||||
break
|
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)
|
httpClient.uploadRawPool.Put(uploadConn)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in New Issue