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 }