mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
209 lines
4.4 KiB
Go
209 lines
4.4 KiB
Go
package conf
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/xtls/xray-core/common/errors"
|
|
"github.com/xtls/xray-core/common/utils"
|
|
"github.com/xtls/xray-core/transport/internet/headers/http"
|
|
"github.com/xtls/xray-core/transport/internet/headers/noop"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type NoOpConnectionAuthenticator struct{}
|
|
|
|
func (NoOpConnectionAuthenticator) Build() (proto.Message, error) {
|
|
return new(noop.ConnectionConfig), nil
|
|
}
|
|
|
|
type AuthenticatorRequest struct {
|
|
Version string `json:"version"`
|
|
Method string `json:"method"`
|
|
Path StringList `json:"path"`
|
|
Headers map[string]*StringList `json:"headers"`
|
|
}
|
|
|
|
func sortMapKeys(m map[string]*StringList) []string {
|
|
var keys []string
|
|
for key := range m {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|
|
|
|
func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) {
|
|
config := &http.RequestConfig{
|
|
Uri: []string{"/"},
|
|
Header: []*http.Header{
|
|
{
|
|
Name: "Host",
|
|
Value: []string{"www.baidu.com", "www.bing.com"},
|
|
},
|
|
{
|
|
Name: "User-Agent",
|
|
Value: []string{utils.ChromeUA},
|
|
},
|
|
{
|
|
Name: "Sec-CH-UA",
|
|
Value: []string{utils.ChromeUACH},
|
|
},
|
|
{
|
|
Name: "Sec-CH-UA-Mobile",
|
|
Value: []string{"?0"},
|
|
},
|
|
{
|
|
Name: "Sec-CH-UA-Platform",
|
|
Value: []string{"Windows"},
|
|
},
|
|
{
|
|
Name: "Sec-Fetch-Mode",
|
|
Value: []string{"no-cors", "cors", "same-origin"},
|
|
},
|
|
{
|
|
Name: "Sec-Fetch-Dest",
|
|
Value: []string{"empty"},
|
|
},
|
|
{
|
|
Name: "Sec-Fetch-Site",
|
|
Value: []string{"none"},
|
|
},
|
|
{
|
|
Name: "Sec-Fetch-User",
|
|
Value: []string{"?1"},
|
|
},
|
|
{
|
|
Name: "Accept-Encoding",
|
|
Value: []string{"gzip, deflate"},
|
|
},
|
|
{
|
|
Name: "Connection",
|
|
Value: []string{"keep-alive"},
|
|
},
|
|
{
|
|
Name: "Pragma",
|
|
Value: []string{"no-cache"},
|
|
},
|
|
},
|
|
}
|
|
|
|
if len(v.Version) > 0 {
|
|
config.Version = &http.Version{Value: v.Version}
|
|
}
|
|
|
|
if len(v.Method) > 0 {
|
|
config.Method = &http.Method{Value: v.Method}
|
|
}
|
|
|
|
if len(v.Path) > 0 {
|
|
config.Uri = append([]string(nil), (v.Path)...)
|
|
}
|
|
|
|
if len(v.Headers) > 0 {
|
|
config.Header = make([]*http.Header, 0, len(v.Headers))
|
|
headerNames := sortMapKeys(v.Headers)
|
|
for _, key := range headerNames {
|
|
value := v.Headers[key]
|
|
if value == nil {
|
|
return nil, errors.New("empty HTTP header value: " + key).AtError()
|
|
}
|
|
config.Header = append(config.Header, &http.Header{
|
|
Name: key,
|
|
Value: append([]string(nil), (*value)...),
|
|
})
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
type AuthenticatorResponse struct {
|
|
Version string `json:"version"`
|
|
Status string `json:"status"`
|
|
Reason string `json:"reason"`
|
|
Headers map[string]*StringList `json:"headers"`
|
|
}
|
|
|
|
func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) {
|
|
config := &http.ResponseConfig{
|
|
Header: []*http.Header{
|
|
{
|
|
Name: "Content-Type",
|
|
Value: []string{"application/octet-stream", "video/mpeg"},
|
|
},
|
|
{
|
|
Name: "Transfer-Encoding",
|
|
Value: []string{"chunked"},
|
|
},
|
|
{
|
|
Name: "Connection",
|
|
Value: []string{"keep-alive"},
|
|
},
|
|
{
|
|
Name: "Pragma",
|
|
Value: []string{"no-cache"},
|
|
},
|
|
{
|
|
Name: "Cache-Control",
|
|
Value: []string{"private", "no-cache"},
|
|
},
|
|
},
|
|
}
|
|
|
|
if len(v.Version) > 0 {
|
|
config.Version = &http.Version{Value: v.Version}
|
|
}
|
|
|
|
if len(v.Status) > 0 || len(v.Reason) > 0 {
|
|
config.Status = &http.Status{
|
|
Code: "200",
|
|
Reason: "OK",
|
|
}
|
|
if len(v.Status) > 0 {
|
|
config.Status.Code = v.Status
|
|
}
|
|
if len(v.Reason) > 0 {
|
|
config.Status.Reason = v.Reason
|
|
}
|
|
}
|
|
|
|
if len(v.Headers) > 0 {
|
|
config.Header = make([]*http.Header, 0, len(v.Headers))
|
|
headerNames := sortMapKeys(v.Headers)
|
|
for _, key := range headerNames {
|
|
value := v.Headers[key]
|
|
if value == nil {
|
|
return nil, errors.New("empty HTTP header value: " + key).AtError()
|
|
}
|
|
config.Header = append(config.Header, &http.Header{
|
|
Name: key,
|
|
Value: append([]string(nil), (*value)...),
|
|
})
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
type Authenticator struct {
|
|
Request AuthenticatorRequest `json:"request"`
|
|
Response AuthenticatorResponse `json:"response"`
|
|
}
|
|
|
|
func (v *Authenticator) Build() (proto.Message, error) {
|
|
config := new(http.Config)
|
|
requestConfig, err := v.Request.Build()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
config.Request = requestConfig
|
|
|
|
responseConfig, err := v.Response.Build()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
config.Response = responseConfig
|
|
|
|
return config, nil
|
|
}
|