【问题标题】:What is the best way to use .PAC in C# when request is redirected重定向请求时在 C# 中使用 .PAC 的最佳方法是什么
【发布时间】:2014-01-28 04:25:33
【问题描述】:

背景

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

问题

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

【问题讨论】:

    标签: c# redirect proxy httpwebrequest pac


    【解决方案1】:

    您可以像这样实现自己的 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");
    

    希望这会有所帮助:)

    【讨论】:

    • 我试过这个。我发现 GetProxy 没有被命中。我明天再试一次。谢谢。
    • 请确保IsBypassed()返回false,否则GetProxy()会被忽略。
    • 我明白了。非常感谢!迫不及待想试试这个。
    猜你喜欢
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2011-02-15
    • 2012-03-03
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    相关资源
    最近更新 更多