kyurkchyan
kyurkchyan

Reputation: 2428

RestSharp portable RestClient Proxy property is not working

Here is what is the issue. I'm using portable RestSharp which uses HttpClient under the hood. But for iOS there is problem with HttpClient, because the Default IWebProxy instance doesn't allow to monitor requests using request monitoring software like Charles (look here to see the issue and the solution ) The solution for this is using CFNetwork.GetDefaultProxy () which returns IWebProxy and set it as proxy of a request. I tried setting the Proxy property of RestClient but it didn't work, when digging in the open source code of portable RestClient I found out that the Proxy property is not used anywhere. The only place where it is used is commented out. That method is called ConfigureProxy line 572 in RestSharp.Portable project RestClient file, and this method is called only from ConfigureHttp method line 541 same file, which is also commented out. I believe this is a bug. May be someone has forgotten to set Proxy after commenting out this code. So can someone tell me wether it will be safe to remove the commented line, or may be say the right place where to set the proxy of IHttp interface? For instance is it safe to set the proxy on the line 393 (this is again in the RestClient file) of the attached image, like

httpRequest.Proxy = this.Proxy;

enter image description here

strong text

Upvotes: 2

Views: 5494

Answers (1)

ZEvS
ZEvS

Reputation: 181

I fixed this issue by myself after 2 days of debugging RestSharp.Portable 3.1.0 source code.

There is a bug in
RestSharp.Portable.HttpClient.Shared - project
DefaultHttpClientFactory - class
CreateMessageHandler - method

Original code is:

if (handler.SupportsProxy && _proxyProperty != null && proxy != null)
{
    _proxyProperty.SetValue(handler, new RequestProxyWrapper(proxy), null);
}

Code does not work because _proxyProperty is null. This field initializes within constructor by reflection.

_proxyProperty = typeof(HttpClientHandler).GetProperty("Proxy");

Simulator initializes this property well, but real iOS device doesn't. I do not know why it happens.

So, here is the code that contains the fix:

if (handler.SupportsProxy && proxy != null)
{
    handler.Proxy = new RequestProxyWrapper(proxy);
}

I have added this fix into my application using reflection. If you want to do the same you should wrap your authenticator(s) or implement dummy one and override two methods:

public override bool CanPreAuthenticate(IHttpClient client, IHttpRequestMessage request, ICredentials credentials)
{
    return true;
}

and

public override async Task PreAuthenticate(IHttpClient client, IHttpRequestMessage request, ICredentials credentials)
{
...
    // get private "handler" field of type DefaultHttpClient from client by reflection here
    // get private "proxy" field of type IWebProxy from "handler" by reflection here
    // set private "proxy" field if it's null by reflection here
...
}

Hope this help. Do not forget to test your solution on each platform:)

I have added new issue on github FubarDevelopment/restsharp.portable

Upvotes: 1

Related Questions