DarkLeafyGreen
DarkLeafyGreen

Reputation: 70406

Android EOFException when using HttpURLConnection headers

I sign my http request with a custom authorization header:

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

If anybody is interested in the sha1 method: http://pastebin.com/HRFXQ4Bk The key string is used as header:

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());

When I try to get the response I get following error:

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): at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:579) 10-28 18:25:40.111: E/error(6855): at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:827) 10-28 18:25:40.111: E/error(6855): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283) 10-28 18:25:40.111: E/error(6855): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)

On my server no access was logged by this request. However when I remove the auth header a connection to my server is established according to the server log.

So how does the auth header influence the request? Why is there no connection when using header?


BTW a header like

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

works, however is refused because the authorization header does not match the requirements:

10-29 08:12:07.235: E/error(23663): java.net.ConnectException: failed to connect to api.myserver.net (port 1337): connect failed: ECONNREFUSED (Connection refused) 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)

My webservice requires the header to have following format

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

So this exception is different from the initial exception. When I remove the header and disable authorization on my webservice the connection works as expected. So the problem seems to be with the custom authorization header. Any ideas?

Upvotes: 3

Views: 8739

Answers (4)

alexhilton
alexhilton

Reputation: 576

First, check whether your URL contains unexpected newline ('\n' or '\r\n'), if does, you will get EOFException when read response. The newline will trunk HTTP packages and server thinks client has more data to send, so there is no response. Every attempt to read response will get EOF immediately.

After ensure your request is valid, then try solutions provided by other guys.

Upvotes: 1

tangobravo
tangobravo

Reputation: 926

It might just be due to your server response in that case not quite being correct.

My server was using python SimpleHTTPServer and I was wrongly assuming all I needed to do to indicate success was the following:

self.send_response(200)

That sends the initial response header line, a server and a date header, but leaves the stream in the state where you are able to send additional headers too. HTTP requires an additional new line after headers to indicate they are finished. It appears if this new line isn't present when you attempt to get the result body InputStream or response code etc with HttpURLConnection then it throws the EOFException (which is actually reasonable, thinking about it). Some HTTP clients did accept the short response and reported the success result code which lead to me perhaps unfairly pointing the finger at HttpURLConnection.

I changed my server to do this instead:

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

No more EOFException with that code. It's possible the "Connection: close" solutions trigger some behaviour on certain servers that might work around this (eg ensuring the response is valid before closing) but that wasn't the case with the python SimpleHTTPServer, and the root cause turned out to be my fault.

NB: There are some bugs on Android pre-Froyo (2.2) relating to keep-alive connections but I don't think this is one of them.

Upvotes: 0

rsc
rsc

Reputation: 10669

I started to see that problem when I changed the backend of my Android app from Asp to PHP.

I solved it adding the following line on my PHP page:

header("Connection: close");

Upvotes: 0

Ben Siver
Ben Siver

Reputation: 2948

Looks like it may be a problem with certain versions of Android according to this question.

Try adding conn.setRequestProperty("Connection", "close") to your request.

Upvotes: 8

Related Questions