Add WSS Browser Dialer support (#421)

This commit is contained in:
RPRX 2021-03-23 09:25:35 +00:00 committed by GitHub
parent 0470381fe2
commit d46af8b5d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 8 deletions

View file

@ -2,8 +2,12 @@ package websocket
import (
"context"
_ "embed"
"encoding/base64"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/gorilla/websocket"
@ -15,6 +19,27 @@ import (
"github.com/xtls/xray-core/transport/internet/tls"
)
//go:embed dialer.html
var webpage []byte
var conns chan *websocket.Conn
func init() {
if addr := os.Getenv("XRAY_BROWSER_DIALER"); addr != "" {
conns = make(chan *websocket.Conn, 256)
go http.ListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/websocket" {
if conn, err := upgrader.Upgrade(w, r, nil); err == nil {
conns <- conn
} else {
fmt.Println("unexpected error")
}
} else {
w.Write(webpage)
}
}))
}
}
// Dial dials a WebSocket connection to the given destination.
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
newError("creating connection to ", dest).WriteToLog(session.ExportIDToError(ctx))
@ -66,6 +91,30 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
}
uri := protocol + "://" + host + wsSettings.GetNormalizedPath()
if conns != nil {
data := []byte(uri)
if ed != nil {
data = append(data, " "+base64.RawURLEncoding.EncodeToString(ed)...)
}
var conn *websocket.Conn
for {
conn = <-conns
if conn.WriteMessage(websocket.TextMessage, data) != nil {
conn.Close()
} else {
break
}
}
if _, p, err := conn.ReadMessage(); err != nil {
conn.Close()
return nil, err
} else if s := string(p); s != "ok" {
conn.Close()
return nil, newError(s)
}
return newConnection(conn, conn.RemoteAddr(), nil), nil
}
header := wsSettings.GetRequestHeader()
if ed != nil {
header.Set("Sec-WebSocket-Protocol", base64.StdEncoding.EncodeToString(ed))