设置HTTP代理,在一些优秀的开源或商业的httpClient库,应该是很容易的事,但不包括苹果CFNetwork 和URLSession
2、URLSession HTTP代理设置
1、CFNetwrok HTTP代理设置
首先你要分开CFHTTPMessageRef 和 CFReadStreamRef 这两个,对于HTTP的一些常规设置,有的需要配置前者,有的需要配置后者。HTTP代理设置就配置后者CFReadStreamRef。
代理设置代码也很简单,但要区分HTTP请求还是HTTPS请求,关键字kCFStreamPropertyHTTPProxy
NSDictionary *proxyToUse = nil;
if (scheme_is_https) //HTTPS 代理设置
{
proxyToUse = @{(__bridge NSString*)kCFStreamPropertyHTTPSProxyHost:@"agent.server.cn",
(__bridge NSString*)kCFStreamPropertyHTTPSProxyPort:[NSNumber numberWithInt:8443]
};
}
else //HTTP代理设置
{
proxyToUse = @{(__bridge NSString*)kCFStreamPropertyHTTPProxyHost:@"agent.server.cn",
(__bridge NSString*)kCFStreamPropertyHTTPProxyPort:[NSNumber numberWithInt:8080]
};
if (proxyToUse)
{//设置代理host port
CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxy, (__bridge CFDictionaryRef)proxyToUse);
}
需要注意的是,kCFStreamPropertyHTTPProxy必须要对应一个host和port的字典,你要是分别设置host和port,是不生效的,运行时也不报错。下面的设置就是错误的
CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxyHost, (__bridge CFTypeRef)@"http.server.cn");
CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxyPort, (__bridge CFTypeRef)[NSNumber numberWithInt:8080]);
2、URLSession HTTP代理设置
需要配置session的config NSURLSessionConfiguration.connectionProxyDictionary这个属性
这里面有个坑,对于HTTP代理设置,基本上可以搜索到下面的代码
config.connectionProxyDictionary = @{(__bridge NSString*)kCFNetworkProxiesHTTPEnable:@YES,
(__bridge NSString*)kCFStreamPropertyHTTPProxyHost:@"agent.server.cn",
(__bridge NSString*)kCFStreamPropertyHTTPProxyPort:@(8080),
};
那么对于HTTPS代理,怎么配置呢?
找到kCFNetworkProxiesHTTPEnable的声明文件,CFProxySupport.h,里面有个kCFNetworkProxiesHTTPSEnable声明,是不是想把上面的代码直接替换为kCFNetworkProxiesHTTPSEnable?空欢喜
你会发现编译失败,因为kCFNetworkProxiesHTTPSEnable在IPhone上未定义,未定义,未定义(但是在MAX OS上定义了,这个API设计确实挺贱的)
可行的办法是直接使用字符串“HTTPSEnable”
config.connectionProxyDictionary = @{@"HTTPSEnable":@YES,
(__bridge NSString*)kCFStreamPropertyHTTPSProxyHost:@"agent.server.cn",
(__bridge NSString*)kCFStreamPropertyHTTPSProxyPort:@(8443),
};
别问我这个字符串怎么来的,xcode是可以调试的