mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
Merge 78bb59f0c5c319736a1f896cfdcfbd64baa51a14 into d9370f5a98ea6f35a41c8e2c2fd8e9d22a4a8eeb
This commit is contained in:
commit
58540829da
@ -3,6 +3,7 @@ package transport
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -42,6 +43,7 @@ type HTTPSTransport struct {
|
|||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
dialer N.Dialer
|
dialer N.Dialer
|
||||||
destination *url.URL
|
destination *url.URL
|
||||||
|
method string
|
||||||
headers http.Header
|
headers http.Header
|
||||||
transport *http.Transport
|
transport *http.Transport
|
||||||
}
|
}
|
||||||
@ -104,6 +106,7 @@ func NewHTTPS(ctx context.Context, logger log.ContextLogger, tag string, options
|
|||||||
logger,
|
logger,
|
||||||
transportDialer,
|
transportDialer,
|
||||||
&destinationURL,
|
&destinationURL,
|
||||||
|
options.Method,
|
||||||
headers,
|
headers,
|
||||||
serverAddr,
|
serverAddr,
|
||||||
tlsConfig,
|
tlsConfig,
|
||||||
@ -115,6 +118,7 @@ func NewHTTPSRaw(
|
|||||||
logger log.ContextLogger,
|
logger log.ContextLogger,
|
||||||
dialer N.Dialer,
|
dialer N.Dialer,
|
||||||
destination *url.URL,
|
destination *url.URL,
|
||||||
|
method string,
|
||||||
headers http.Header,
|
headers http.Header,
|
||||||
serverAddr M.Socksaddr,
|
serverAddr M.Socksaddr,
|
||||||
tlsConfig tls.Config,
|
tlsConfig tls.Config,
|
||||||
@ -147,6 +151,7 @@ func NewHTTPSRaw(
|
|||||||
TransportAdapter: adapter,
|
TransportAdapter: adapter,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
dialer: dialer,
|
dialer: dialer,
|
||||||
|
method: method,
|
||||||
destination: destination,
|
destination: destination,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
transport: transport,
|
transport: transport,
|
||||||
@ -176,13 +181,26 @@ func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS
|
|||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request, err := http.NewRequestWithContext(ctx, http.MethodPost, t.destination.String(), bytes.NewReader(rawMessage))
|
destination := *t.destination
|
||||||
|
var request *http.Request
|
||||||
|
var body io.Reader
|
||||||
|
switch t.method {
|
||||||
|
case http.MethodGet:
|
||||||
|
query := url.Values{}
|
||||||
|
query.Set("dns", base64.RawURLEncoding.EncodeToString(rawMessage))
|
||||||
|
destination.RawQuery = query.Encode()
|
||||||
|
case http.MethodPost:
|
||||||
|
body = bytes.NewReader(rawMessage)
|
||||||
|
}
|
||||||
|
request, err = http.NewRequestWithContext(ctx, t.method, destination.String(), body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.Header = t.headers.Clone()
|
request.Header = t.headers.Clone()
|
||||||
request.Header.Set("Content-Type", MimeType)
|
if t.method == http.MethodPost {
|
||||||
|
request.Header.Set("Content-Type", MimeType)
|
||||||
|
}
|
||||||
request.Header.Set("Accept", MimeType)
|
request.Header.Set("Accept", MimeType)
|
||||||
response, err := t.transport.RoundTrip(request)
|
response, err := t.transport.RoundTrip(request)
|
||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
|
@ -3,6 +3,7 @@ package quic
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -40,6 +41,7 @@ type HTTP3Transport struct {
|
|||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
dialer N.Dialer
|
dialer N.Dialer
|
||||||
destination *url.URL
|
destination *url.URL
|
||||||
|
method string
|
||||||
headers http.Header
|
headers http.Header
|
||||||
transport *http3.Transport
|
transport *http3.Transport
|
||||||
}
|
}
|
||||||
@ -100,6 +102,7 @@ func NewHTTP3(ctx context.Context, logger log.ContextLogger, tag string, options
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
dialer: transportDialer,
|
dialer: transportDialer,
|
||||||
destination: &destinationURL,
|
destination: &destinationURL,
|
||||||
|
method: options.Method,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
transport: &http3.Transport{
|
transport: &http3.Transport{
|
||||||
Dial: func(ctx context.Context, addr string, tlsCfg *tls.STDConfig, cfg *quic.Config) (quic.EarlyConnection, error) {
|
Dial: func(ctx context.Context, addr string, tlsCfg *tls.STDConfig, cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||||
@ -132,13 +135,26 @@ func (t *HTTP3Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS
|
|||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request, err := http.NewRequestWithContext(ctx, http.MethodPost, t.destination.String(), bytes.NewReader(rawMessage))
|
destination := *t.destination
|
||||||
|
var request *http.Request
|
||||||
|
var body io.Reader
|
||||||
|
switch t.method {
|
||||||
|
case http.MethodGet:
|
||||||
|
query := url.Values{}
|
||||||
|
query.Set("dns", base64.RawURLEncoding.EncodeToString(rawMessage))
|
||||||
|
destination.RawQuery = query.Encode()
|
||||||
|
case http.MethodPost:
|
||||||
|
body = bytes.NewReader(rawMessage)
|
||||||
|
}
|
||||||
|
request, err = http.NewRequestWithContext(ctx, t.method, destination.String(), body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.Header = t.headers.Clone()
|
request.Header = t.headers.Clone()
|
||||||
request.Header.Set("Content-Type", transport.MimeType)
|
if t.method == http.MethodPost {
|
||||||
|
request.Header.Set("Content-Type", transport.MimeType)
|
||||||
|
}
|
||||||
request.Header.Set("Accept", transport.MimeType)
|
request.Header.Set("Accept", transport.MimeType)
|
||||||
response, err := t.transport.RoundTrip(request)
|
response, err := t.transport.RoundTrip(request)
|
||||||
requestBuffer.Release()
|
requestBuffer.Release()
|
||||||
|
@ -20,6 +20,7 @@ icon: material/new-box
|
|||||||
"server_port": 443,
|
"server_port": 443,
|
||||||
|
|
||||||
"path": "",
|
"path": "",
|
||||||
|
"method": "",
|
||||||
"headers": {},
|
"headers": {},
|
||||||
|
|
||||||
"tls": {},
|
"tls": {},
|
||||||
@ -58,6 +59,14 @@ The path of the DNS server.
|
|||||||
|
|
||||||
`/dns-query` will be used by default.
|
`/dns-query` will be used by default.
|
||||||
|
|
||||||
|
#### method
|
||||||
|
|
||||||
|
The method of the DNS server.
|
||||||
|
|
||||||
|
Only `GET` and `POST` are supported.
|
||||||
|
|
||||||
|
`POST` will be used by default.
|
||||||
|
|
||||||
#### headers
|
#### headers
|
||||||
|
|
||||||
Additional headers to be sent to the DNS server.
|
Additional headers to be sent to the DNS server.
|
||||||
|
@ -20,6 +20,7 @@ icon: material/new-box
|
|||||||
"server_port": 443,
|
"server_port": 443,
|
||||||
|
|
||||||
"path": "",
|
"path": "",
|
||||||
|
"method": "",
|
||||||
"headers": {},
|
"headers": {},
|
||||||
|
|
||||||
"tls": {},
|
"tls": {},
|
||||||
@ -58,6 +59,14 @@ The path of the DNS server.
|
|||||||
|
|
||||||
`/dns-query` will be used by default.
|
`/dns-query` will be used by default.
|
||||||
|
|
||||||
|
#### method
|
||||||
|
|
||||||
|
The method of the DNS server.
|
||||||
|
|
||||||
|
Only `GET` and `POST` are supported.
|
||||||
|
|
||||||
|
`POST` will be used by default.
|
||||||
|
|
||||||
#### headers
|
#### headers
|
||||||
|
|
||||||
Additional headers to be sent to the DNS server.
|
Additional headers to be sent to the DNS server.
|
||||||
|
@ -2,6 +2,7 @@ package option
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/http"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
@ -371,13 +372,39 @@ type RemoteTLSDNSServerOptions struct {
|
|||||||
OutboundTLSOptionsContainer
|
OutboundTLSOptionsContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoteHTTPSDNSServerOptions struct {
|
type _RemoteHTTPSDNSServerOptions struct {
|
||||||
RemoteTLSDNSServerOptions
|
RemoteTLSDNSServerOptions
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RemoteHTTPSDNSServerOptions _RemoteHTTPSDNSServerOptions
|
||||||
|
|
||||||
|
func (o *RemoteHTTPSDNSServerOptions) MarshalJSONContext(ctx context.Context) ([]byte, error) {
|
||||||
|
switch o.Method {
|
||||||
|
case http.MethodPost:
|
||||||
|
o.Method = ""
|
||||||
|
}
|
||||||
|
return badjson.MarshallObjectsContext(ctx, (*_RemoteHTTPSDNSServerOptions)(o))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *RemoteHTTPSDNSServerOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
||||||
|
err := json.UnmarshalContext(ctx, content, (*_RemoteHTTPSDNSServerOptions)(o))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch o.Method {
|
||||||
|
case "", http.MethodPost:
|
||||||
|
o.Method = http.MethodPost
|
||||||
|
case http.MethodGet:
|
||||||
|
o.Method = http.MethodGet
|
||||||
|
default:
|
||||||
|
return E.New("unsupported method")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type FakeIPDNSServerOptions struct {
|
type FakeIPDNSServerOptions struct {
|
||||||
Inet4Range *badoption.Prefix `json:"inet4_range,omitempty"`
|
Inet4Range *badoption.Prefix `json:"inet4_range,omitempty"`
|
||||||
Inet6Range *badoption.Prefix `json:"inet6_range,omitempty"`
|
Inet6Range *badoption.Prefix `json:"inet6_range,omitempty"`
|
||||||
|
@ -180,13 +180,13 @@ func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dn
|
|||||||
tlsConfig := common.Must1(tls.NewClient(t.ctx, serverAddr.AddrString(), option.OutboundTLSOptions{
|
tlsConfig := common.Must1(tls.NewClient(t.ctx, serverAddr.AddrString(), option.OutboundTLSOptions{
|
||||||
ALPN: []string{http2.NextProtoTLS, "http/1.1"},
|
ALPN: []string{http2.NextProtoTLS, "http/1.1"},
|
||||||
}))
|
}))
|
||||||
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, tlsConfig), nil
|
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.MethodPost, http.Header{}, serverAddr, tlsConfig), nil
|
||||||
case "http":
|
case "http":
|
||||||
serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
||||||
if serverAddr.Port == 0 {
|
if serverAddr.Port == 0 {
|
||||||
serverAddr.Port = 80
|
serverAddr.Port = 80
|
||||||
}
|
}
|
||||||
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, nil), nil
|
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.MethodPost, http.Header{}, serverAddr, nil), nil
|
||||||
// case "tls":
|
// case "tls":
|
||||||
default:
|
default:
|
||||||
return nil, E.New("unknown resolver scheme: ", serverURL.Scheme)
|
return nil, E.New("unknown resolver scheme: ", serverURL.Scheme)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user