1

背景

我必须在我的应用程序中使用用户指定的代理服务器。现在,我检查输入代理是否包含“.pac”。如果是,我将从 pac 文件中获取真正的代理。( http://www.codeproject.com/Articles/12168/Using-PAC-files-proxy ) 否则,我只是将输入代理设置为 WebProxy。

public HttpWebRequest CreateRequest(string url, string proxy)
{
    var request = WebRequest.Create(url);
    if (proxy.ToLower().Contains(".pac")) 
    {
        string realProxy = GetProxyFromPac(url, proxy);
        request.Proxy = (string.IsNullOrEmpty(realProxy)) 
            ? new WebProxy() 
            : new WebProxy(realProxy, true);
    }
    else
    {
        request.Proxy = new WebProxy(proxy, true);
    }
    return request as HttpWebRequest;
}

并像这样使用请求。

var request = CreateRequest(url, proxy);
var response = request.GetResponse() as HttpWebResponse;

问题

当服务器将 url 重定向到另一个 url 时,我会得到请求超时。

例子:

  • 输入网址网址
  • 输入代理PAC_P
  • GetProxyFromPac( PAC_P , URL ) 返回P
  • 重定向的 url REAL_URL
  • GetProxyFromPac( PAC_P , REAL_URL ) 返回PP

我发现这是因为我在请求中将代理设置为P,它将用于所有 url(包括重定向的 url),但REAL_URL无法通过P访问。我必须从REAL_URLPAC_P获取PP并使用PP请求REAL_URL

我脑海中的第一个解决方案是每次重定向请求时获取一个新代理并手动请求重定向的 url。

var request = CreateRequest(url, proxy);
request.AllowAutoRedirect = false;
var response = request.GetResponse() as HttpWebResponse;
while (response.StatusCode == HttpStatusCode.Redirect ||
       response.StatusCode == HttpStatusCode.Moved)
{
    request = CreateRequest(response.Headers["Location"], proxy);
    response = request.GetResponse() as HttpWebResponse;
}

问题

我认为应该有一种优雅的方式来处理这个问题。这似乎是一个非常普遍的情况。你有什么主意吗?

4

1 回答 1

2

您可以像这样实现自己的 IWebProxy 类:

public class MyPacScriptProxy : IWebProxy
{
    protected string PacScriptUrl;

    public MyPacScriptProxy(string url)
    {
        PacScriptUrl = url;
    }

    public ICredentials Credentials { get; set; }

    public Uri GetProxy(Uri dest)
    {
        // you can return your GetProxyFromPac(dest, PacScriptUrl); result here

        if (dest.Host.EndsWith(".net")) {
            return null; // bypass proxy for .net websites
        }

        return new Uri("http://localhost:8888");
    }

    public bool IsBypassed(Uri host)
    {
        return false;
    }
}

然后像这样使用它:

var request = WebRequest.Create("http://www.google.com");
request.Proxy = new MyPacScriptProxy("http://localhost/proxy.pac");

希望这可以帮助 :)

于 2014-01-28T15:27:03.033 回答