目标 C - 使用 ASIHTTPRequest 来自 GET 的 HTTP/0.9 响应

Posted

技术标签:

【中文标题】目标 C - 使用 ASIHTTPRequest 来自 GET 的 HTTP/0.9 响应【英文标题】:Objective C - HTTP/0.9 response from GET using ASIHTTPRequest 【发布时间】:2012-04-28 05:12:05 【问题描述】:

我已经开始在我的 ios 项目中使用 ASIHTTPRequest 来执行 REST 服务器方法调用,并且到目前为止非常成功。我只有一个奇怪的间歇性问题。偶尔我会从使用 [ASIHTTPRequest startAsynchronous] 得到以下响应:

HTTP/0.9 200 正常

发生这种情况时,我的服务器方法不会被调用。通常每个方法调用都会返回一个以“HTTP/1.1”开头的响应。我正在使用带有 GeoTrust/RapidSSL 证书的 HTTPS 来保护连接。有趣的是,我发现如果我尝试连接到 SSL 端口 (443) 但指定 'http' 作为协议,我会得到相同的 'HTTP/0.9 200 OK' 响应。

只是为了添加更多信息 - 问题主要发生在应用程序闲置一段时间后。例如。请求成功完成,然后让应用闲置一段时间,然后在下一次请求时出现问题,然后应用继续正常工作。

谁能解释一下可能发生的事情?

非常感谢, 乔纳森

更新:当问题发生时,我在下面粘贴了 ASIHTTPRequest 输出的一些调试信息:

2012-07-12 09:35:49.376 mytestapp[3038:18f07] [CONNECTION] Closing connection #13 because it has expired
2012-07-12 09:35:49.377 mytestapp[3038:18f07] [CONNECTION] Closing connection #14 because it has expired
2012-07-12 09:35:49.378 mytestapp[3038:18f07] [CONNECTION] Closing connection #15 because it has expired
2012-07-12 09:35:49.380 mytestapp[3038:18f07] [CONNECTION] Request #39 will use connection #16
2012-07-12 09:35:49.381 mytestapp[3038:18f07] [CONNECTION] Request #40 will use connection #17
2012-07-12 09:35:49.382 mytestapp[3038:18f07] [CONNECTION] Request #41 will use connection #18
2012-07-12 09:35:49.529 mytestapp[3038:18f07] [STATUS] Request <ASIHTTPRequest: 0x88a1e00> finished downloading data (0 bytes)
2012-07-12 09:35:49.529 mytestapp[3038:18f07] [STATUS] Request <ASIHTTPRequest: 0x88a1e00> received response headers
2012-07-12 09:35:49.530 mytestapp[3038:18f07] [AUTH] Request <ASIHTTPRequest: 0x88a1e00> has passed Basic authentication
2012-07-12 09:35:49.530 mytestapp[3038:18f07] [CONNECTION] Got no keep-alive header, will keep this connection open for 60.000000 seconds
2012-07-12 09:35:49.530 mytestapp[3038:18f07] [CONNECTION] Request #41 finished using connection #18
2012-07-12 09:35:49.531 mytestapp[3038:18f07] [STATUS] Request finished: <ASIHTTPRequest: 0x88a1e00>
2012-07-12 09:35:49.531 mytestapp[3038:15803] responseHeaders=

2012-07-12 09:35:49.531 mytestapp[3038:18f07] [STATUS] Request cancelled: <ASIHTTPRequest: 0x88a1e00>
2012-07-12 09:35:49.532 mytestapp[3038:18f07] [STATUS] Request cancelled: <ASIHTTPRequest: 0x88a0200>
2012-07-12 09:35:49.532 mytestapp[3038:18f07] [STATUS] Request <ASIHTTPRequest: 0x88a0200>: Cancelled
2012-07-12 09:35:49.532 mytestapp[3038:18f07] [CONNECTION] Request #39 failed and will invalidate connection #16
2012-07-12 09:35:49.533 mytestapp[3038:18f07] [STATUS] Request cancelled: <ASIHTTPRequest: 0x88a0a00>
2012-07-12 09:35:49.533 mytestapp[3038:18f07] [STATUS] Request <ASIHTTPRequest: 0x88a0a00>: Cancelled
2012-07-12 09:35:49.533 mytestapp[3038:18f07] [CONNECTION] Request #40 failed and will invalidate connection #17

【问题讨论】:

你的服务器端是什么?您是否通过使用 Wireshark 等数据包嗅探器检查实际网络数据流,绝对 100% 断然排除服务器行为不端? 您的 ISP 是否有可能使用代理? 你试过设置“validatesSecureCertificate = NO;” 感谢 cmets。服务器端是作为 Windows 服务(不是 IIS)运行的 Delphi DataSnap REST 服务器。我有其他应用程序(android、Win32)连接到使用 DataSnap 客户端框架的未遇到此问题的同一服务。我只开始在 iOS 上使用 ASIHTTPRequest,因为 iOS DataSnap 框架有缺陷并导致 EXC_BAD_ACCESS 错误。 ASIHTTPRequest 工作得很好,除了这个问题,在合理使用的情况下每天只发生一次或两次。每次发生时,您只需重试,它就会继续正常。 我一直在使用 Wireshark 将来自我的 Win32/Android 客户端的调用与我的 iOS 客户端进行比较,随后更改了 ASIHTTPRequest 中使用的 HTTP 标头以匹配它们,但这并没有解决问题。 【参考方案1】:

HTTP/0.9 200 OK 是一个不存在的消息头。 HTTP/0.9 被定义为请求:GET &lt;Request-URI&gt; HTTP/0.9 &lt;CRLF&gt;,其响应为[Entity-Body],没有任何状态行和标头。 ()

您的软件某处出现错误。我猜这个请求要么失败,要么还没有收到。

【讨论】:

【参考方案2】:

在这种情况下不确定 IOS 细节,但 HTTP 0.9 已完全放弃。这有明确的原因 - 它不支持“Host:”标头。这意味着单个 IP 根本无法拥有虚拟主机。这些东西在 90 年代末就已经过时了。

这种反应在现实生活中绝不应该发生。如果仍然发生,则某些客户端发出了诸如“GET / HTTP/0.9”之类的请求。但是这些客户在大约 15 年前就消失了。

SSL 是 HTTP 不太了解的东西。所以我相信这不相关。设置 SSL 隧道,然后运行纯 HTTP。

作为结论,我会说您或某人可能触发了过时的方法。而IOS可能只是不知道如何处理它。也许 IOS 方法是包含主机名的有限方法,因此它不会触发。无论如何,如果客户真的在说 0.9,你不应该担心它,因为它无论如何都没有从大多数网站得到正确的答案。如果客户端说 1.1 而你回答 0.9,那么可能会以某种方式误解请求,并且会出现回退机制到可能的最低 HTTP 版本。也许您忘记为请求设置主机名或在其中出现语法错误?

【讨论】:

【参考方案3】:

在网络上有一些关于这个问题的提及,基本上它与持久连接有关,当 Content-length 标头和一些错误服务器返回的内容本身出现问题时。它可能会搞砸浏览器和 iOS 框架,而且它们实际上不会注意到标题。

这里是one of the possible explanations。

尝试禁用持久连接,它应该会有所帮助。这个advice 来自 ASIHTTPRequest 的开发者(情况差不多)。

[httpRequest setShouldAttemptPersistentConnection:NO]; 

【讨论】:

您好,感谢您的回复。我已经尝试禁用持久连接、cookie 持久性、钥匙串持久性、会话持久性、缓存等,但问题仍然存在。

以上是关于目标 C - 使用 ASIHTTPRequest 来自 GET 的 HTTP/0.9 响应的主要内容,如果未能解决你的问题,请参考以下文章

使用 ASIHTTPRequest 下载 plist 只能部分工作

目标 C - 从 WiFi 切换到 3G,反之亦然

用Block封装ASIHttpRequest

IOS-网络(ASIHTTPRequest的使用简介)

ASIHTTPRequest类库简介和使用说明

带有 ASIHTTPRequest 的 ARC