重定向请求时,在C#中使用.PAC的最佳方法是什么

时间:2014-01-28 04:25:33

标签: c# redirect proxy httpwebrequest pac

背景

我必须在我的应用程序中使用用户指定的代理服务器。 现在,我检查输入代理是否包含“.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 网址)返回 P
  • 重定向的网址 REAL_URL
  • GetProxyFromPac( PAC_P REAL_URL )返回 PP

我发现这是因为我在请求中将代理设置为 P ,它将用于所有网址(包括重定向的网址),但 REAL_URL 无法通过的 P 即可。 我必须从 REAL_URL PAC_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;
}

问题

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

1 个答案:

答案 0 :(得分: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");

希望这会有所帮助:)