feat: add v2ray-http-upgrade support

This commit is contained in:
wwqgtxx
2023-11-02 11:11:19 +08:00
parent b0638cfc49
commit ceac5bfaa4
8 changed files with 97 additions and 49 deletions

View File

@ -55,10 +55,11 @@ type Option struct {
}
type WebsocketOption struct {
Host string
Port string
Path string
Headers http.Header
Host string
Port string
Path string
Headers http.Header
V2rayHttpUpgrade bool
}
type Trojan struct {
@ -132,6 +133,7 @@ func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptio
Port: wsOptions.Port,
Path: wsOptions.Path,
Headers: wsOptions.Headers,
V2rayHttpUpgrade: wsOptions.V2rayHttpUpgrade,
TLS: true,
TLSConfig: tlsConfig,
ClientFingerprint: t.option.ClientFingerprint,

View File

@ -12,14 +12,15 @@ import (
// Option is options of websocket obfs
type Option struct {
Host string
Port string
Path string
Headers map[string]string
TLS bool
SkipCertVerify bool
Fingerprint string
Mux bool
Host string
Port string
Path string
Headers map[string]string
TLS bool
SkipCertVerify bool
Fingerprint string
Mux bool
V2rayHttpUpgrade bool
}
// NewV2rayObfs return a HTTPObfs
@ -30,10 +31,11 @@ func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn,
}
config := &vmess.WebsocketConfig{
Host: option.Host,
Port: option.Port,
Path: option.Path,
Headers: header,
Host: option.Host,
Port: option.Port,
Path: option.Path,
V2rayHttpUpgrade: option.V2rayHttpUpgrade,
Headers: header,
}
if option.TLS {

View File

@ -55,6 +55,7 @@ type WebsocketConfig struct {
MaxEarlyData int
EarlyDataHeaderName string
ClientFingerprint string
V2rayHttpUpgrade bool
}
// Read implements net.Conn.Read()
@ -352,6 +353,39 @@ func streamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig,
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.Set("User-Agent", "Go-http-client/1.1") // match golang's net/http
if c.Headers != nil {