Reputation: 609
Background
I have to use the proxy server specified by users in my application. Right now, I check that the input proxy contains ".pac" or not. If yes, I'll get the real proxy from pac file. (http://www.codeproject.com/Articles/12168/Using-PAC-files-proxy) Otherwise, I just set the input proxy to 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;
}
And use the request like this.
var request = CreateRequest(url, proxy);
var response = request.GetResponse() as HttpWebResponse;
Problem
When the server redirects url to another url, I'll get request timeout.
Example:
I found that it's because I set the proxy to P in the request and it will be used for all urls (including redirected urls) but REAL_URL is not accessible via P. I have to get PP from the REAL_URL and PAC_P and use PP to request to REAL_URL.
The first solution in my head is to get a new proxy every time the request is redirected and manually request to the redirected 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;
}
Question
I think there should be an elegant way to handle this. It seems to be an extremely general case. Do you have any idea?
Upvotes: 1
Views: 3064
Reputation: 11547
You can implement your own IWebProxy class like this:
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;
}
}
then use it like this:
var request = WebRequest.Create("http://www.google.com");
request.Proxy = new MyPacScriptProxy("http://localhost/proxy.pac");
Hope this helps :)
Upvotes: 2