Skip to content

Commit

Permalink
proxy/http: Avoid getting stuck when using server-first protocols
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lrh2000 committed Jan 3, 2022
1 parent d13894e commit d345804
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions proxy/http/client.go
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"sync"
"time"

"golang.org/x/net/http2"

Expand Down Expand Up @@ -79,14 +80,27 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
var user *protocol.MemoryUser
var conn internet.Connection

mbuf, _ := link.Reader.ReadMultiBuffer()
len := mbuf.Len()
firstPayload := bytespool.Alloc(len)
mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
firstPayload = firstPayload[:len]

buf.ReleaseMulti(mbuf)
defer bytespool.Free(firstPayload)
var firstPayload []byte

if reader, ok := link.Reader.(buf.TimeoutReader); ok {
// 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)
} else {
firstPayload = make([]byte, 0)
}
} else {
firstPayload = make([]byte, 0)
}

if err := retry.ExponentialBackoff(5, 100).On(func() error {
server := c.serverPicker.PickServer()
Expand Down

0 comments on commit d345804

Please sign in to comment.