1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-30 05:56:54 -05:00

proxy/http: Avoid getting stuck when using server-first protocols

PR #99 reduces an extra RTT when setting up the CONNECT tunnel
via http proxy, however, server-first protocols (such as MySQL)
will be unusable as v2ray keeps to wait for the client request.
This commit solves the problem by limiting the maximum waiting
time to 50 ms.
This commit is contained in:
lrh2000 2022-01-03 22:53:15 +08:00 committed by Shelikhoo
parent b4069f743c
commit 17d85263e2
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316

View File

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"sync" "sync"
"time"
"golang.org/x/net/http2" "golang.org/x/net/http2"
@ -79,14 +80,23 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
var user *protocol.MemoryUser var user *protocol.MemoryUser
var conn internet.Connection var conn internet.Connection
mbuf, _ := link.Reader.ReadMultiBuffer() var firstPayload []byte
len := mbuf.Len()
firstPayload := bytespool.Alloc(len)
mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
firstPayload = firstPayload[:len]
buf.ReleaseMulti(mbuf) if reader, ok := link.Reader.(buf.TimeoutReader); ok {
defer bytespool.Free(firstPayload) // 0-RTT optimization for HTTP/2: If the payload comes within 50 ms, it can be
// transmitted together. Note we should not get stuck here, as the payload may
// not exist (considering to access MySQL database via a HTTP proxy, where the
// server sends hello to the client first).
if mbuf, _ := reader.ReadMultiBufferTimeout(50 * time.Millisecond); mbuf != nil {
mlen := mbuf.Len()
firstPayload = bytespool.Alloc(mlen)
mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
firstPayload = firstPayload[:mlen]
buf.ReleaseMulti(mbuf)
defer bytespool.Free(firstPayload)
}
}
if err := retry.ExponentialBackoff(5, 100).On(func() error { if err := retry.ExponentialBackoff(5, 100).On(func() error {
server := c.serverPicker.PickServer() server := c.serverPicker.PickServer()