问题
I have a simple web api project based on this example: http://aspnet.codeplex.com/sourcecontrol/latest#Samples/WebApi/RelaySample/Program.cs
However, in the above sample the relay is working with a local server, in my project the relay is working with an external web server with a real address; companyX.com
I am using the relay service (or, web proxy service) through a browser, for example, in the browser request relayService.com/companyX. The relay service responds with data from the external companyX.com site.
The relay works great, however some headers are not correct and I need to see what the HttpClient is sending to the remote companyX.com server.
In fiddler or Charles, only the request/response from my browser to relayService.com is listed, the request/response from the HttpClient to relayService.com never shows up.
The relayService.com is running locally on my machine, in IIS7, I'm using the hosts file to direct traffic to relayService.com.
I have tried several variation of the following when creating the HttpClient:
var clientHandler = new HttpClientHandler
{
CookieContainer = cookies,
UseCookies = true,
UseDefaultCredentials = false,
Proxy = new WebProxy("http://localhost:8888"),
UseProxy = true,
AutomaticDecompression = DecompressionMethods.GZip,
AllowAutoRedirect = false,
ClientCertificateOptions = ClientCertificateOption.Automatic
};
HttpClient client = new HttpClient(clientHandler);
UPDATE
If I change UseProxy = false
The service continues to work, when Fiddler is open or closed.
With UseProxy = true
then the service will fail, if fiddler is open, I get the following error:
Object reference not set to an instance of an object.
at System.DomainNameHelper.IdnEquivalent(String hostname) at System.Net.HttpWebRequest.GetSafeHostAndPort(Uri sourceUri, Boolean addDefaultPort, Boolean forcePunycode) at System.Net.HttpWebRequest.GenerateProxyRequestLine(Int32 headersSize) at System.Net.HttpWebRequest.SerializeHeaders() at System.Net.HttpWebRequest.EndSubmitRequest() at System.Net.Connection.CompleteConnection(Boolean async, HttpWebRequest request)
With UseProxy = true
and fiddler is CLOSED, I get the following (obvious) error:
No connection could be made because the target machine actively refused it 127.0.0.1:8888
In the same solution I am using HttpWebRequest to download data from the web and that does show up in Fiddler, so it seems to be an issue with the HttpClient.GetAsync()
I have tried this on two machines with identical results.
I have been struggling with this all day, any help would be much appreciated.
Just to recap: * relayService.com is running locally on my machine, in IIS7
hosts file has "127.0.0.1 relayService.com"
relayService.com is an MVC Web API site that uses HttpClient.GetAsync() to download content from the live web
Fiddler/Charles is running locally on same machine
browser traffic to the local relayService.com appears in Fiddler/Charles
HttpClient.GetAsync() to live web traffic does not appear in Fiddler/Charles
Fiddler/Charles are both up to date versions.
Thanks again
回答1:
You don't need anything in your HOSTS file if you're using Fiddler; you can use Fiddler's Tools > HOSTS to redirect traffic anywhere you'd like.
When trying to capture traffic from a service account (e.g. the ASP.NET acccount) you typically want to configure that account to use the proxy; see http://fiddler2.com/blog/blog/2013/01/08/capturing-traffic-from-.net-services-with-fiddler for details on that. If you do that, you shouldn't need to configure the proxy object directly in code.
The exception you've shown suggests that here's a bug in the GenerateProxyRequestLine function. Is there any change if you update this: new WebProxy("http://localhost:8888");
to new WebProxy("127.0.0.1", 8888);
?
Generally speaking, .NET applications will bypass the proxy for URLs pointed at //localhost or //127.0.0.1, so when debugging with Fiddler it's common to use a service URL of //localhost.fiddler so that the traffic is always sent to the proxy.
回答2:
I fixed the problem by making the HttpClient static.
This works fine (for the program functionality) but has the problem with fiddler described above, where trying to use the proxy throws an error:
private HttpClient _client()
{
var clientHandler = new HttpClientHandler
{
UseCookies = true,
UseDefaultCredentials = false,
Proxy = new WebProxy("http://localhost:8888"),
UseProxy = true,
AutomaticDecompression = DecompressionMethods.GZip,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic
};
HttpClient client = new HttpClient(clientHandler);
client.Timeout = TimeSpan.FromMinutes(20);
return client;
}
The client was created with:
using (HttpResponseMessage serviceResponse = await _client().GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
{
// Return response
}
However, the below also works and all traffic shows up in Fiddler!
private static readonly HttpClientHandler _clientHandler = new HttpClientHandler()
{
//CookieContainer = cookies,
UseCookies = true,
UseDefaultCredentials = false,
Proxy = new WebProxy("http://localhost:8888"),
UseProxy = false,
AutomaticDecompression = DecompressionMethods.GZip,
AllowAutoRedirect = false,
ClientCertificateOptions = ClientCertificateOption.Automatic,
};
//Create a shared instance of HttpClient and set the request timeout
private static readonly HttpClient _client = new HttpClient(_clientHandler)
{
Timeout = TimeSpan.FromMinutes(20)
};
The client was created with (only difference is removing the '()' after _client above):
using (HttpResponseMessage serviceResponse = await _client.GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
{
// Return response
}
I have no clue why this works. Any insight would be appreciated.
Thanks,
来源:https://stackoverflow.com/questions/17824555/how-to-make-httpclient-relay-traffic-show-up-in-fidder-or-charles