iOS any body knows how to add a proxy to NSURLRequest?
Asked Answered
G

4

8

I'm setting up a webview but I need to load the content of the webview using a proxy. Any of you knows how can I'm implement the proxy in NSURLRequest?

for example:

    NSString *location=@"http://google.com";
    NSURL *url=[NSURL URLWithString:location];
    NSURLRequest *request=[NSURLRequest requestWithURL:url];
//    some code to set the proxy

    [self.myWebView loadRequest:request];

I'll really appreciate your help

Gurgitation answered 31/5, 2013 at 0:8 Comment(0)
U
7

Take a look at iOS URL Loading System as well as NSURLProtocol

You can write a custom NSURLProtocol class for your NSURLRequest. A custom NSURLProtocol can intercept your requests and add proxy to each request. the relevant method is -(void)startLoading, inside this method you can use Core-Function which is a little low-level api in iOS to add the proxy to each request:

//"request" is your NSURLRequest
NSURL *url = [request URL];
NSString *urlString = [url absoluteString];

CFStringRef urlStringRef = (CFStringRef) urlString;
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, urlStringRef, NULL);
CFStringRef requestMethod = CFSTR("GET");

CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1);

self.httpMessageRef = CFHTTPMessageCreateCopy(kCFAllocatorDefault, myRequest);

CFReadStreamRef myReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);

// You can add body, headers.... using core function api, CFNetwork.etc

// below code is to set proxy from code if needs
NSString *hostKey;
NSString *portKey;
if ([[[urlString scheme] lowercaseString] isEqualToString:@"https"]) {
    hostKey = (NSString *)kCFStreamPropertyHTTPSProxyHost;
    portKey = (NSString *)kCFStreamPropertyHTTPSProxyPort;
} else {
    hostKey = (NSString *)kCFStreamPropertyHTTPProxyHost;
    portKey = (NSString *)kCFStreamPropertyHTTPProxyPort;
}

//set http or https proxy, change "localhost" to your proxy host, change "5566" to your proxy port 
NSMutableDictionary *proxyToUse = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"localhost",hostKey,[NSNumber numberWithInt:5566],portKey,nil];

CFReadStreamSetProperty(myReadStream, kCFStreamPropertyHTTPProxy, proxyToUse);
CFReadStreamOpen(myReadStream);

hope this can help you.

Do forget to register your custom NSURLProtocol to your delegate.

Undefined answered 26/8, 2013 at 12:14 Comment(1)
Not knowing Objective-C, I tried to implement a custom NSURLProtocol (in my code I'm going to use no-proxy://), but I can't understand a couple of things: 1) why self.httpMessageRef? 2) [urlString scheme] should be [url scheme], am I right?Atmospheric
U
2

You cannot add a proxy to NSURLRequest. You will need to use a 3rd party library like ASIHTTPRequest.

// Configure a proxy server manually
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:@"192.168.0.1"];
[request setProxyPort:3128];
Unhandled answered 31/5, 2013 at 2:15 Comment(2)
ASIHTTPRequest is not being maintained by the developer anymore. Consider using AFNetworking.Disorientate
if you take deep looking at the ASIHTTPRequest, how do setProxyHost and setProxyPortwork, the low level code is pretty much the same as my answer above, ASIHTTPRequest just wrappered all those low level core function code. If it's not being maintained anymore, why dont you just write it by yourself :-).Undefined
D
2

I have used the below code for Http proxy.

let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration();
sessionConfiguration.connectionProxyDictionary = [
    kCFNetworkProxiesHTTPEnable: true,
    kCFNetworkProxiesHTTPPort: myPortInt,
    kCFNetworkProxiesHTTPProxy: myProxyUrlString,
]
let url = NSURL(string: endPointUrl)
let postRequest = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10.0)


let jsonString =  bodyString
postRequest.HTTPBody = jsonString 
postRequest.HTTPMethod = "POST"
postRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")

let session = NSURLSession(configuration: sessionConfiguration)       
let task = session.dataTaskWithRequest(postRequest){}
Doubleganger answered 27/10, 2016 at 15:46 Comment(1)
#40246510Doubleganger
J
0

check out https://github.com/CXTretar/CXProxyURLProtocol it use NSURLProtocol to add proxy for http/https request, support both NSURLConnection and NSURLSession. it works

Jobye answered 10/3, 2023 at 10:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.