Proxy with HTTP Requests - c#

Would it be possible to route a GET request through a proxy by specifying the host as the proxy? Or would you have to set the destination of the packet?
I am trying to generate an HTTPRequestMessage and route it through a proxy. However, I do not have fine level control of setting the destination of the request being sent out.

I was able to add a proxy to HttpClient, HttpWebRequest and HttpRequestMessage. They do not have to be used together, but I just found two ways of making HTTP Requests with proxy. To do this in windows store/metro applications, you would have to implement IWebProxy.
Take a look at this for implementing IWebProxy: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/6e20c2c0-105c-4d66-8535-3ddb9a048b69/bug-missing-type-webproxy-cant-set-proxy-then-where-is-the-appconfig
Then all you need to do is set the proxy for HttpClient or HttpWebRequest:
HttpClient:
HttpClientHandler aHandler = new HttpClientHandler();
IWebProxy proxy = new MyProxy(new Uri("http://xx.xx.xx.xxx:xxxx"));
proxy.Credentials = new NetworkCredential("xxxx", "xxxx");
aHandler.Proxy = proxy;
HttpClient client = new HttpClient(aHandler);
HttpWebRequest:
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.CreateHttp(uri);
IWebProxy proxy = new MyProxy(new Uri("http://xx.xx.xx.xxx:xxxx"));
proxy.Credentials = new NetworkCredential("xxxx", "xxxx");
webrequest.Proxy = proxy;
HttpRequestMessage
Once you construct an HttpRequestMessage, you can use the method above (HttpClient) to send this request message and it will be routed through the proxy without any additional work.

Related

How to conveniently extract single response cookies from a shared static HttpClient without mixing cookies from other parallel requests?

I'm working on a web application that needs to proxy some requests to some other internal website.
I'm using a shared static HTTP client instance to avoid performance issues, according to these articles:
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
https://medium.com/#nuno.caneco/c-httpclient-should-not-be-disposed-or-should-it-45d2a8f568bc
Obviously, I don't want to blindly store cookies coming back from HttpClient and then blindly send them back because that would mess up cookies coming from different web requests to my website. So, I have turned cookie usage off:
var httpClientHandler = new HttpClientHandler
{
// make sure we don't share cookies
// when sending requests over our shared HttpClient instance
UseCookies = false,
// if API returns a redirect, we want to let the caller handle it
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.GZip
};
var apiClient = new HttpClient(httpClientHandler);
However, there are situations when I need to extract and process cookies from a specific HttpClient web request in my web app.
I can see the required cookies present in HttpResponseMessage headers:
var setCookieHdr = response.Headers.GetValues("set-cookie");
The problem - setCookieHdr is a string and not a convenient CookieCollection.
Is there any simple and thread-safe way to turn the "set-cookie" header into a CookieCollection?
I have seen examples using
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = client.GetAsync("http://google.com").Result;
Uri uri = new Uri("http://google.com");
IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).
but I highly suspect that such approach would lead to race conditions. The handler could have stored the last cookie value coming from a parallel proxy-ed HttpClient response and not the response my proxy controller method is currently working on, because HttpClient is a shared static instance, together with the handler and its CookieContainer.
I need to extract cookies just from this specific response and not mess with any current cookies of the shared static HttpClient - those cookies should be ignored completely to avoid mixing them for multiple parallel requests.

How do I pass credentials with DalSoft.RestClient?

I am attempting to use DalSoft.RestClient to make restful calls to an internal service which requires network credentials (for my use case a default credential) be provided.
The constructor for RestClient provides an overload to pass in an IHttpClientWrapper which I could implement handling credentials, but am hoping there's an out of the box solution for passing credentials to RestClient.
How do I pass credentials to the DalSoft.RestClient?
For any credentials that are set via a header such as basic or oauth you can use the Headers methods. Example for oauth2 bearer token:
dynamic client = new RestClient("http://localhost/");
client
.Headers(new { Authorization = "Bearer " + bearerToken })
.MyResource
.Get();
If you are talking about kerberos or ntlm at the moment there is no method to do this but as you suggested you can implement IHttpClientWrapper to do this. Strangely Credentials are passed to a HttpClient using a HttpClientHandler. Below is an example of how to do this:
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential();
HttpClient client = new HttpClient(handler);
I realize implementing IHttpClientWrapper just to do this isn't ideal, so if you need this functionality I'll look at adding it to the ctor. It would look like this:
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential();
new RestClient("http://localhost/", new Config(handler));
Update this is now supported as of 3.0

C# Windows Store App HTTPClient with Basic Authentication leads to 401 "Unauthorized"

I am trying to send a HTTP GET request to a service secured with BASIC authentication and https. If I use the RESTClient Firefox plugin to do so there is no problem. I am defining the basic-header and sending the GET to the url and I am getting the answer (data in json).
Now I am working on a Windows Store App in C# which is meant to consume the service. I enabled all required capabilities in the manifest and wrote the following method:
private async void HttpRequest()
{
string basic = "Basic ...........";
Uri testuri = new Uri(#"https://...Servlet");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", basic);
Task<HttpResponseMessage> response = client.GetAsync(testuri);
var text = await response;
var message = text.RequestMessage;
}
I tried out many different possibilites like getting the response-string but everything lead to an 401 Status Code answer from the Server.
I looked at many similar problems and my understanding of the communication is the following: Client request -> Server response with 401 -> Client sends Authorization header -> Server response with 200 (OK)
What I don't understand is why I am getting the 401 "Unauthorized" Status Code although I am sending the Authorization header right at the beginning. It would be interesting if someone knows how this is handled in the RESTClient.
The BASIC header is definetly correct I was comparing it with the one in the RESTClient.
It would be great if someone could help me with this.
Thanks in advance and kind regards,
Max
Was having a similar problem, i added a HttpClientHandler to HttpClient.
var httpClientHandler = new HttpClientHandler();
httpClientHandler.Credentials = new System.Net.NetworkCredential("","")
var httpClient = new HttpClient(httpClientHandler);
Credentials should be encoded, before adding to the header. I tested it in WPF app, It works...
string _auth = string.Format("{0}:{1}", "username", "password");
string _enc = Convert.ToBase64String(Encoding.UTF8.GetBytes(_auth));
string _basic = string.Format("{0} {1}", "Basic", _enc);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization",_basic);

Restful, Proxy and webapi

I'm developing a consumer app for a publically avalible rest webservice.
I'm having 2 problems: My proxy and the service authentication.
i cant seem to get past my proxy, actually i do have a valid credential to get by it, but i dont know where or how to provide it!
And second, i also dont know how to responde the basic authentication challenge issued by the web-service...
I do can use it via browser, but i cant get it working on my c# app. Heres the code so far:
HttpClient cli = new HttpClient();
cli.BaseAddress = new Uri("http://myserver.com/");
HttpResponseMessage response = cli.GetAsync("api/service1").Result;
textBox1.Text = response.Content.ReadAsStringAsync().Result;
the result in textBox1 so far is always a 407 error... Can anyone help?
Edit1: Authentication on the webservice is of the type BASIC!
Edit2: clientHandler.Credentials = new NetworkCredential("user", "P#ssw0rd"); does not work... server returns "This request requires HTTP authentication"
Proxy information needs to be configured on the HttpClientHandler object which can be passed into the HttpClient constructor.
var clientHandler = new HttpClientHandler();
clientHandler.Proxy = new WebProxy("http://proxyserver:80/",true);
var httpClient = new HttpClient(clientHandler);
For credentials I do something like this...
var clientHandler = new HttpClientHandler() {PreAuthenticate = true};
var credentialCache = new CredentialCache();
credentialCache.Add(new Uri(Host), "Basic", new NetworkCredential(userName, password));
clientHandler.Credentials = credentialCache;
By setting this up this way, whenever you make a request to any URI that is below the "Host" URI, HttpClientHandler will automatically set the correct authorization header.
Also, be aware there is an alternative handler called WebRequestHandler that can be used instead of HttpClientHandler that add in extra stuff that is only available on the Windows OS like WinINet proxy and Pipelining.

How to set proxy without credentials to WebClient c.net

I have a proxy and port number but don't have credentials .how can iset the webclient to go through that proxy ,the below code is giving error
string proxyserver = "http://10.0.0.127:8080/";
IWebProxy proxy = new WebProxy(proxyserver);
proxy.Credentials = CredentialCache.DefaultCredentials;
WebClient.Proxy = proxy;
byte[] rawResponse = WebClient.UploadFile(url, filename);
If i use CredentialCache i don't have authenticationtype and networkcredential. Is there any other way to assign my proxy to the WebClient
thanks,
michaled
Unless the code you have supplied is only a portion of your actual code, you will need to associate the proxy created with the WebClient object using the Proxy property (See documentation below):
WebClient.Proxy Property
If you are already doing so then disregard this.

Categories