【问题标题】:How to cancel a persistent connection using NSURLConnection?如何使用 NSURLConnection 取消持久连接?
【发布时间】:2012-11-13 21:46:16
【问题描述】:

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

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

【问题讨论】:

  • 我也有同样的问题。我已经尝试了几种修复方法,但到目前为止都没有奏效。

标签: iphone objective-c ios ssl nsurlconnection


【解决方案1】:

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

我也问了on the apple developer forums这个问题,得到了苹果人的回复。他指给我看这个Apple sample code readme,上面写着:

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

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

这提出了一些有趣的问题,尤其是在您进行调试时。例如,考虑以下序列:

  1. 您使用“调试”选项卡将 TLS 服务器验证设置为已禁用。

  2. 您使用自签名身份连接到站点。连接成功,因为您已禁用 TLS 服务器信任验证。这会向安全传输 TLS 会话缓存添加一个条目。

  3. 您使用“调试”选项卡将 TLS 服务器验证设置为默认值。

  4. 您立即连接到与步骤 2 中相同的站点。由于服务器信任验证策略的更改,这应该会失败,但它会成功,因为您从未收到 NSURLAuthenticationMethodServerTrust 质询。在幕后,安全传输已恢复 TLS 会话,这意味着挑战永远不会冒泡到您的水平。

  5. 另一方面,如果您在第 3 步和第 4 步之间延迟 11 分钟,事情会按预期工作(好吧,按预期失败 :-)。这是因为 Secure Transport 的 TLS 会话缓存有 10 分钟的超时时间。

在现实世界中,这不是一个大问题,但在调试过程中可能会非常混乱。没有编程方式来清除安全传输 TLS 会话缓存,但由于缓存是每个进程的,因此您可以在调试期间通过简单地退出并重新启动应用程序来避免此问题。请记住,从 iOS 4 开始,按下 Home 按钮并不一定会退出您的应用程序。相反,您应该使用从最近的应用程序列表中退出应用程序。

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

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

### 编辑###

我测试了添加一个“。”到ip地址末尾,请求依然成功完成。

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

【讨论】:

    【解决方案2】:

    从 OS X 10.9 开始,NSURLSession 是解决方案。

    【讨论】:

      【解决方案3】:

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

      希望对您有所帮助。

      【讨论】:

      • 我的问题可能解释得不够清楚。 NSURLConnection 对象(conn)被取消就好了,但底层的套接字连接保持打开状态,下次我创建到同一主机的 NSURLConnection 时会重新使用它。这是一个问题,因为我有时需要与主机进行另一次 SSL 握手,并且由于它正在重新使用连接,因此握手已经完成。
      猜你喜欢
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多