github.com/xraypb/xray-core@v1.6.6/infra/conf/transport_authenticators.go (about)

     1  package conf
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/golang/protobuf/proto"
     7  	"github.com/xraypb/xray-core/transport/internet/headers/http"
     8  	"github.com/xraypb/xray-core/transport/internet/headers/noop"
     9  	"github.com/xraypb/xray-core/transport/internet/headers/srtp"
    10  	"github.com/xraypb/xray-core/transport/internet/headers/tls"
    11  	"github.com/xraypb/xray-core/transport/internet/headers/utp"
    12  	"github.com/xraypb/xray-core/transport/internet/headers/wechat"
    13  	"github.com/xraypb/xray-core/transport/internet/headers/wireguard"
    14  )
    15  
    16  type NoOpAuthenticator struct{}
    17  
    18  func (NoOpAuthenticator) Build() (proto.Message, error) {
    19  	return new(noop.Config), nil
    20  }
    21  
    22  type NoOpConnectionAuthenticator struct{}
    23  
    24  func (NoOpConnectionAuthenticator) Build() (proto.Message, error) {
    25  	return new(noop.ConnectionConfig), nil
    26  }
    27  
    28  type SRTPAuthenticator struct{}
    29  
    30  func (SRTPAuthenticator) Build() (proto.Message, error) {
    31  	return new(srtp.Config), nil
    32  }
    33  
    34  type UTPAuthenticator struct{}
    35  
    36  func (UTPAuthenticator) Build() (proto.Message, error) {
    37  	return new(utp.Config), nil
    38  }
    39  
    40  type WechatVideoAuthenticator struct{}
    41  
    42  func (WechatVideoAuthenticator) Build() (proto.Message, error) {
    43  	return new(wechat.VideoConfig), nil
    44  }
    45  
    46  type WireguardAuthenticator struct{}
    47  
    48  func (WireguardAuthenticator) Build() (proto.Message, error) {
    49  	return new(wireguard.WireguardConfig), nil
    50  }
    51  
    52  type DTLSAuthenticator struct{}
    53  
    54  func (DTLSAuthenticator) Build() (proto.Message, error) {
    55  	return new(tls.PacketConfig), nil
    56  }
    57  
    58  type AuthenticatorRequest struct {
    59  	Version string                 `json:"version"`
    60  	Method  string                 `json:"method"`
    61  	Path    StringList             `json:"path"`
    62  	Headers map[string]*StringList `json:"headers"`
    63  }
    64  
    65  func sortMapKeys(m map[string]*StringList) []string {
    66  	var keys []string
    67  	for key := range m {
    68  		keys = append(keys, key)
    69  	}
    70  	sort.Strings(keys)
    71  	return keys
    72  }
    73  
    74  func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) {
    75  	config := &http.RequestConfig{
    76  		Uri: []string{"/"},
    77  		Header: []*http.Header{
    78  			{
    79  				Name:  "Host",
    80  				Value: []string{"www.baidu.com", "www.bing.com"},
    81  			},
    82  			{
    83  				Name: "User-Agent",
    84  				Value: []string{
    85  					"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    86  					"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46",
    87  				},
    88  			},
    89  			{
    90  				Name:  "Accept-Encoding",
    91  				Value: []string{"gzip, deflate"},
    92  			},
    93  			{
    94  				Name:  "Connection",
    95  				Value: []string{"keep-alive"},
    96  			},
    97  			{
    98  				Name:  "Pragma",
    99  				Value: []string{"no-cache"},
   100  			},
   101  		},
   102  	}
   103  
   104  	if len(v.Version) > 0 {
   105  		config.Version = &http.Version{Value: v.Version}
   106  	}
   107  
   108  	if len(v.Method) > 0 {
   109  		config.Method = &http.Method{Value: v.Method}
   110  	}
   111  
   112  	if len(v.Path) > 0 {
   113  		config.Uri = append([]string(nil), (v.Path)...)
   114  	}
   115  
   116  	if len(v.Headers) > 0 {
   117  		config.Header = make([]*http.Header, 0, len(v.Headers))
   118  		headerNames := sortMapKeys(v.Headers)
   119  		for _, key := range headerNames {
   120  			value := v.Headers[key]
   121  			if value == nil {
   122  				return nil, newError("empty HTTP header value: " + key).AtError()
   123  			}
   124  			config.Header = append(config.Header, &http.Header{
   125  				Name:  key,
   126  				Value: append([]string(nil), (*value)...),
   127  			})
   128  		}
   129  	}
   130  
   131  	return config, nil
   132  }
   133  
   134  type AuthenticatorResponse struct {
   135  	Version string                 `json:"version"`
   136  	Status  string                 `json:"status"`
   137  	Reason  string                 `json:"reason"`
   138  	Headers map[string]*StringList `json:"headers"`
   139  }
   140  
   141  func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) {
   142  	config := &http.ResponseConfig{
   143  		Header: []*http.Header{
   144  			{
   145  				Name:  "Content-Type",
   146  				Value: []string{"application/octet-stream", "video/mpeg"},
   147  			},
   148  			{
   149  				Name:  "Transfer-Encoding",
   150  				Value: []string{"chunked"},
   151  			},
   152  			{
   153  				Name:  "Connection",
   154  				Value: []string{"keep-alive"},
   155  			},
   156  			{
   157  				Name:  "Pragma",
   158  				Value: []string{"no-cache"},
   159  			},
   160  			{
   161  				Name:  "Cache-Control",
   162  				Value: []string{"private", "no-cache"},
   163  			},
   164  		},
   165  	}
   166  
   167  	if len(v.Version) > 0 {
   168  		config.Version = &http.Version{Value: v.Version}
   169  	}
   170  
   171  	if len(v.Status) > 0 || len(v.Reason) > 0 {
   172  		config.Status = &http.Status{
   173  			Code:   "200",
   174  			Reason: "OK",
   175  		}
   176  		if len(v.Status) > 0 {
   177  			config.Status.Code = v.Status
   178  		}
   179  		if len(v.Reason) > 0 {
   180  			config.Status.Reason = v.Reason
   181  		}
   182  	}
   183  
   184  	if len(v.Headers) > 0 {
   185  		config.Header = make([]*http.Header, 0, len(v.Headers))
   186  		headerNames := sortMapKeys(v.Headers)
   187  		for _, key := range headerNames {
   188  			value := v.Headers[key]
   189  			if value == nil {
   190  				return nil, newError("empty HTTP header value: " + key).AtError()
   191  			}
   192  			config.Header = append(config.Header, &http.Header{
   193  				Name:  key,
   194  				Value: append([]string(nil), (*value)...),
   195  			})
   196  		}
   197  	}
   198  
   199  	return config, nil
   200  }
   201  
   202  type Authenticator struct {
   203  	Request  AuthenticatorRequest  `json:"request"`
   204  	Response AuthenticatorResponse `json:"response"`
   205  }
   206  
   207  func (v *Authenticator) Build() (proto.Message, error) {
   208  	config := new(http.Config)
   209  	requestConfig, err := v.Request.Build()
   210  	if err != nil {
   211  		return nil, err
   212  	}
   213  	config.Request = requestConfig
   214  
   215  	responseConfig, err := v.Response.Build()
   216  	if err != nil {
   217  		return nil, err
   218  	}
   219  	config.Response = responseConfig
   220  
   221  	return config, nil
   222  }