3

我使用自定义授权标头签署我的 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/error(6855): at libcore.io.Streams.readAsciiLine(Streams.java: 203) 10-28 18:25:40.111: E/error(6855): 在 libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:579) 10-28 18:25:40.111: E/error(6855) : 在 libcore.net.http.HttpEngine.readResponse(HttpEngine.java:827) 10-28 18:25:40.111: E/error(6855): 在 libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283 ) 10-28 18:25:40.111: E/error(6855): 在 libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)

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

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


顺便说一句,像这样的标题

conn.setRequestProperty("Authorization", "FOOBAR");

有效,但是由于授权标头不符合要求而被拒绝:

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

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

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

所以这个异常不同于最初的异常。当我删除标题并禁用我的网络服务上的授权时,连接按预期工作。所以问题似乎出在自定义授权标头上。有任何想法吗?

4

4 回答 4

8

根据this question,某些版本的Android似乎可能存在问题。

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

于 2013-10-28T19:05:53.033 回答
1

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

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

于 2015-01-30T09:19:38.623 回答
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 pre-Froyo (2.2) 上存在一些与保持连接相关的错误,但我认为这不是其中之一。

于 2015-01-08T16:21:32.480 回答
0

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

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

header("Connection: close");
于 2014-10-09T17:13:11.417 回答