1. 程式人生 > >IPhone Objective-C HTTP代理那些破事

IPhone Objective-C HTTP代理那些破事

設定HTTP代理,在一些優秀的開源或商業的httpClient庫,應該是很容易的事,但不包括蘋果CFNetwork 和URLSession

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是可以除錯的