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