I'm trying to send a POST request to a specific URL through a proxy server. To test that the code I'm writing is working, I installed squidman on my machine and started a proxy server on port 33074. I tested the proxy server by changing the network settings to use the proxy when making HTTP/HTTPS requests and it's working ok.
Now I wrote the following code:
NSDictionary* proxyConfig = @{
(NSString*) kCFNetworkProxiesHTTPSEnable: @(1),
(NSString*) kCFNetworkProxiesHTTPSProxy: @"127.0.0.1",
(NSString*) kCFNetworkProxiesHTTPSPort: @"33074",
};
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
[sessionConfig setTimeoutIntervalForRequest:60];
[sessionConfig setConnectionProxyDictionary:proxyConfig];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"https://the-host-where-im-posting"]];
[request setHTTPMethod:@"POST"];
[request setValue:[[NSString alloc] initWithFormat:@"%lu",length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:data];
NSURLSession *session = [self createHttpSession];
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode == 200){
//...
} else {
LOGERROR(@"Error: %@", error);
}
}
The problem is that the request is not successfull and the following error is logged:
Error: Error Domain=kCFErrorDomainCFNetwork Code=310 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2096, _kCFStreamErrorDomainKey=4}
Additional Info:
1. It should be noted that the requests submits perfectly without setting the proxyConfig
dictionary.
2. A similar error gets reported if I'm trying to submit the request using HTTP through the proxy (by correspondingly changing the keys in the proxyConfig
dictionary) with a small diff in the Err Code and _kCFStreamErrorCodeKey: 306 instead of 310 and -2094 instead of -2096.
3. The process making the request runs as a daemon.
What exactly am I doing wrong ? What am I missing ?
I was setting the kCFNetworkProxiesHTTPSPort
field from the proxyConfig
dictionary to a value of type NSString
. After carefully reading the documentation for it I observed the following:
Key for the port number associated with the HTTPS proxy; value is a CFNumber which is the port number.
The library was encountering an object that was not a CFNumber
and was using the default port for HTTPS communication to connect to the proxy instead (443). That's bad error handling imho. It was essentially silently trying to make a request using a port that I was not aware of. Changing the proxyConfig
dictionary to the following fixed the problem:
NSDictionary* proxyConfig = @{
(NSString*) kCFNetworkProxiesHTTPSEnable: @(1),
(NSString*) kCFNetworkProxiesHTTPSProxy: @"127.0.0.1",
(NSString*) kCFNetworkProxiesHTTPSPort: @(33074),
};