Android HttpsUrlConnection eofexception

一个人想着一个人 提交于 2019-11-26 13:01:03

问题


I have a problem where my HttpsURLConnection will throw an EOFException when i try to read any input. The code works for some network calls, but fails on others. If i try and read anything from the connection, it fails with the aforementioned error.

Example:

urlConnect.getResponseCode() // will throw error
urlConnect.getResponseMessage() // will throw error
BufferedInputStream in = new BufferedInputStream(urlConnect.getInputStream()); //will throw error

Here is the stack trace for each:

getResponse:

03-14 09:49:18.547: W/System.err(6270): java.io.EOFException
03-14 09:49:18.547: W/System.err(6270):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:495)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)

BufferedInputStream:

03-14 09:39:14.077: W/System.err(5935): java.io.EOFException
03-14 09:39:14.077: W/System.err(5935):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

Thank you for any help,

Rick

EDIT I found my answer:

This was not a well documented answer. It appears in some of the newer versions of android, there is a bug with recycled url connections. To fix this (although there may be some performance issues), I needed to add:

if (Build.VERSION.SDK != null
&& Build.VERSION.SDK_INT > 13) {
urlConnect.setRequestProperty(\"Connection\", \"close\");
}

Thanks!

Rick


回答1:


Someone requested I answer my own question instead of editing. So here is the answer again.

This was not a well documented answer. It appears in some of the newer versions of android, there is a bug with recycled url connections. To fix this (although there may be some performance issues), I needed to add:

if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
    urlConnect.setRequestProperty("Connection", "close");
}



回答2:


You don't specify your server, so potentially it is a custom one you have implemented yourself. It is possible your responses are not quite correct by the HTTP spec.

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 (adding Content-Length for good measure):

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 there's enough info in this question to claim there are Android bugs on new versions.




回答3:


First, check whether your URL contains unexpected newline ('\n' or '\r\n'), if does, you will get EOFException when reading 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.




回答4:


I use NetHttpTransport from google-api-java-client so it wasn't really apparent how to set the RequestProperty, I switched to use ApacheHttpTransport and the issue is gone.



来源:https://stackoverflow.com/questions/15411213/android-httpsurlconnection-eofexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!