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