.NET5 HttpClient自定义服务器名称指定(SNI)的值
原理就是.NET5中SocketsHttpHandler类添加了一个属性ConnectCallback允许你自定义链接,但是假如你构造一个SslStream返回并且传入的uri是https协议那么库内部还会自动再套一个SslStream,所以后续传入的uri必须改成http协议
static async Task Main(string[] args) { const string DNS_AND_SNI = "www.pixivision.net"; //注意这个地方是http而不是httpps //否则我们不能自定义sslstream const string URI = "http://www.pixiv.net/"; var handler = new SocketsHttpHandler() { ConnectCallback = (info, token) => { Console.WriteLine(info.InitialRequestMessage.RequestUri); Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); socket.Connect(DNS_AND_SNI, 443); var stream = new NetworkStream(socket, true); SslStream sslstream = new SslStream(stream, false); sslstream.AuthenticateAsClient(new SslClientAuthenticationOptions { //sni字符串 TargetHost = DNS_AND_SNI, //tls指定后续的应用层协议 ApplicationProtocols = new List<SslApplicationProtocol>(new SslApplicationProtocol[] { SslApplicationProtocol.Http2 }) }); return new ValueTask<Stream>(sslstream); } }; HttpClient client = new HttpClient(handler); //协议和tls预先指定的保持一致 client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; client.DefaultRequestVersion = HttpVersion.Version20; var headers = client.DefaultRequestHeaders; headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); headers.Add("Accept-Language", "zh-CN,zh;q=0.9"); headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"); string s = await client.GetStringAsync(URI); Console.WriteLine(s.Length); }
浙公网安备 33010602011771号