mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-25 18:11:28 +00:00
Fix v2ray HTTP/1.1 transport compatibility
This commit is contained in:
parent
05bb1b88c3
commit
46c318c6fe
|
@ -61,19 +61,19 @@ func (o *V2RayTransportOptions) UnmarshalJSON(bytes []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayHTTPOptions struct {
|
type V2RayHTTPOptions struct {
|
||||||
Host Listable[string] `json:"host,omitempty"`
|
Host Listable[string] `json:"host,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Headers map[string]string `json:"headers,omitempty"`
|
Headers map[string]Listable[string] `json:"headers,omitempty"`
|
||||||
IdleTimeout Duration `json:"idle_timeout,omitempty"`
|
IdleTimeout Duration `json:"idle_timeout,omitempty"`
|
||||||
PingTimeout Duration `json:"ping_timeout,omitempty"`
|
PingTimeout Duration `json:"ping_timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayWebsocketOptions struct {
|
type V2RayWebsocketOptions struct {
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Headers map[string]string `json:"headers,omitempty"`
|
Headers map[string]Listable[string] `json:"headers,omitempty"`
|
||||||
MaxEarlyData uint32 `json:"max_early_data,omitempty"`
|
MaxEarlyData uint32 `json:"max_early_data,omitempty"`
|
||||||
EarlyDataHeaderName string `json:"early_data_header_name,omitempty"`
|
EarlyDataHeaderName string `json:"early_data_header_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayQUICOptions struct{}
|
type V2RayQUICOptions struct{}
|
||||||
|
|
|
@ -37,7 +37,10 @@ func startInstance(t *testing.T, options option.Options) *box.Box {
|
||||||
var instance *box.Box
|
var instance *box.Box
|
||||||
var err error
|
var err error
|
||||||
for retry := 0; retry < 3; retry++ {
|
for retry := 0; retry < 3; retry++ {
|
||||||
instance, err = box.New(ctx, options, nil)
|
instance, err = box.New(box.Options{
|
||||||
|
Context: ctx,
|
||||||
|
Options: options,
|
||||||
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = instance.Start()
|
err = instance.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
26
test/go.mod
26
test/go.mod
|
@ -10,17 +10,17 @@ require (
|
||||||
github.com/docker/docker v20.10.18+incompatible
|
github.com/docker/docker v20.10.18+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible
|
github.com/gofrs/uuid v4.4.0+incompatible
|
||||||
github.com/sagernet/sing v0.2.1-0.20230318094614-4bbf5f2c3046
|
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9
|
github.com/sagernet/sing-shadowsocks v0.2.0
|
||||||
github.com/spyzhov/ajson v0.7.1
|
github.com/spyzhov/ajson v0.7.1
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.2
|
||||||
go.uber.org/goleak v1.2.0
|
go.uber.org/goleak v1.2.0
|
||||||
golang.org/x/net v0.8.0
|
golang.org/x/net v0.9.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
berty.tech/go-libtor v1.0.385 // indirect
|
berty.tech/go-libtor v1.0.385 // indirect
|
||||||
github.com/Dreamacro/clash v1.13.0 // indirect
|
github.com/Dreamacro/clash v1.14.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||||
github.com/ajg/form v1.5.1 // indirect
|
github.com/ajg/form v1.5.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
@ -42,14 +42,14 @@ require (
|
||||||
github.com/google/btree v1.0.1 // indirect
|
github.com/google/btree v1.0.1 // indirect
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20230307103557-e252950ab961 // indirect
|
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e // indirect
|
||||||
github.com/josharian/native v1.1.0 // indirect
|
github.com/josharian/native v1.1.0 // indirect
|
||||||
github.com/klauspost/compress v1.15.15 // indirect
|
github.com/klauspost/compress v1.15.15 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
|
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
|
||||||
github.com/libdns/libdns v0.2.1 // indirect
|
github.com/libdns/libdns v0.2.1 // indirect
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||||
github.com/mholt/acmez v1.1.0 // indirect
|
github.com/mholt/acmez v1.1.0 // indirect
|
||||||
github.com/miekg/dns v1.1.52 // indirect
|
github.com/miekg/dns v1.1.53 // indirect
|
||||||
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c // indirect
|
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
||||||
|
@ -69,10 +69,10 @@ require (
|
||||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
|
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||||
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect
|
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect
|
||||||
github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8 // indirect
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
||||||
github.com/sagernet/sing-dns v0.1.4 // indirect
|
github.com/sagernet/sing-dns v0.1.5-0.20230407055526-2a27418e7855 // indirect
|
||||||
github.com/sagernet/sing-shadowtls v0.1.0 // indirect
|
github.com/sagernet/sing-shadowtls v0.1.0 // indirect
|
||||||
github.com/sagernet/sing-tun v0.1.3-0.20230315134716-fe89bbded22d // indirect
|
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab // indirect
|
||||||
github.com/sagernet/sing-vmess v0.1.3 // indirect
|
github.com/sagernet/sing-vmess v0.1.3 // indirect
|
||||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
|
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
|
||||||
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect
|
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect
|
||||||
|
@ -88,14 +88,14 @@ require (
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect
|
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect
|
||||||
golang.org/x/crypto v0.7.0 // indirect
|
golang.org/x/crypto v0.7.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||||
golang.org/x/mod v0.8.0 // indirect
|
golang.org/x/mod v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.6.0 // indirect
|
golang.org/x/sys v0.7.0 // indirect
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||||
golang.org/x/tools v0.6.0 // indirect
|
golang.org/x/tools v0.6.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
|
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
|
||||||
google.golang.org/grpc v1.53.0 // indirect
|
google.golang.org/grpc v1.54.0 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gotest.tools/v3 v3.4.0 // indirect
|
gotest.tools/v3 v3.4.0 // indirect
|
||||||
|
|
54
test/go.sum
54
test/go.sum
|
@ -1,8 +1,8 @@
|
||||||
berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
|
berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
|
||||||
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
|
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
github.com/Dreamacro/clash v1.13.0 h1:gF0E0TluE1LCmuhhg0/bjqABYDmSnXkUjXjRhZxyrm8=
|
github.com/Dreamacro/clash v1.14.0 h1:ehJ/C/1m9LEjmME72WSE/Y2YqbR3Q54AbjqiRCvtyW4=
|
||||||
github.com/Dreamacro/clash v1.13.0/go.mod h1:hf0RkWPsQ0e8oS8WVJBIRocY/1ILYzQQg9zeMwd8LsM=
|
github.com/Dreamacro/clash v1.14.0/go.mod h1:ia2CU7V713H1QdCqMwOLK9U9V5Ay8X0voj3yQr2tk+I=
|
||||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
|
@ -61,8 +61,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
|
||||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20230307103557-e252950ab961 h1:x/YtdDlmypenG1te/FfH6LVM+3krhXk5CFV8VYNNX5M=
|
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e h1:8ChxkWKTVYg7LKBvYNLNRnlobgbPrzzossZUoST2T7o=
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20230307103557-e252950ab961/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI=
|
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI=
|
||||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
|
@ -80,8 +80,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||||
github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY=
|
github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY=
|
||||||
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs=
|
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs=
|
||||||
github.com/miekg/dns v1.1.52 h1:Bmlc/qsNNULOe6bpXcUTsuOajd0DzRHwup6D9k1An0c=
|
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
|
||||||
github.com/miekg/dns v1.1.52/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||||
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c h1:RC8WMpjonrBfyAh6VN/POIPtYD5tRAq0qMqCRjQNK+g=
|
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c h1:RC8WMpjonrBfyAh6VN/POIPtYD5tRAq0qMqCRjQNK+g=
|
||||||
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c/go.mod h1:9OcmHNQQUTbk4XCffrLgN1NEKc2mh5u++biHVrvHsSU=
|
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c/go.mod h1:9OcmHNQQUTbk4XCffrLgN1NEKc2mh5u++biHVrvHsSU=
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
|
@ -122,20 +122,20 @@ github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6E
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||||
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY=
|
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY=
|
||||||
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32/go.mod h1:QMCkxXAC3CvBgDZVIJp43NWTuwGBScCzMLVLynjERL8=
|
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32/go.mod h1:QMCkxXAC3CvBgDZVIJp43NWTuwGBScCzMLVLynjERL8=
|
||||||
github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8 h1:4M3+0/kqvJuTsimEORH0/vUYTpMDUETBH2zNUU38SUw=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||||
github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||||
github.com/sagernet/sing v0.2.1-0.20230318094614-4bbf5f2c3046 h1:/+ZWbxRvQmco9ES2qT5Eh/x/IiQRjAcUyRG/vQ4dpxc=
|
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2 h1:VjeHDxEgpB2fqK5G16yBvtLacibvg3h2MsIjal0UXH0=
|
||||||
github.com/sagernet/sing v0.2.1-0.20230318094614-4bbf5f2c3046/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
||||||
github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN+0=
|
github.com/sagernet/sing-dns v0.1.5-0.20230407055526-2a27418e7855 h1:a3W2X1n5C/oYGp/Dd26eoymME3iXN8TJq7LZtO2MSUY=
|
||||||
github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk=
|
github.com/sagernet/sing-dns v0.1.5-0.20230407055526-2a27418e7855/go.mod h1:69PNSHyEmXdjf6C+bXBOdr2GQnPeEyWjIzo/MV8gmz8=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0=
|
github.com/sagernet/sing-shadowsocks v0.2.0 h1:ILDWL7pwWfkPLEbviE/MyCgfjaBmJY/JVVY+5jhSb58=
|
||||||
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9/go.mod h1:f3mHTy5shnVM9l8UocMlJgC/1G/zdj5FuEuVXhDinGU=
|
github.com/sagernet/sing-shadowsocks v0.2.0/go.mod h1:ysYzszRLpNzJSorvlWRMuzU6Vchsp7sd52q+JNY4axw=
|
||||||
github.com/sagernet/sing-shadowtls v0.1.0 h1:05MYce8aR5xfKIn+y7xRFsdKhKt44QZTSEQW+lG5IWQ=
|
github.com/sagernet/sing-shadowtls v0.1.0 h1:05MYce8aR5xfKIn+y7xRFsdKhKt44QZTSEQW+lG5IWQ=
|
||||||
github.com/sagernet/sing-shadowtls v0.1.0/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
github.com/sagernet/sing-shadowtls v0.1.0/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
||||||
github.com/sagernet/sing-tun v0.1.3-0.20230315134716-fe89bbded22d h1:1gt4Hu2fHCrmL2NZYCNJ3nCgeczuhK09oCMni9mZmZk=
|
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab h1:a9oeWuPBuIZ70qMhIIH6RrYhp886xN9jJIwsuu4ZFUo=
|
||||||
github.com/sagernet/sing-tun v0.1.3-0.20230315134716-fe89bbded22d/go.mod h1:KnRkwaDHbb06zgeNPu0LQ8A+vA9myMxKEgHN1brCPHg=
|
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab/go.mod h1:4YxIDEkkCjGXDOTMPw1SXpLmCQUFAWuaQN250oo+928=
|
||||||
github.com/sagernet/sing-vmess v0.1.3 h1:q/+tsF46dvvapL6CpQBgPHJ6nQrDUZqEtLHCbsjO7iM=
|
github.com/sagernet/sing-vmess v0.1.3 h1:q/+tsF46dvvapL6CpQBgPHJ6nQrDUZqEtLHCbsjO7iM=
|
||||||
github.com/sagernet/sing-vmess v0.1.3/go.mod h1:GVXqAHwe9U21uS+Voh4YBIrADQyE4F9v0ayGSixSQAE=
|
github.com/sagernet/sing-vmess v0.1.3/go.mod h1:GVXqAHwe9U21uS+Voh4YBIrADQyE4F9v0ayGSixSQAE=
|
||||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||||
|
@ -191,8 +191,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
@ -206,8 +206,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -232,15 +232,15 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
@ -257,8 +257,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
|
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
|
||||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
|
||||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
|
|
|
@ -66,8 +66,8 @@ func newV2RayPlugin(pluginOpts Args, router adapter.Router, dialer N.Dialer, ser
|
||||||
transportOptions = option.V2RayTransportOptions{
|
transportOptions = option.V2RayTransportOptions{
|
||||||
Type: C.V2RayTransportTypeWebsocket,
|
Type: C.V2RayTransportTypeWebsocket,
|
||||||
WebsocketOptions: option.V2RayWebsocketOptions{
|
WebsocketOptions: option.V2RayWebsocketOptions{
|
||||||
Headers: map[string]string{
|
Headers: map[string]option.Listable[string]{
|
||||||
"Host": host,
|
"Host": []string{host},
|
||||||
},
|
},
|
||||||
Path: path,
|
Path: path,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package v2rayhttp
|
package v2rayhttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -81,8 +80,8 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||||
if !strings.HasPrefix(uri.Path, "/") {
|
if !strings.HasPrefix(uri.Path, "/") {
|
||||||
uri.Path = "/" + uri.Path
|
uri.Path = "/" + uri.Path
|
||||||
}
|
}
|
||||||
for key, value := range options.Headers {
|
for key, valueList := range options.Headers {
|
||||||
client.headers.Set(key, value)
|
client.headers[key] = valueList
|
||||||
}
|
}
|
||||||
client.url = &uri
|
client.url = &uri
|
||||||
return client
|
return client
|
||||||
|
@ -97,18 +96,16 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) dialHTTP(ctx context.Context) (net.Conn, error) {
|
func (c *Client) dialHTTP(ctx context.Context) (net.Conn, error) {
|
||||||
conn, err := c.dialer.DialContext(c.ctx, N.NetworkTCP, c.serverAddr)
|
conn, err := c.dialer.DialContext(ctx, N.NetworkTCP, c.serverAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
request := &http.Request{
|
request := &http.Request{
|
||||||
Method: c.method,
|
Method: c.method,
|
||||||
URL: c.url,
|
URL: c.url,
|
||||||
ProtoMajor: 1,
|
Header: c.headers.Clone(),
|
||||||
Proto: "HTTP/1.1",
|
|
||||||
Header: c.headers.Clone(),
|
|
||||||
}
|
}
|
||||||
request = request.WithContext(ctx)
|
|
||||||
switch hostLen := len(c.host); hostLen {
|
switch hostLen := len(c.host); hostLen {
|
||||||
case 0:
|
case 0:
|
||||||
request.Host = c.serverAddr.AddrString()
|
request.Host = c.serverAddr.AddrString()
|
||||||
|
@ -117,30 +114,17 @@ func (c *Client) dialHTTP(ctx context.Context) (net.Conn, error) {
|
||||||
default:
|
default:
|
||||||
request.Host = c.host[rand.Intn(hostLen)]
|
request.Host = c.host[rand.Intn(hostLen)]
|
||||||
}
|
}
|
||||||
err = request.Write(conn)
|
|
||||||
if err != nil {
|
return NewHTTP1Conn(conn, request), nil
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
reader := bufio.NewReader(conn)
|
|
||||||
response, err := http.ReadResponse(reader, request)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if response.StatusCode != 200 {
|
|
||||||
return nil, E.New("unexpected status: ", response.Status)
|
|
||||||
}
|
|
||||||
return conn, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) {
|
func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) {
|
||||||
pipeInReader, pipeInWriter := io.Pipe()
|
pipeInReader, pipeInWriter := io.Pipe()
|
||||||
request := &http.Request{
|
request := &http.Request{
|
||||||
Method: c.method,
|
Method: c.method,
|
||||||
Body: pipeInReader,
|
Body: pipeInReader,
|
||||||
URL: c.url,
|
URL: c.url,
|
||||||
ProtoMajor: 2,
|
Header: c.headers.Clone(),
|
||||||
Proto: "HTTP/2",
|
|
||||||
Header: c.headers.Clone(),
|
|
||||||
}
|
}
|
||||||
request = request.WithContext(ctx)
|
request = request.WithContext(ctx)
|
||||||
switch hostLen := len(c.host); hostLen {
|
switch hostLen := len(c.host); hostLen {
|
||||||
|
@ -152,8 +136,6 @@ func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) {
|
||||||
default:
|
default:
|
||||||
request.Host = c.host[rand.Intn(hostLen)]
|
request.Host = c.host[rand.Intn(hostLen)]
|
||||||
}
|
}
|
||||||
// Disable any compression method from server.
|
|
||||||
request.Header.Set("Accept-Encoding", "identity")
|
|
||||||
conn := newLateHTTPConn(pipeInWriter)
|
conn := newLateHTTPConn(pipeInWriter)
|
||||||
go func() {
|
go func() {
|
||||||
response, err := c.transport.RoundTrip(request)
|
response, err := c.transport.RoundTrip(request)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package v2rayhttp
|
package v2rayhttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
std_bufio "bufio"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -12,37 +14,146 @@ import (
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"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"
|
||||||
|
F "github.com/sagernet/sing/common/format"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HTTPConn struct {
|
type HTTPConn struct {
|
||||||
|
net.Conn
|
||||||
|
request *http.Request
|
||||||
|
requestWritten bool
|
||||||
|
responseRead bool
|
||||||
|
responseCache *buf.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHTTP1Conn(conn net.Conn, request *http.Request) *HTTPConn {
|
||||||
|
return &HTTPConn{
|
||||||
|
Conn: conn,
|
||||||
|
request: request,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) Read(b []byte) (n int, err error) {
|
||||||
|
if !c.responseRead {
|
||||||
|
reader := std_bufio.NewReader(c.Conn)
|
||||||
|
response, err := http.ReadResponse(reader, c.request)
|
||||||
|
if err != nil {
|
||||||
|
return 0, E.Cause(err, "read response")
|
||||||
|
}
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return 0, E.New("unexpected status: ", response.Status)
|
||||||
|
}
|
||||||
|
if cacheLen := reader.Buffered(); cacheLen > 0 {
|
||||||
|
c.responseCache = buf.NewSize(cacheLen)
|
||||||
|
_, err = c.responseCache.ReadFullFrom(reader, cacheLen)
|
||||||
|
if err != nil {
|
||||||
|
c.responseCache.Release()
|
||||||
|
return 0, E.Cause(err, "read cache")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.responseRead = true
|
||||||
|
}
|
||||||
|
if c.responseCache != nil {
|
||||||
|
n, err = c.responseCache.Read(b)
|
||||||
|
if err == io.EOF {
|
||||||
|
c.responseCache.Release()
|
||||||
|
c.responseCache = nil
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.Conn.Read(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) Write(b []byte) (int, error) {
|
||||||
|
if !c.requestWritten {
|
||||||
|
err := c.writeRequest(b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, E.Cause(err, "write request")
|
||||||
|
}
|
||||||
|
c.requestWritten = true
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
return c.Conn.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) writeRequest(payload []byte) error {
|
||||||
|
writer := bufio.NewBufferedWriter(c.Conn, buf.New())
|
||||||
|
const CRLF = "\r\n"
|
||||||
|
_, err := writer.Write([]byte(F.ToString(c.request.Method, " ", c.request.URL.RequestURI(), " HTTP/1.1", CRLF)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if c.request.Header.Get("Host") == "" {
|
||||||
|
c.request.Header.Set("Host", c.request.Host)
|
||||||
|
}
|
||||||
|
for key, value := range c.request.Header {
|
||||||
|
_, err = writer.Write([]byte(F.ToString(key, ": ", strings.Join(value, ", "), CRLF)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = writer.Write([]byte(CRLF))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = writer.Write(payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = writer.Fallthrough()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) ReaderReplaceable() bool {
|
||||||
|
return c.responseRead
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) WriterReplaceable() bool {
|
||||||
|
return c.requestWritten
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) NeedHandshake() bool {
|
||||||
|
return !c.requestWritten
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPConn) Upstream() any {
|
||||||
|
return c.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTP2Conn struct {
|
||||||
reader io.Reader
|
reader io.Reader
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
create chan struct{}
|
create chan struct{}
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPConn(reader io.Reader, writer io.Writer) HTTPConn {
|
func NewHTTPConn(reader io.Reader, writer io.Writer) HTTP2Conn {
|
||||||
return HTTPConn{
|
return HTTP2Conn{
|
||||||
reader: reader,
|
reader: reader,
|
||||||
writer: writer,
|
writer: writer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLateHTTPConn(writer io.Writer) *HTTPConn {
|
func newLateHTTPConn(writer io.Writer) *HTTP2Conn {
|
||||||
return &HTTPConn{
|
return &HTTP2Conn{
|
||||||
create: make(chan struct{}),
|
create: make(chan struct{}),
|
||||||
writer: writer,
|
writer: writer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) setup(reader io.Reader, err error) {
|
func (c *HTTP2Conn) setup(reader io.Reader, err error) {
|
||||||
c.reader = reader
|
c.reader = reader
|
||||||
c.err = err
|
c.err = err
|
||||||
close(c.create)
|
close(c.create)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) Read(b []byte) (n int, err error) {
|
func (c *HTTP2Conn) Read(b []byte) (n int, err error) {
|
||||||
if c.reader == nil {
|
if c.reader == nil {
|
||||||
<-c.create
|
<-c.create
|
||||||
if c.err != nil {
|
if c.err != nil {
|
||||||
|
@ -53,24 +164,24 @@ func (c *HTTPConn) Read(b []byte) (n int, err error) {
|
||||||
return n, baderror.WrapH2(err)
|
return n, baderror.WrapH2(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) Write(b []byte) (n int, err error) {
|
func (c *HTTP2Conn) Write(b []byte) (n int, err error) {
|
||||||
n, err = c.writer.Write(b)
|
n, err = c.writer.Write(b)
|
||||||
return n, baderror.WrapH2(err)
|
return n, baderror.WrapH2(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) Close() error {
|
func (c *HTTP2Conn) Close() error {
|
||||||
return common.Close(c.reader, c.writer)
|
return common.Close(c.reader, c.writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) LocalAddr() net.Addr {
|
func (c *HTTP2Conn) LocalAddr() net.Addr {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) RemoteAddr() net.Addr {
|
func (c *HTTP2Conn) RemoteAddr() net.Addr {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) SetDeadline(t time.Time) error {
|
func (c *HTTP2Conn) SetDeadline(t time.Time) error {
|
||||||
if responseWriter, loaded := c.writer.(interface {
|
if responseWriter, loaded := c.writer.(interface {
|
||||||
SetWriteDeadline(time.Time) error
|
SetWriteDeadline(time.Time) error
|
||||||
}); loaded {
|
}); loaded {
|
||||||
|
@ -79,7 +190,7 @@ func (c *HTTPConn) SetDeadline(t time.Time) error {
|
||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) SetReadDeadline(t time.Time) error {
|
func (c *HTTP2Conn) SetReadDeadline(t time.Time) error {
|
||||||
if responseWriter, loaded := c.writer.(interface {
|
if responseWriter, loaded := c.writer.(interface {
|
||||||
SetReadDeadline(time.Time) error
|
SetReadDeadline(time.Time) error
|
||||||
}); loaded {
|
}); loaded {
|
||||||
|
@ -88,7 +199,7 @@ func (c *HTTPConn) SetReadDeadline(t time.Time) error {
|
||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPConn) SetWriteDeadline(t time.Time) error {
|
func (c *HTTP2Conn) SetWriteDeadline(t time.Time) error {
|
||||||
if responseWriter, loaded := c.writer.(interface {
|
if responseWriter, loaded := c.writer.(interface {
|
||||||
SetWriteDeadline(time.Time) error
|
SetWriteDeadline(time.Time) error
|
||||||
}); loaded {
|
}); loaded {
|
||||||
|
@ -98,7 +209,7 @@ func (c *HTTPConn) SetWriteDeadline(t time.Time) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerHTTPConn struct {
|
type ServerHTTPConn struct {
|
||||||
HTTPConn
|
HTTP2Conn
|
||||||
flusher http.Flusher
|
flusher http.Flusher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/buf"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
@ -62,7 +64,7 @@ func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig t
|
||||||
server.path = "/" + server.path
|
server.path = "/" + server.path
|
||||||
}
|
}
|
||||||
for key, value := range options.Headers {
|
for key, value := range options.Headers {
|
||||||
server.headers.Set(key, value)
|
server.headers[key] = value
|
||||||
}
|
}
|
||||||
server.httpServer = &http.Server{
|
server.httpServer = &http.Server{
|
||||||
Handler: server,
|
Handler: server,
|
||||||
|
@ -106,11 +108,20 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||||
var metadata M.Metadata
|
var metadata M.Metadata
|
||||||
metadata.Source = sHttp.SourceAddress(request)
|
metadata.Source = sHttp.SourceAddress(request)
|
||||||
if h, ok := writer.(http.Hijacker); ok {
|
if h, ok := writer.(http.Hijacker); ok {
|
||||||
conn, _, err := h.Hijack()
|
conn, reader, err := h.Hijack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.fallbackRequest(request.Context(), writer, request, http.StatusInternalServerError, E.Cause(err, "hijack conn"))
|
s.fallbackRequest(request.Context(), writer, request, http.StatusInternalServerError, E.Cause(err, "hijack conn"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if cacheLen := reader.Reader.Buffered(); cacheLen > 0 {
|
||||||
|
cache := buf.NewSize(cacheLen)
|
||||||
|
_, err = cache.ReadFullFrom(reader.Reader, cacheLen)
|
||||||
|
if err != nil {
|
||||||
|
s.fallbackRequest(request.Context(), writer, request, http.StatusInternalServerError, E.Cause(err, "read cache"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conn = bufio.NewCachedConn(conn, cache)
|
||||||
|
}
|
||||||
s.handler.NewConnection(request.Context(), conn, metadata)
|
s.handler.NewConnection(request.Context(), conn, metadata)
|
||||||
} else {
|
} else {
|
||||||
conn := NewHTTP2Wrapper(&ServerHTTPConn{
|
conn := NewHTTP2Wrapper(&ServerHTTPConn{
|
||||||
|
|
|
@ -62,7 +62,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||||
}
|
}
|
||||||
headers := make(http.Header)
|
headers := make(http.Header)
|
||||||
for key, value := range options.Headers {
|
for key, value := range options.Headers {
|
||||||
headers.Set(key, value)
|
headers[key] = value
|
||||||
}
|
}
|
||||||
return &Client{
|
return &Client{
|
||||||
wsDialer,
|
wsDialer,
|
||||||
|
|
Loading…
Reference in a new issue