Merge 78bb59f0c5c319736a1f896cfdcfbd64baa51a14 into d9370f5a98ea6f35a41c8e2c2fd8e9d22a4a8eeb

This commit is contained in:
PuerNya 2025-05-18 06:03:42 +00:00 committed by GitHub
commit 58540829da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 86 additions and 7 deletions

View File

@ -3,6 +3,7 @@ package transport
import (
"bytes"
"context"
"encoding/base64"
"io"
"net"
"net/http"
@ -42,6 +43,7 @@ type HTTPSTransport struct {
logger logger.ContextLogger
dialer N.Dialer
destination *url.URL
method string
headers http.Header
transport *http.Transport
}
@ -104,6 +106,7 @@ func NewHTTPS(ctx context.Context, logger log.ContextLogger, tag string, options
logger,
transportDialer,
&destinationURL,
options.Method,
headers,
serverAddr,
tlsConfig,
@ -115,6 +118,7 @@ func NewHTTPSRaw(
logger log.ContextLogger,
dialer N.Dialer,
destination *url.URL,
method string,
headers http.Header,
serverAddr M.Socksaddr,
tlsConfig tls.Config,
@ -147,6 +151,7 @@ func NewHTTPSRaw(
TransportAdapter: adapter,
logger: logger,
dialer: dialer,
method: method,
destination: destination,
headers: headers,
transport: transport,
@ -176,13 +181,26 @@ func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS
requestBuffer.Release()
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 {
requestBuffer.Release()
return nil, err
}
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)
response, err := t.transport.RoundTrip(request)
requestBuffer.Release()

View File

@ -3,6 +3,7 @@ package quic
import (
"bytes"
"context"
"encoding/base64"
"io"
"net"
"net/http"
@ -40,6 +41,7 @@ type HTTP3Transport struct {
logger logger.ContextLogger
dialer N.Dialer
destination *url.URL
method string
headers http.Header
transport *http3.Transport
}
@ -100,6 +102,7 @@ func NewHTTP3(ctx context.Context, logger log.ContextLogger, tag string, options
logger: logger,
dialer: transportDialer,
destination: &destinationURL,
method: options.Method,
headers: headers,
transport: &http3.Transport{
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()
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 {
requestBuffer.Release()
return nil, err
}
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)
response, err := t.transport.RoundTrip(request)
requestBuffer.Release()

View File

@ -20,6 +20,7 @@ icon: material/new-box
"server_port": 443,
"path": "",
"method": "",
"headers": {},
"tls": {},
@ -58,6 +59,14 @@ The path of the DNS server.
`/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
Additional headers to be sent to the DNS server.

View File

@ -20,6 +20,7 @@ icon: material/new-box
"server_port": 443,
"path": "",
"method": "",
"headers": {},
"tls": {},
@ -58,6 +59,14 @@ The path of the DNS server.
`/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
Additional headers to be sent to the DNS server.

View File

@ -2,6 +2,7 @@ package option
import (
"context"
"net/http"
"net/netip"
"net/url"
@ -371,13 +372,39 @@ type RemoteTLSDNSServerOptions struct {
OutboundTLSOptionsContainer
}
type RemoteHTTPSDNSServerOptions struct {
type _RemoteHTTPSDNSServerOptions struct {
RemoteTLSDNSServerOptions
Path string `json:"path,omitempty"`
Method string `json:"method,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 {
Inet4Range *badoption.Prefix `json:"inet4_range,omitempty"`
Inet6Range *badoption.Prefix `json:"inet6_range,omitempty"`

View File

@ -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{
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":
serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
if serverAddr.Port == 0 {
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":
default:
return nil, E.New("unknown resolver scheme: ", serverURL.Scheme)