mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
Add v2ray httpupgrade fast open support
This commit is contained in:
parent
e80f5ac9dd
commit
5341365bb8
@ -95,4 +95,5 @@ type V2RayHTTPUpgradeOptions struct {
|
|||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Headers HTTPHeader `json:"headers,omitempty"`
|
Headers HTTPHeader `json:"headers,omitempty"`
|
||||||
|
FastOpen bool `json:"fast_open,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,15 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/tls"
|
"github.com/sagernet/sing-box/common/tls"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
@ -28,6 +32,7 @@ type Client struct {
|
|||||||
requestURL url.URL
|
requestURL url.URL
|
||||||
headers http.Header
|
headers http.Header
|
||||||
host string
|
host string
|
||||||
|
fastOpen bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPUpgradeOptions, tlsConfig tls.Config) (*Client, error) {
|
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPUpgradeOptions, tlsConfig tls.Config) (*Client, error) {
|
||||||
@ -70,6 +75,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
|||||||
requestURL: requestURL,
|
requestURL: requestURL,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
host: host,
|
host: host,
|
||||||
|
fastOpen: options.FastOpen,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +102,17 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if c.fastOpen {
|
||||||
|
return &EarlyHTTPUpgradeConn{
|
||||||
|
Conn: conn,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return readResponse(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readResponse(conn net.Conn) (net.Conn, error) {
|
||||||
bufReader := std_bufio.NewReader(conn)
|
bufReader := std_bufio.NewReader(conn)
|
||||||
response, err := http.ReadResponse(bufReader, request)
|
response, err := http.ReadResponse(bufReader, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -116,3 +131,53 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EarlyHTTPUpgradeConn struct {
|
||||||
|
net.Conn
|
||||||
|
once sync.Once
|
||||||
|
err error
|
||||||
|
created atomic.Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) Read(b []byte) (int, error) {
|
||||||
|
c.once.Do(func() {
|
||||||
|
var newConn net.Conn
|
||||||
|
newConn, c.err = readResponse(c.Conn)
|
||||||
|
if c.err == nil {
|
||||||
|
c.Conn = newConn
|
||||||
|
c.created.Store(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if c.err != nil {
|
||||||
|
return 0, c.err
|
||||||
|
}
|
||||||
|
return c.Conn.Read(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) Upstream() any {
|
||||||
|
return c.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) ReaderReplaceable() bool {
|
||||||
|
return c.created.Load()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) WriterReplaceable() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) SetDeadline(time.Time) error {
|
||||||
|
return os.ErrInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) SetReadDeadline(time.Time) error {
|
||||||
|
return os.ErrInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) SetWriteDeadline(time.Time) error {
|
||||||
|
return os.ErrInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EarlyHTTPUpgradeConn) NeedAdditionalReadDeadline() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user