How to programmatically add a proxy to an NSURLSession

大憨熊 提交于 2019-12-28 02:39:13

问题


Looking over the documentation of NSURLSession and NSURLSessionConfiguration, I was under the impression I should configure it with a dictionary like the following:

    // Create a dictionary to describe the proxy 
    NSDictionary *proxyDict = @{
        (NSString *)kCFProxyHostNameKey   : @"myProxyHost.com",
        (NSString *)kCFProxyPortNumberKey : @"12345",
        (NSString *)kCFProxyTypeKey       : (NSString*)kCFProxyTypeHTTP
    };

    // Create a configuration that uses the dictionary
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    [configuration setConnectionProxyDictionary:proxyDict];

However, the requests from NSURLSession created with this configuration connect directly.


回答1:


It turns out, the dictionary keys you want are the Stream variants, they are the ones that resolve down to "HTTPProxy" and such:

NSString* proxyHost = @"myProxyHost.com";
NSNumber* proxyPort = [NSNumber numberWithInt: 12345];

// Create an NSURLSessionConfiguration that uses the proxy
NSDictionary *proxyDict = @{
    @"HTTPEnable"  : [NSNumber numberWithInt:1],
    (NSString *)kCFStreamPropertyHTTPProxyHost  : proxyHost,
    (NSString *)kCFStreamPropertyHTTPProxyPort  : proxyPort,

    @"HTTPSEnable" : [NSNumber numberWithInt:1],
    (NSString *)kCFStreamPropertyHTTPSProxyHost : proxyHost,
    (NSString *)kCFStreamPropertyHTTPSProxyPort : proxyPort,
};

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
configuration.connectionProxyDictionary = proxyDict;

// Create a NSURLSession with our proxy aware configuration
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

// Form the request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com?2"]];

// Dispatch the request on our custom configured session
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:
                              ^(NSData *data, NSURLResponse *response, NSError *error) {
                                  NSLog(@"NSURLSession got the response [%@]", response);
                                  NSLog(@"NSURLSession got the data [%@]", data);
                              }];

NSLog(@"Lets fire up the task!");
[task resume];



回答2:


If anyone needs the swift version of this:

Swift 3

let sessionConfiguration = URLSessionConfiguration.default
sessionConfiguration.connectionProxyDictionary = [
    kCFNetworkProxiesHTTPEnable as AnyHashable: true,
    kCFNetworkProxiesHTTPPort as AnyHashable: 999, //myPortInt
    kCFNetworkProxiesHTTPProxy as AnyHashable: "myProxyUrlString"
]
let session = URLSession(configuration: sessionConfiguration)



回答3:


Since several of Jeff's answer keys were deprecated I use this ones

NSMutableDictionary *proxy=[NSMutableDictionary dictionaryWithDictionary:@{(__bridge NSString *)kCFNetworkProxiesHTTPEnable  : @1,  (__bridge NSString *)kCFNetworkProxiesHTTPSEnable : @1}];
proxy[(__bridge NSString *)kCFNetworkProxiesHTTPProxy] =host;
proxy[(__bridge NSString *)kCFNetworkProxiesHTTPSProxy]=host;
proxy[(__bridge NSString *)kCFNetworkProxiesHTTPPort]  =port;
proxy[(__bridge NSString *)kCFNetworkProxiesHTTPSPort] =port;
proxy[(__bridge NSString *)kCFProxyUsernameKey]=user;
proxy[(__bridge NSString *)kCFProxyPasswordKey]=password;

configuration.connectionProxyDictionary=proxy;



回答4:


kCFProxyPortNumberKey value should be Int not String




回答5:


Swift 3 extension

extension URLSession {

    func withProxy(proxyURL: String, proxyPort: Int) -> URLSession {

        var configuration = self.configuration

        configuration.connectionProxyDictionary = [
            kCFNetworkProxiesHTTPEnable as AnyHashable : true,
            kCFNetworkProxiesHTTPPort as AnyHashable : proxyPort,
            kCFNetworkProxiesHTTPProxy as AnyHashable : proxyURL
        ]

        return URLSession(configuration: configuration, delegate: self.delegate, delegateQueue: self.delegateQueue)
    }
}

Usage:

let session = URLSession().withProxy(proxyURL: "xxxxxx", proxyPort: 8321)



回答6:


Based on all previous responses, this works for Swift 4, both HTTP and HTTPS:

let proxyHost = "127.0.0.1"
let proxyPort = 8888
let configuration = URLSessionConfiguration.default
configuration.connectionProxyDictionary = [
    kCFNetworkProxiesHTTPEnable: true,
    kCFNetworkProxiesHTTPProxy: proxyHost,
    kCFNetworkProxiesHTTPPort: proxyPort,
    kCFNetworkProxiesHTTPSEnable: true,
    kCFNetworkProxiesHTTPSProxy: proxyHost,
    kCFNetworkProxiesHTTPSPort: proxyPort
]

proxyHost should be a hostname and not contain any URL scheme.



来源:https://stackoverflow.com/questions/28101582/how-to-programmatically-add-a-proxy-to-an-nsurlsession

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!