I'm trying to get HTTP calls I'm making from C# .NET to a local address (localhost:3000) to use the proxy I set (so I can go through fiddler). Using the below WebProxy approach works if I point the target URL to a non-local address, however I need to point it to a local web-server I have (at localhost:3000), and when I do this the request is not going through the proxy.
I have inlcuded the "proxyObject.BypassProxyOnLocal = false". This should make it work no? Any suggestions re how to force the request to go through the WebProxy for http calls targetting a local address?
WebProxy proxyObject = new WebProxy("http://localhost:8888/", false);
proxyObject.Credentials = new NetworkCredential();
proxyObject.BypassProxyOnLocal = false;
WebRequest.DefaultWebProxy = proxyObject;
var request = (HttpWebRequest)WebRequest.Create(targetUri);
// I also included this line as a double check
request.Proxy = proxyObject;
Subsequent calls do not go through the proxy however, such as when I do:
var res = (HttpWebResponse)req.GetResponse();
thanks
I get around this simply by appending a "dot" to localhost, so instead of accessing "localhost", I try to access "localhost." (notice the dot at the end of the hostname)
Credit where credit is due:
I got this unusual tip from this thread http://www.west-wind.com/weblog/posts/2009/Jan/14/Monitoring-HTTP-Output-with-Fiddler-in-NET-HTTP-Clients-and-WCF-Proxies#596591
Works fine!
See explanation on https://docs.telerik.com/fiddler/observe-traffic/troubleshooting/notraffictolocalhost
Internet Explorer and the .NET Framework are hardcoded not to send requests for Localhost through any proxies, and as a proxy, Fiddler will not receive such traffic.
The simplest workaround is to use your machine name as the hostname instead of Localhost or 127.0.0.1. So, for instance, rather than hitting http://localhost:8081/mytestpage.aspx, instead visit http://machinename:8081/mytestpage.aspx.
Related
I am trying to make a Soap call to a webservice hosted by business partner. The problem I am having is that our client is hosted on a virtual PC with multiple IPs. I would like to call the hosted webservice with a different (not default) IP address. Why is that? There is VPN connection between our client application and hosted webservice but it is set up LAN2LAN between two IPs. Now I have to change local source IP address to match with the VPN requirements.
I have tried using SoapHttpClientProtocol's WebProxy, setting its value to the new IP but it does not seem to work. I am getting HTTP 404 error.
Here is some of the code:
//soapApiClient is typeof SoapHttpClientProtocol
//endpoint url -> webservice, url from appSettings
var url = SettingsProvider.ClientSapGetUserDataUrl;
soapApiClient.Url = url;
//proxy settings -> setting new IP, defined in appSettings
var proxy = SettingsProvider.ClientProxyAddress;
soapApiClient.Proxy = new WebProxy(proxy);
//credentials
soapApiClient.Credentials = GetCredentials();
I HTTP post user code and return value should be user data from SAP, currently I am getting 404 http error code. For comparison, it works like a charm from SoapUI. Maybe setting proxy is not what I am looking for? Any help would be much appreciated.
EDIT: To be more clear
Currently, by default service is called from default ip 91.185.201.88. Service's IP is 10.67.145.70. I want to change it like so: service is called from 192.168.4.2 to service's 10.67.145.70.
I finally managed to make it work. If anyone else will have problem with this, just follow these instructions.
Before calling remote service, you have to find service point for it. This is done via ServicePointManager like so
Example:
var servicePointUserReader = ServicePointManager.FindServicePoint(new Uri(FULLY QUALIFIED REMOTE SERVICE URL));
servicePointUserReader.BindIPEndPointDelegate = (sp, remote, retryCount) => new IPEndPoint(IPAddress.Parse(SOURCE IP FROM WHICH YOU WANT TO SEND REQUEST), 0);
In my example, fully qualified remote service url was something like http://65.145.63.71:8010/sapService (this is the one we are trying to call). Then I wanted to make a call from a different IP on our virtual PC which has many IPs addressed to it. You just need to input desired IP as shown in the second line of the code, for example 192.168.5.1.
Make sure you use "http://" when calling FindServicePoint with new Uri() constrcutor otherwise it will not work!
After that just proceed with the call to the service. Two lines of code, that's all you need. :)
I am not sure i am doing correctly or not
Would below way prevent DNS lookup when keep-alive is set false?
The host is : tatoeba.org
The url is : http://188.213.24.161/eng/sentences/show/1
Here screenshots
the url is given as above
the host is set as below
I believe that if you specify your host as an ip address (as you did), then .net will skip the dsn look up (regardless of the keep alive or the host header setting).
If you dig a little bit into HttpClient you will see it basically uses HttpWebRequest for making the requests. https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs
HttpWebRequest eventually uses a class called ServicePoint which call a
Dns.TryInternalResolve.
Dns.TryInternalResolve doesn't try to resolve IPAddresses.
For more info refer to:
https://referencesource.microsoft.com/#System/net/System/Net/DNS.cs,f8023b9c19212708
I also tried to verify that by running the following lines and monitor the requests using netmon
using (HttpClient c = new HttpClient())
{
var response = c.GetAsync(url).Result;
}
I saw that indeed for a url that contains an host name .net issue a dns request while for requests with an ipAddress as an host name there is no dns request.
I have App that makes use of some web service and acquire data via JSON, all was working fine for quite long time, up until latest discoveries about SSLv3 being vulnerable to man-in-the-middle attacks and server owners turning off SSLv3 for good. My application started to have problems connecting and returned error "Request was aborted: cannot establish secure SSL/TLS connection". I've tried to look for solution and found information i got to add this code before creating web request:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = delegate{
return true;
};
Unfortunately no luck here, app acts the same as before, and I have no clue if this code does nothing or there is still some problem with server. Error information is pretty vague and i have problem figuring where things go wrong.
Here is my code
...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = GetRequestContentType();
request.Method = method.ToString();
request.Credentials = GetCredential(url);
request.PreAuthenticate = true;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
...
I want to ask how to set Tls12 to be used as default and ensure that at my end request I make is with desired protocol.
If I confirm that my app at my end works fine, is there way to get more detailed information from server response and pinpoint precise reason of error?
Thanks for all answers and suggestions.
EDIT
Second part of question is solved, I found this tool http://www.telerik.com/download/fiddler it pretty much allows to see what is going on with outgoing and incoming data. There is also thing that this tool allow to decode SSL connections, enabling this option makes that my application starts to work. I assume that this app does something that make communication between my app and destination host possible. But i do still have no idea what it could be. And how to make my app to handle these connections properly by itself.
Being desperate made me to inspect whole source code (part responsible for getting data of the internet was 3rd party and until it worked fine there was no reason to change it) and I discovered that line
request.Credentials = GetCredential(url);
called method that in its body had
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
So all my attempts to change that value before creating httpwebrequest was overwritten. Changing SecurityProtocolType to Tls12 makes it all work now.
I am able to fix a problem with a client where they cannot authenticate through a proxy doing the following:
var proxy = WebRequest.GetSystemWebProxy();
proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
service.Proxy = proxy;
This works fine for Windows XP, however on Windows 7 I get a 407 (proxy not authenticated exception). Does anybody know what the difference is, and more importantly, what I need to do to get this to work on both OS?
UPDATE
I am having the users check the following:
In the registry editor, can you go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon and let me know what the value is for CachedLogonsCount. f
In the Start box, type in Group Policy and an option to Edit Group Policy should pop up, click on it. Then go to Computer Configuration\Administrative Templates\System\User Profiles\Delete cached copies of roaming profiles and let me know if it is configured, and if so, to what is it set?
UPDATE FOR BOUNTY
So, I added the bounty. I can take a solution from here, or just an alternate means to getting through a proxy on Windows 7...
Another Update
I am not sure if this is useful or not, but we are also doing the following:
service.PreAuthenticate = true;
service.Url = "myurl";
service.Credentials = new NetworkCredential(txt_UserName.Text, txt_Password.Text);
My temporary solution
This is not really a solution, but works for now. I am using the app.config and setting the proxy to be default, with a ByPassList so that the proxy is not even used. This is only doable since the proxy does not have a strong firewall currently. For other clients, I need to get the above to work
This piece of code works for me on XP, Win7 and 2008
var webProxy = new WebProxy(WebRequest.DefaultWebProxy.GetProxy(new Uri({TheURLoftheService})));
webProxy.Credentials = CredentialCache.DefaultCredentials;
webProxy.UseDefaultCredentials = true;
service.Proxy = webProxy;
actually looks like they "fixed" it in Win7 :) Can you confirm that both client and server are specifying http 1.1
Now let's discuss as to why the browser works in this scenario. IE
uses WinINet under the hood rather than WinHTTP. If we look at the
network traces we see that IE sends HTTP/1.1, but the proxy replies
with HTTP/1.0. IE still accepts this behavior, because in the internet
scenario there are countless number of clients and servers which still
use HTTP/1.0.
WinHTTP strictly requires HTTP/1.1 compliance for keeping the
connection alive and HTTP Keep-Alives are not supported in HTTP/1.0
protocol. HTTP Keep-Alive feature was introduced in the HTTP/1.1
protocol as per RFC 2616. The server or the proxy which expects the
keep-alive should also implement the protocol correctly. WinHTTP on
Windows 7, Windows 2008 R2 are strict in terms of security wrto
protocol compliance. The ideal solution is to change the server/proxy
to use the right protocol and be RFC compliant.
http://blogs.msdn.com/b/httpcontext/archive/2012/02/21/changes-in-winhttp-on-windows-7-and-onwards-wrto-http-1-0.aspx
Will this work?
I am using this to set proxy, so far we did not encounter an error on all windows platform
Uri address = new Uri("http://your-webservice-address");
//Get User current network credential
ICredentials credentials = CredentialCache.DefaultCredentials;
NetworkCredential credential = credentials.GetCredential(address, "Basic");
//Get HttpWebRequest
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
//Network Credential should be included on the request to avoid network issues when requesting to the web servic
request.Proxy = WebRequest.DefaultWebProxy;
request.Credentials = new NetworkCredential(credential.UserName, credential.Password, credential.Domain);
It's hard to say based on the code you've given. I'd suspect that it's either your IE settings or your proxy variables.
Check http://social.msdn.microsoft.com/Forums/en/netfxnetcom/thread/61b71194-1758-4c7b-89fe-91be7363db13 it may help.
I am talking to a webservice via a webrequest, I am behind a proxy that requires authentication.
What I would like to do is piggyback off the IE / Control Panel settings but I am having some difficulty...
if I do this, all is fine...
WebProxy proxy = new WebProxy(#"http://my.secret.address:8080");
proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
WebRequest.DefaultWebProxy = proxy;
What I really want to do is simply this...
WebRequest.DefaultWebProxy = WebRequest.GetSystemWebProxy(); // Subsequent webrequest call Fails with a "Unable to connect to remote server" error message.
I really do not want to have to specify the proxy address, as it is not the same for all users. In fact some won't even be behind a proxy. I just want to use the IE /Control Panel settings. Oh I am using Vista in case that makes a difference, and also the proxy settings in th econtrol panel / IE are using an auto config file (proxy.pac file)
Edit: So succinctly. How do I use the IE / Control Panel proxy settings. Including when using an Auto configuration file ?
Further Edit:
Ok, I think I have narrowed down the problem to the Auto Config thing. If I have the proxy address explicitly set in the dialog I can use the .GetSystemWebProxy() settings...but (like in my case) if I am using an Auto Config pac file, I have this issue.
alt text http://img40.imageshack.us/img40/5635/57955210.jpg
In .NET 1.0, you could use:
WebRequest.DefaultWebProxy = WebProxy.GetDefaultProxy();
In 2.0, DefaultWebProxy is supposed to contain the IE proxy settings by default, so this method is obsolete.
http://www.west-wind.com/WebLog/posts/2542.aspx has more information.
UPDATE: Apperently the .NET 2.0 method is now;
WebRequest.DefaultProxy = WebRequest.GetSystemWebProxy();
http://msdn.microsoft.com/en-us/library/system.net.webrequest.getsystemwebproxy.aspx
sigh, well after more investigation I fixed this problem just to get a different one....
The fix is to create the WebProxy with the .pac Uri
WebProxy proxy = new WebProxy(#"http://blahblah/proxy.pac);
Easy peasy...
So now I am getting through the proxy, but the Proxy server is messing with my request and the web service is barffing. (Note it doesn't do it if I am specific about the proxy address....sigh)