mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-09-09 13:04:06 +08:00
add v2ray extra options
This commit is contained in:
parent
d57183a218
commit
80bf1f838e
@ -2,12 +2,25 @@ package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
type V2RayExtraOptionsKeyType int
|
||||
|
||||
var V2RayExtraOptionsKey V2RayExtraOptionsKeyType = 1
|
||||
|
||||
type V2RayExtraOptions struct {
|
||||
URL *url.URL
|
||||
QueryParams url.Values
|
||||
Headers http.Header
|
||||
}
|
||||
|
||||
type V2RayServerTransport interface {
|
||||
Network() []string
|
||||
Serve(listener net.Listener) error
|
||||
@ -24,3 +37,32 @@ type V2RayClientTransport interface {
|
||||
DialContext(ctx context.Context) (net.Conn, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
func (options *V2RayExtraOptions) Apply(requestURL *url.URL, headers http.Header) (*url.URL, http.Header) {
|
||||
copyURL := *requestURL
|
||||
copyHeaders := headers.Clone()
|
||||
if options.URL != nil {
|
||||
copyURL = *options.URL
|
||||
}
|
||||
if options.QueryParams != nil {
|
||||
rQuery := copyURL.Query()
|
||||
for key, values := range options.QueryParams {
|
||||
for _, value := range values {
|
||||
if rQuery.Has(key) {
|
||||
rQuery.Add(key, value)
|
||||
} else {
|
||||
rQuery.Set(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
copyURL.RawQuery = base64.RawURLEncoding.EncodeToString([]byte(rQuery.Encode()))
|
||||
}
|
||||
if options.Headers != nil {
|
||||
for key, values := range options.Headers {
|
||||
for _, value := range values {
|
||||
copyHeaders.Add(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ©URL, copyHeaders
|
||||
}
|
||||
|
@ -104,10 +104,16 @@ func (c *Client) dialHTTP(ctx context.Context) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requestURL, headers := &c.requestURL, c.headers.Clone()
|
||||
options, ok := ctx.Value(adapter.V2RayExtraOptionsKey).(adapter.V2RayExtraOptions)
|
||||
if ok {
|
||||
requestURL, headers = options.Apply(requestURL, headers)
|
||||
}
|
||||
|
||||
request := &http.Request{
|
||||
Method: c.method,
|
||||
URL: &c.requestURL,
|
||||
Header: c.headers.Clone(),
|
||||
URL: requestURL,
|
||||
Header: headers,
|
||||
}
|
||||
switch hostLen := len(c.host); hostLen {
|
||||
case 0:
|
||||
@ -122,12 +128,17 @@ func (c *Client) dialHTTP(ctx context.Context) (net.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) {
|
||||
requestURL, headers := &c.requestURL, c.headers.Clone()
|
||||
options, ok := ctx.Value(adapter.V2RayExtraOptionsKey).(adapter.V2RayExtraOptions)
|
||||
if ok {
|
||||
requestURL, headers = options.Apply(requestURL, headers)
|
||||
}
|
||||
pipeInReader, pipeInWriter := io.Pipe()
|
||||
request := &http.Request{
|
||||
Method: c.method,
|
||||
Body: pipeInReader,
|
||||
URL: &c.requestURL,
|
||||
Header: c.headers.Clone(),
|
||||
URL: requestURL,
|
||||
Header: headers,
|
||||
}
|
||||
request = request.WithContext(ctx)
|
||||
switch hostLen := len(c.host); hostLen {
|
||||
|
@ -74,6 +74,11 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||
}
|
||||
|
||||
func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
requestURL, headers := &c.requestURL, c.headers.Clone()
|
||||
options, ok := ctx.Value(adapter.V2RayExtraOptionsKey).(adapter.V2RayExtraOptions)
|
||||
if ok {
|
||||
requestURL, headers = options.Apply(requestURL, headers)
|
||||
}
|
||||
conn, err := c.dialer.DialContext(ctx, N.NetworkTCP, c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -86,8 +91,8 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
}
|
||||
request := &http.Request{
|
||||
Method: http.MethodGet,
|
||||
URL: &c.requestURL,
|
||||
Header: c.headers.Clone(),
|
||||
URL: requestURL,
|
||||
Header: headers,
|
||||
Host: c.host,
|
||||
}
|
||||
request.Header.Set("Connection", "Upgrade")
|
||||
|
@ -75,6 +75,10 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||
}
|
||||
|
||||
func (c *Client) dialContext(ctx context.Context, requestURL *url.URL, headers http.Header) (*WebsocketConn, error) {
|
||||
options, ok := ctx.Value(adapter.V2RayExtraOptionsKey).(adapter.V2RayExtraOptions)
|
||||
if ok {
|
||||
requestURL, headers = options.Apply(requestURL, headers)
|
||||
}
|
||||
conn, err := c.dialer.DialContext(ctx, N.NetworkTCP, c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -77,7 +77,7 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
)
|
||||
if s.earlyDataHeaderName == "" {
|
||||
if strings.HasPrefix(request.URL.RequestURI(), s.path) {
|
||||
earlyDataStr := request.URL.RequestURI()[len(s.path):]
|
||||
earlyDataStr := request.URL.RequestURI()[len(s.path)+len("?"):]
|
||||
earlyData, err = base64.RawURLEncoding.DecodeString(earlyDataStr)
|
||||
} else {
|
||||
s.invalidRequest(writer, request, http.StatusNotFound, E.New("bad path: ", request.URL.Path))
|
||||
|
Loading…
x
Reference in New Issue
Block a user