Swift 2 如何实现需要授权的代理主机和端口?

Posted

技术标签:

【中文标题】Swift 2 如何实现需要授权的代理主机和端口?【英文标题】:Swift 2 How do I implement proxy host and port that requires authorization? 【发布时间】:2016-05-02 17:43:40 【问题描述】:

这是我用来使用代理主机和端口发送请求的代码。我知道实现是正确的,因为我得到了 407 状态码(需要代理身份验证)。我不知道为什么代理服务器的用户名/密码不起作用。凭据正确且代理处于活动状态。

class Request: NSOperation, NSURLSessionDelegate 
    private var URL:NSURL = NSURL()
    private var method: String
    private var params: String
    private var session: NSURLSession = NSURLSession.sharedSession()
    private var cookies: [NSHTTPCookie] = [NSHTTPCookie]()
    private var httpResponse: NSHTTPURLResponse?
    private var contentsOfURL: String?
    private var statusCode: Int?
    var isConnecting = false

    var shouldUseProxy = false
    var proxyHost:CFString!
    var proxyPort:CFNumber!
    var proxyUser:CFString!
    var proxyPW:CFString!

    init(URL: NSURL, method: String, params: String, cookies:[NSHTTPCookie]) 
        self.URL = URL
        self.params = params
        self.method = method
        self.cookies = cookies
    

    override func main() -> () 
        let request = NSMutableURLRequest(URL: self.URL)
        request.HTTPMethod = self.method
        if method == "POST" 
            request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding)
        
        if self.shouldUseProxy 
            let proxyEnable = NSNumber(int: 1) as NSNumber
            let proxyDict: [NSObject:AnyObject] = [
                kCFNetworkProxiesHTTPEnable: proxyEnable,
                kCFStreamPropertyHTTPProxyHost: self.proxyHost,
                kCFStreamPropertyHTTPProxyPort: self.proxyPort,
                kCFStreamPropertyHTTPSProxyHost: self.proxyHost,
                kCFStreamPropertyHTTPSProxyPort: self.proxyPort,
                kCFProxyTypeKey: kCFProxyTypeHTTPS,
                kCFProxyUsernameKey: self.proxyUser,
                kCFProxyPasswordKey: self.proxyPW
            ]
            let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
            config.connectionProxyDictionary = proxyDict
            self.session = NSURLSession.init(configuration: config, delegate: self, delegateQueue: NSOperationQueue())
        

        let task = session.dataTaskWithRequest(request) 
                (data, response, error) in
                if error == nil 
                    let httpResponse = response as! NSHTTPURLResponse
                    let statusCode = httpResponse.statusCode
                    print("statusCode \(statusCode)")
                
            self.isConnecting = false
        
        task.resume()
    

【问题讨论】:

您是否通过嗅探网络连接(例如使用 Charles)来检查通过网络发送的内容?它是否使用 HTTP 而不是 HTTPS 工作? HTTP 会更容易调试。 我在做研究的时候读了一点关于查尔斯的文章。那是像钢丝鲨这样的第三方应用程序吗?我知道如果我在浏览器中使用 Http,它确实可以工作,但它会重定向到 HTTPS。我是否假设无法像在 iPhone 用户界面上那样输入代理服务器设置?我这么说是因为我到处搜索,我唯一能找到的就是上面的内容。 确实像 WireShark。但它也可以通过在手机上添加欺骗 CA 来嗅探 HTTPS。但是,它使用代理进行操作,因此可能会干扰您要调试的代理。我会尝试仅使用 HTTP 设置代理,这样可以更轻松地嗅探连接,因为它是纯文本的。 您可以尝试使用非临时会话。这可能是由临时会话尝试将凭据存储在内存中的方式引起的错误。如果使用非临时会话有效,您可以通过编写适当的会话委托方法、使用自己的仅内存缓存等来模拟临时会话,然后自己存储和处理凭证存储。 【参考方案1】:

为您的配置添加额外的标题。

 func main() -> () 
let request = NSMutableURLRequest(URL: self.URL)
request.HTTPMethod = self.method
if method == "POST" 
    request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding)

if self.shouldUseProxy 
    let proxyEnable = NSNumber(int: 1) as NSNumber
    let proxyDict: [NSObject:AnyObject] = [
        kCFNetworkProxiesHTTPEnable: proxyEnable,
        kCFStreamPropertyHTTPProxyHost: self.proxyHost,
        kCFStreamPropertyHTTPProxyPort: self.proxyPort,
        kCFStreamPropertyHTTPSProxyHost: self.proxyHost,
        kCFStreamPropertyHTTPSProxyPort: self.proxyPort,
        kCFProxyTypeKey: kCFProxyTypeHTTPS,
        kCFProxyUsernameKey: self.proxyUser,
        kCFProxyPasswordKey: self.proxyPW
    ]
    let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
    let config.httpAdditionalHeaders = ["Proxy-Authorization":  Request.authorizationHeader(user: self.proxyUser, password: self.proxyPW) ]
    config.connectionProxyDictionary = proxyDict
    self.session = NSURLSession.init(configuration: config, delegate: self, delegateQueue: NSOperationQueue())


let task = session.dataTaskWithRequest(request) 
    (data, response, error) in
    if error == nil 
        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode
        print("statusCode \(statusCode)")
    
    self.isConnecting = false

task.resume()


【讨论】:

以上是关于Swift 2 如何实现需要授权的代理主机和端口?的主要内容,如果未能解决你的问题,请参考以下文章

ssh隧道代理连接

如何检测远程主机上的某个端口是不是开启

socket如何通过代理服务器通讯,在线等

linux下实现nginx安装实现端口区分,域名区分

nginx如何实现请求转发,方法步骤如下

nginx 80端口反向代理多个域名,怎样隐藏端口的