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

标签 iphone objective-c ios ssl nsurlconnection

是否可以销毁使用 NSURLConnection 创建的持久连接?我需要能够破坏持久连接并进行另一次 SSL 握手。

就像现在一样,调用 [conn cancel] 会在后面留下一个持久连接,该连接将用于对该主机的下一个连接请求,我不希望发生这种情况。

最佳答案

事实证明,我认为安全传输 TLS session 缓存是罪魁祸首。

我也问了这个问题 on the apple developer forums ,并得到了 Apple 人员的回应。他向我指出了这个 Apple sample code readme它说:

At the bottom of the TLS stack on both iOS and Mac OS X is a component known as Secure Transport. Secure Transport maintains a per-process TLS session cache. When you connect via TLS, the cache stores information about the TLS negotiation so that subsequent connections can connect more quickly. The on-the-wire mechanism is described at the link below.

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

This presents some interesting gotchas, especially while you're debugging. For example, consider the following sequence:

  1. You use the Debug tab to set the TLS Server Validation to Disabled.

  2. You connect to a site with a self-signed identity. The connection succeeds because you've disabled TLS server trust validation. This adds an entry to the Secure Transport TLS session cache.

  3. You use the Debug tab to set the TLS Server Validation to Default.

  4. You immediately connect to the same site as you did in step 2. This should fail, because of the change in server trust validation policy, but it succeeds because you never receive an NSURLAuthenticationMethodServerTrust challenge. Under the covers, Secure Transport has resumed the TLS session, which means that the challenge never bubbles up to your level.

  5. On the other hand, if you delay for 11 minutes between steps 3 and 4, things work as expected (well, fail as expected :-). This is because Secure Transport's TLS session cache has a timeout of 10 minutes.

In the real world this isn't a huge problem, but it can be very confusing during debugging. There's no programmatic way to clear the Secure Transport TLS session cache but, as the cache is per-process, you can avoid this problem during debugging by simply quitting and relaunching your application. Remember that, starting with iOS 4, pressing the Home button does not necessarily quit your application. Instead, you should use quit the application from the recent applications list.

因此,基于此,用户将不得不终止他们的应用并重新启动它,或者等待 10 分钟以上再发送另一个请求。

我用这个新信息做了另一个谷歌搜索并找到了 this Apple technical Q&A article完全符合这个问题。在底部附近,它提到添加尾随“。”请求的域名(希望是 IP 地址)以强制 TLS session 缓存未命中(如果你不能以某种方式修改服务器,我不能),所以我将尝试这个并希望它将工作。我会在测试后发布我的发现。

### 编辑###

我测试了添加“.”到ip地址的末尾,请求仍然成功完成。

但我考虑的是一般问题,确实没有理由强制进行另一次 SSL 握手。就我而言,解决此问题的方法是保留从服务器返回的最后一个已知 SecCertificateRef 的副本。当向服务器发出另一个请求时,如果使用缓存的 TLS session (未调用 connection:didReceiveAuthenticationChallenge:),我们知道保存的 SecCertificateRef 仍然有效。如果connection:didReceiveAuthenticationChallenge:被调用,我们可以在那个时候得到新的SecCertificateRef

关于iphone - 如何使用 NSURLConnection 取消持久连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13369386/

相关文章:

iphone - 获取特定标签栏项目的框架

iphone - 如何在 iPhone 上使用 ffmpeg

ios - CIMedianFilter 是如何工作的? (算法)

iPhone库: file is not of required architecture

iphone - 恢复 iPhone/iPad 应用程序内应用内购买功能

iphone - 如何在 iOS 中最有效和高效地存储数据,尤其是存储便签实例

ios - 我们可以从印度注册 iOS 开发者计划吗

ios - 根据日期删除行

iphone - 构建 10x10 UIButton 网格的最佳方法?

ios - 在 UIImage 和 UIImageViews 中释放 Swift 中的内存