feat: add v2ray-http-upgrade
support
This commit is contained in:
parent
b0638cfc49
commit
ceac5bfaa4
8 changed files with 97 additions and 49 deletions
|
@ -66,6 +66,7 @@ type v2rayObfsOption struct {
|
||||||
Headers map[string]string `obfs:"headers,omitempty"`
|
Headers map[string]string `obfs:"headers,omitempty"`
|
||||||
SkipCertVerify bool `obfs:"skip-cert-verify,omitempty"`
|
SkipCertVerify bool `obfs:"skip-cert-verify,omitempty"`
|
||||||
Mux bool `obfs:"mux,omitempty"`
|
Mux bool `obfs:"mux,omitempty"`
|
||||||
|
V2rayHttpUpgrade bool `obfs:"v2ray-http-upgrade,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type shadowTLSOption struct {
|
type shadowTLSOption struct {
|
||||||
|
@ -263,6 +264,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||||
Path: opts.Path,
|
Path: opts.Path,
|
||||||
Headers: opts.Headers,
|
Headers: opts.Headers,
|
||||||
Mux: opts.Mux,
|
Mux: opts.Mux,
|
||||||
|
V2rayHttpUpgrade: opts.V2rayHttpUpgrade,
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.TLS {
|
if opts.TLS {
|
||||||
|
|
|
@ -56,6 +56,7 @@ func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error)
|
||||||
Host: host,
|
Host: host,
|
||||||
Port: port,
|
Port: port,
|
||||||
Path: t.option.WSOpts.Path,
|
Path: t.option.WSOpts.Path,
|
||||||
|
V2rayHttpUpgrade: t.option.WSOpts.V2rayHttpUpgrade,
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.option.SNI != "" {
|
if t.option.SNI != "" {
|
||||||
|
|
|
@ -93,6 +93,7 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||||
Path: v.option.WSOpts.Path,
|
Path: v.option.WSOpts.Path,
|
||||||
MaxEarlyData: v.option.WSOpts.MaxEarlyData,
|
MaxEarlyData: v.option.WSOpts.MaxEarlyData,
|
||||||
EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName,
|
EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName,
|
||||||
|
V2rayHttpUpgrade: v.option.WSOpts.V2rayHttpUpgrade,
|
||||||
ClientFingerprint: v.option.ClientFingerprint,
|
ClientFingerprint: v.option.ClientFingerprint,
|
||||||
Headers: http.Header{},
|
Headers: http.Header{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ type WSOptions struct {
|
||||||
Headers map[string]string `proxy:"headers,omitempty"`
|
Headers map[string]string `proxy:"headers,omitempty"`
|
||||||
MaxEarlyData int `proxy:"max-early-data,omitempty"`
|
MaxEarlyData int `proxy:"max-early-data,omitempty"`
|
||||||
EarlyDataHeaderName string `proxy:"early-data-header-name,omitempty"`
|
EarlyDataHeaderName string `proxy:"early-data-header-name,omitempty"`
|
||||||
|
V2rayHttpUpgrade bool `proxy:"v2ray-http-upgrade,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamConnContext implements C.ProxyAdapter
|
// StreamConnContext implements C.ProxyAdapter
|
||||||
|
@ -110,6 +111,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||||
Path: v.option.WSOpts.Path,
|
Path: v.option.WSOpts.Path,
|
||||||
MaxEarlyData: v.option.WSOpts.MaxEarlyData,
|
MaxEarlyData: v.option.WSOpts.MaxEarlyData,
|
||||||
EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName,
|
EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName,
|
||||||
|
V2rayHttpUpgrade: v.option.WSOpts.V2rayHttpUpgrade,
|
||||||
ClientFingerprint: v.option.ClientFingerprint,
|
ClientFingerprint: v.option.ClientFingerprint,
|
||||||
Headers: http.Header{},
|
Headers: http.Header{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,6 +362,7 @@ proxies: # socks5
|
||||||
# mux: true
|
# mux: true
|
||||||
# headers:
|
# headers:
|
||||||
# custom: value
|
# custom: value
|
||||||
|
# v2ray-http-upgrade: false
|
||||||
|
|
||||||
- name: "ss4-shadow-tls"
|
- name: "ss4-shadow-tls"
|
||||||
type: ss
|
type: ss
|
||||||
|
@ -439,6 +440,7 @@ proxies: # socks5
|
||||||
# Host: v2ray.com
|
# Host: v2ray.com
|
||||||
# max-early-data: 2048
|
# max-early-data: 2048
|
||||||
# early-data-header-name: Sec-WebSocket-Protocol
|
# early-data-header-name: Sec-WebSocket-Protocol
|
||||||
|
# v2ray-http-upgrade: false
|
||||||
|
|
||||||
- name: "vmess-h2"
|
- name: "vmess-h2"
|
||||||
type: vmess
|
type: vmess
|
||||||
|
@ -566,6 +568,7 @@ proxies: # socks5
|
||||||
path: "/"
|
path: "/"
|
||||||
headers:
|
headers:
|
||||||
Host: example.com
|
Host: example.com
|
||||||
|
# v2ray-http-upgrade: false
|
||||||
|
|
||||||
# Trojan
|
# Trojan
|
||||||
- name: "trojan"
|
- name: "trojan"
|
||||||
|
@ -609,6 +612,7 @@ proxies: # socks5
|
||||||
# path: /path
|
# path: /path
|
||||||
# headers:
|
# headers:
|
||||||
# Host: example.com
|
# Host: example.com
|
||||||
|
# v2ray-http-upgrade: false
|
||||||
|
|
||||||
- name: "trojan-xtls"
|
- name: "trojan-xtls"
|
||||||
type: trojan
|
type: trojan
|
||||||
|
|
|
@ -59,6 +59,7 @@ type WebsocketOption struct {
|
||||||
Port string
|
Port string
|
||||||
Path string
|
Path string
|
||||||
Headers http.Header
|
Headers http.Header
|
||||||
|
V2rayHttpUpgrade bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Trojan struct {
|
type Trojan struct {
|
||||||
|
@ -132,6 +133,7 @@ func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptio
|
||||||
Port: wsOptions.Port,
|
Port: wsOptions.Port,
|
||||||
Path: wsOptions.Path,
|
Path: wsOptions.Path,
|
||||||
Headers: wsOptions.Headers,
|
Headers: wsOptions.Headers,
|
||||||
|
V2rayHttpUpgrade: wsOptions.V2rayHttpUpgrade,
|
||||||
TLS: true,
|
TLS: true,
|
||||||
TLSConfig: tlsConfig,
|
TLSConfig: tlsConfig,
|
||||||
ClientFingerprint: t.option.ClientFingerprint,
|
ClientFingerprint: t.option.ClientFingerprint,
|
||||||
|
|
|
@ -20,6 +20,7 @@ type Option struct {
|
||||||
SkipCertVerify bool
|
SkipCertVerify bool
|
||||||
Fingerprint string
|
Fingerprint string
|
||||||
Mux bool
|
Mux bool
|
||||||
|
V2rayHttpUpgrade bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewV2rayObfs return a HTTPObfs
|
// NewV2rayObfs return a HTTPObfs
|
||||||
|
@ -33,6 +34,7 @@ func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn,
|
||||||
Host: option.Host,
|
Host: option.Host,
|
||||||
Port: option.Port,
|
Port: option.Port,
|
||||||
Path: option.Path,
|
Path: option.Path,
|
||||||
|
V2rayHttpUpgrade: option.V2rayHttpUpgrade,
|
||||||
Headers: header,
|
Headers: header,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ type WebsocketConfig struct {
|
||||||
MaxEarlyData int
|
MaxEarlyData int
|
||||||
EarlyDataHeaderName string
|
EarlyDataHeaderName string
|
||||||
ClientFingerprint string
|
ClientFingerprint string
|
||||||
|
V2rayHttpUpgrade bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read implements net.Conn.Read()
|
// Read implements net.Conn.Read()
|
||||||
|
@ -352,6 +353,39 @@ func streamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig,
|
||||||
RawQuery: u.RawQuery,
|
RawQuery: u.RawQuery,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.V2rayHttpUpgrade {
|
||||||
|
if c.TLS {
|
||||||
|
if dialer.TLSClient != nil {
|
||||||
|
conn = dialer.TLSClient(conn, uri.Host)
|
||||||
|
} else {
|
||||||
|
conn = tls.Client(conn, dialer.TLSConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request := &http.Request{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
URL: &uri,
|
||||||
|
Header: c.Headers.Clone(),
|
||||||
|
Host: c.Host,
|
||||||
|
}
|
||||||
|
request.Header.Set("Connection", "Upgrade")
|
||||||
|
request.Header.Set("Upgrade", "websocket")
|
||||||
|
err = request.Write(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bufferedConn := N.NewBufferedConn(conn)
|
||||||
|
response, err := http.ReadResponse(bufferedConn.Reader(), request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if response.StatusCode != 101 ||
|
||||||
|
!strings.EqualFold(response.Header.Get("Connection"), "upgrade") ||
|
||||||
|
!strings.EqualFold(response.Header.Get("Upgrade"), "websocket") {
|
||||||
|
return nil, fmt.Errorf("unexpected status: %s", response.Status)
|
||||||
|
}
|
||||||
|
return bufferedConn, nil
|
||||||
|
}
|
||||||
|
|
||||||
headers := http.Header{}
|
headers := http.Header{}
|
||||||
headers.Set("User-Agent", "Go-http-client/1.1") // match golang's net/http
|
headers.Set("User-Agent", "Go-http-client/1.1") // match golang's net/http
|
||||||
if c.Headers != nil {
|
if c.Headers != nil {
|
||||||
|
|
Loading…
Reference in a new issue