mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
Make http outbound 0-rtt
This commit is contained in:
parent
e0bbf474ae
commit
d05ddc8f78
@ -16,6 +16,7 @@ import (
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/bytespool"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/retry"
|
||||
@ -80,12 +81,21 @@ 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)
|
||||
|
||||
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||
server := c.serverPicker.PickServer()
|
||||
dest := server.Destination()
|
||||
user = server.PickUser()
|
||||
|
||||
netConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer)
|
||||
netConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, firstPayload)
|
||||
if netConn != nil {
|
||||
conn = internet.Connection(netConn)
|
||||
}
|
||||
@ -126,11 +136,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
||||
}
|
||||
|
||||
// setUpHTTPTunnel will create a socket tunnel via HTTP CONNECT method
|
||||
func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, user *protocol.MemoryUser, dialer internet.Dialer) (net.Conn, error) {
|
||||
func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, user *protocol.MemoryUser, dialer internet.Dialer, firstPayload []byte) (net.Conn, error) {
|
||||
req := &http.Request{
|
||||
Method: http.MethodConnect,
|
||||
URL: &url.URL{Host: target},
|
||||
Header: http.Header{"Proxy-Connection": []string{"Keep-Alive"}},
|
||||
Header: make(http.Header),
|
||||
Host: target,
|
||||
}
|
||||
|
||||
@ -141,12 +151,19 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
|
||||
}
|
||||
|
||||
connectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {
|
||||
req.Header.Set("Proxy-Connection", "Keep-Alive")
|
||||
|
||||
err := req.Write(rawConn)
|
||||
if err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := rawConn.Write(firstPayload); err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(rawConn), req)
|
||||
if err != nil {
|
||||
rawConn.Close()
|
||||
@ -164,12 +181,27 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
|
||||
pr, pw := io.Pipe()
|
||||
req.Body = pr
|
||||
|
||||
var pErr error
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
_, pErr = pw.Write(firstPayload)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
resp, err := h2clientConn.RoundTrip(req)
|
||||
if err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
if pErr != nil {
|
||||
rawConn.Close()
|
||||
return nil, pErr
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
rawConn.Close()
|
||||
return nil, newError("Proxy responded with non 200 code: " + resp.Status)
|
||||
|
Loading…
Reference in New Issue
Block a user