使用HttpURLConnection标头时的Android EOFException

时间:2013-10-28 17:35:47

标签: java android

我使用自定义授权标头签署我的http请求:

String key="client="+USER+",hash="+sha1(STR, API_KEY)+",timestamp="+t.toString();

如果有人对sha1方法感兴趣:http://pastebin.com/HRFXQ4Bk密钥字符串用作标题:

URL url = new URL(sb.toString());

HttpURLConnection conn = null;  
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", key);
conn.setRequestMethod("GET");

InputStreamReader in = new InputStreamReader(conn.getInputStream());

当我尝试获得响应时,我得到以下错误:

  

10-28 18:25:40.111:E / error(6855):java.io.EOFException 10-28   18:25:40.111:E /错误(6855):at   libcore.io.Streams.readAsciiLine(Streams.java:203)10-28 18:25:40.111:   E /错误(6855):at   libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:579)   10-28 18:25:40.111:E /错误(6855):at   libcore.net.http.HttpEngine.readResponse(HttpEngine.java:827)10-28   18:25:40.111:E /错误(6855):at   libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)   10-28 18:25:40.111:E /错误(6855):at   libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)

在我的服务器上,此请求未记录任何访问权限。但是,当我删除auth标头时,根据服务器日志建立与我的服务器的连接。

那么auth头如何影响请求?使用标题时为什么没有连接?


BTW像

这样的标题
conn.setRequestProperty("Authorization", "FOOBAR");
然而,

工作被拒绝,因为授权标头与要求不匹配:

  

10-29 08:12:07.235:E / error(23663):java.net.ConnectException:failed   连接到api.myserver.net(端口1337):   连接失败:ECONNREFUSED(连接被拒绝)10-29 08:12:07.235:   E /错误(23663):at libcore.io.IoBridge.connect(IoBridge.java:114)   10-29 08:12:07.235:E /错误(23663):at   java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)10-29   08:12:07.235:E /错误(23663):at   java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)

我的网络服务要求标题具有以下格式

match(/client=([^,]*),hash=([^,]*),timestamp=([^,]*)/);

因此,此异常与初始异常不同。当我删除标题并禁用我的webservice上的授权时,连接按预期工作。所以问题似乎与自定义授权标头有关。有什么想法吗?

4 个答案:

答案 0 :(得分:8)

根据此question,某些Android版本可能会出现问题。

尝试在您的请求中添加conn.setRequestProperty("Connection", "close")

答案 1 :(得分:1)

首先,检查您的网址是否包含意外的换行符(' \ n'或' \ r \ n'),如果有,您将在读取响应时收到EOFException。新行将中继HTTP包,服务器认为客户端有更多数据要发送,因此没有响应。每次阅读回复的尝试都会立即获得EOF。

确保您的请求有效后,请尝试其他人提供的解决方案。

答案 2 :(得分:0)

当我将Android应用程序的后端从Asp更改为PHP时,我开始发现这个问题。

我解决了它在我的PHP页面上添加以下行:

header("Connection: close");

答案 3 :(得分:0)

这可能只是因为您的服务器响应在这种情况下并不完全正确。

我的服务器正在使用python SimpleHTTPServer,我错误地假设我需要做的就是表明成功如下:

self.send_response(200)

它发送初始响应标题行,服务器和日期标题,但使流处于您能够发送其他标题的状态。 HTTP需要在标题之后添加一个新行以表示它们已完成。当你尝试使用HttpURLConnection获取结果体InputStream或响应代码等时,如果这个新行没有出现,那么它会抛出EOFException(这实际上是合理的,考虑它)。一些HTTP客户端确实接受了短响应并报告了成功结果代码,这导致我可能不公平地指责HttpURLConnection。

我改变了我的服务器来改为:

self.send_response(200)
self.send_header("Content-Length", "0")
self.end_headers()

该代码不再有EOFException。可能的"连接:关闭"解决方案会在某些可能解决此问题的服务器上触发某些行为(例如,在关闭之前确保响应有效)但python SimpleHTTPServer的情况并非如此,并且根本原因证明是我的错。

注意:Android之前的Froyo(2.2)存在一些与保持连接有关的错误,但我不认为这是其中之一。