如何取消使用NSURLConnection的持久连接?

是否有可能摧毁已经创buildNSURLConnection的持久连接? 我需要能够销毁持久连接,并执行另一个SSL握手。

就像现在一样,调用[conn cancel]会留下一个持久的连接,这个连接被用于下一个连接请求,这个连接请求我不想发生。

事实certificate,我相信安全传输TLS会话caching是责任。

我也在苹果开发者论坛上提出了这个问题,并得到了苹果一个人的回应。 他指出我这个苹果示例代码自述它说:

在iOS和Mac OS X上,TLS堆栈的底部是一个称为安全传输的组件。 安全传输维护每个进程的TLS会话caching。 当您通过TLS连接时,caching存储有关TLS协商的信息,以便后续连接可以更快地连接。 在线机制在下面的链接中描述。

http://en.wikipedia.org/wiki/Transport_Layer_Security#Resumed_TLS_handshake

这提出了一些有趣的问题,特别是当你正在debugging。 例如,请考虑以下顺序:

  1. 您使用debugging选项卡将TLS服务器validation设置为禁用。

  2. 您使用自签名身份连接到网站。 连接成功,因为您已禁用TLS服务器信任validation。 这会向Secure Transport TLS会话caching中添加一个条目。

  3. 您可以使用“debugging”选项卡将“TLS服务器validation”设置为“默认”。

  4. 您立即连接到与步骤2中所做的相同的站点。由于服务器信任validation策略的更改,这应该失败,但是它会成功,因为您永远不会收到NSURLAuthenticationMethodServerTrust挑战。 在封面之下,安全交通已经恢复了TLS会话,这意味着挑战永远不会起泡到你的水平。

  5. 另一方面,如果你在步骤3和步骤4之间延迟了11分钟,事情就像预期的那样工作了(好吧,如预期那样失败:-)。 这是因为Secure Transport的TLS会话caching有10分钟的超时时间。

在现实世界中这不是一个大问题,但在debugging过程中可能会非常混乱。 没有编程方法来清除安全传输TLS会话caching,但是,由于caching是按进程进行的,因此只需退出并重新启动应用程序即可在debugging过程中避免此问题。 请记住,从iOS 4开始,按主页button不一定会退出您的应用程序。 相反,您应该使用最近的应用程序列表中的退出应用程序。

所以,基于此,用户将不得不杀死他们的应用并重新启动,或者等待超过10分钟,然后再发送另一个请求。

我做了另一个谷歌search这个新的信息,发现这个苹果技术问答文章 ,完全符合这个问题。 在底部附近,它提到了添加尾随的'。' 到域名(希望IP地址)的请求,以强制TLS会话caching未命中(如果你不能以某种方式修改服务器,我不能),所以我要去尝试这个,希望它将工作。 我会在testing后发布我的发现。

###编辑###

我testing了添加'。' 到IP地址的末尾,请求仍然成功完成。

但是我一般都在想这个问题,而且真的没有理由强迫另一个SSL握手。 就我而言,解决这个问题的办法是保留从服务器返回的最后一个已知SecCertificateRef的副本。 在向服务器发出另一个请求时,如果使用了caching的TLS会话( connection:didReceiveAuthenticationChallenge:未被调用),那么我们知道保存的SecCertificateRef仍然有效。 如果connection:didReceiveAuthenticationChallenge:被调用,那么我们可以在那个时候获得新的SecCertificateRef

从OS X 10.9开始,NSURLSession就是解决scheme。

首先,你应该使用[self.conn取消],其次,这就是它所说的。 它取消了自己。 如果您不想再使用NSURLConnection,那么它将不会执行任何操作,如果您再次使用它,则可以设置一个不同的请求,它将连接到给定的服务器。

希望有所帮助。