通过代理连接不包括我的标题

时间:2012-12-12 07:55:29

标签: c# http webclient

好的,简单的问题,但在我能够达到它之前需要一些解释。

我正在尝试使用System.Net.WebClient(或WebRequest,同样的结果)通过代理服务器下载https页面。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    static class Program
    {
        static void Main(string[] args)
        {
             var wc = new WebClient();
             wc.Proxy = new WebProxy("MyProxyAddress") { UseDefaultCredentials = true };
             wc.Headers.Add("xyz", "abc");

            try
            {
                 Console.WriteLine(wc.DownloadString("https://www.google.co.nz"));
            }
            catch (WebException wex)
            {
                if (wex.Response != null)
                    using (var reader = new StreamReader(wex.Response.GetResponseStream()))
                        Console.WriteLine(reader.ReadToEnd());
            }
        }
    }
}

如果我此时启动Fiddler,我可以看到请求如下所示。请注意,我已将Fiddler设置为要求代理身份验证。

CONNECT www.google.co.nz:443 HTTP/1.1
Host: www.google.co.nz
Proxy-Connection: Keep-Alive

回复将是

HTTP/1.1 407 Proxy Auth Required
Connection: close

,正如所料。如果我将地址从https:// ...更改为http:// ...,我会得到这个。请注意,xyz标题现在显示为

GET http://www.google.co.nz/ HTTP/1.1
xyz: abc
Host: www.google.co.nz
Proxy-Connection: Keep-Alive

一切都很好,除非我正在进行的代理需要用户代理。所有标头(包括我的User-Agent)都会从请求中删除,因此代理会拒绝该请求。如果我将Fiddler配置为强制User-Agent标头进入请求,则一切正常。

那么,为什么我的标题不包含在CONNECT请求中?这是MS的错误,还是我错过了什么?

1 个答案:

答案 0 :(得分:0)

通过网络代理的HTTPS工作方式如下:

  1. 客户端向代理发送CONNECT请求 - 这就是您在Fiddler中看到的内容。
  2. 代理同意连接,返回200 CONNECTED,现在作为无逻辑数据泵运行
    • 如果代理需要身份验证,则会返回407 Proxy Auth Required,客户端会使用正确的代理身份验证生成相同的CONNECT请求。
  3. 客户现在可以通过盲目数据泵送数据的代理直接与真实服务器通信。
    • 通常,客户端会执行HTTPS会话协商,然后通过加密会话发送“真实”HTTP请求。
  4. 我不是100%熟悉WebClient,但我认为添加的标题仅适用于“真正的”HTTP请求(上面的3)。你可以用你的WebProxy实例做一些事情,虽然我也找不到任何解决方案。