3

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?

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601

4 Answers4

8

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.

Community
  • 1
  • 1
Ben Siver
  • 2,758
  • 1
  • 25
  • 42
  • Rats, hoped that would do it. After taking a closer look at the `libcore.io.Streams` class, my second guess is that you need to append a newline character at the end of your header (the documentation for the `readAsciiLine` method states "throws java.io.EOFException if the stream is exhausted before the next newline character"). Hope that helps. – Ben Siver Oct 28 '13 at 19:29
  • hm good catch however the error is still there. I tried \n at the end of the header, no success. – DarkLeafyGreen Oct 28 '13 at 19:50
  • Odd. It seems like whatever web service is getting hit is returning a response header that isn't getting parsed properly. I would try stepping into `HttpEngine.readResponseHeaders` to see what the response looks like. Sorry I can't be of more help. – Ben Siver Oct 28 '13 at 20:26
  • +1 thx for the infos. This is my own rest webservice. It requires a specific header, or it will return a 403 status. I update my question – DarkLeafyGreen Oct 29 '13 at 07:09
  • This did it for me in an app that normally works fine. The problem only occurred when running in the emulator. API level was set to 23, and Android version to Marshmellow (DISCLAIMER: I know almost nothing about Android, and I don't like mashmellows. I don't even know how to spell them correctly) – Florian Winter Jan 07 '19 at 10:01
1

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.

alexhilton
  • 566
  • 7
  • 10
0

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");
rsc
  • 10,348
  • 5
  • 39
  • 36
0

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.

tangobravo
  • 898
  • 10
  • 24
  • Thanks to Ben Silver's comment in the accepted answer that led me to this. I thought it was worth posting an answer too as comments can be easily missed. – tangobravo Jan 08 '15 at 16:28