android httpurlconnection eofexception

Android HttpsUrlConnection eofexception



httpurlconnection (4)

Alguien me pidió que respondiera mi propia pregunta en lugar de editarla. Así que aquí está la respuesta de nuevo.

Esta no fue una respuesta bien documentada. Aparece en algunas de las versiones más recientes de Android, hay un error con las conexiones de URL recicladas. Para solucionar esto (aunque puede haber algunos problemas de rendimiento), necesitaba agregar:

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

Tengo un problema donde mi HttpsURLConnection lanzará una EOFException cuando intento leer cualquier entrada. El código funciona para algunas llamadas de red, pero falla en otras. Si intento leer algo de la conexión, falla con el error mencionado anteriormente.

Ejemplo:

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

Aquí está la traza de pila para cada uno:

obtener una respuesta:

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)

Gracias por cualquier ayuda,

Almiar

EDITAR encontré mi respuesta:

Esta no fue una respuesta bien documentada. Aparece en algunas de las versiones más recientes de Android, hay un error con las conexiones de URL recicladas. Para solucionar esto (aunque puede haber algunos problemas de rendimiento), necesitaba agregar:

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

¡Gracias!

Almiar


No especifica su servidor, por lo que potencialmente es uno personalizado que usted mismo ha implementado. Es posible que sus respuestas no sean del todo correctas por la especificación de HTTP.

Mi servidor estaba usando Python SimpleHTTPServer y asumí erróneamente que todo lo que tenía que hacer para indicar el éxito era lo siguiente:

self.send_response(200)

Eso envía la línea de encabezado de respuesta inicial, un servidor y un encabezado de fecha, pero deja la secuencia en el estado donde también puede enviar encabezados adicionales. HTTP requiere una nueva línea adicional después de los encabezados para indicar que están terminados. Aparece si esta nueva línea no está presente cuando intenta obtener el cuerpo de resultado InputStream o el código de respuesta, etc. con HttpURLConnection, luego emite la EOFException (que en realidad es razonable, pensándolo). Algunos clientes HTTP aceptaron la respuesta corta e informaron el código de resultado exitoso que me llevó a señalar con el dedo de manera injusto a HttpURLConnection.

Cambié mi servidor para hacer esto en su lugar (agregando Content-Length para una buena medida):

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

No más EOFException con ese código. Es posible que las soluciones "Connection: close" desencadenen algún comportamiento en ciertos servidores que puede solucionar esto (por ejemplo, garantizar que la respuesta sea válida antes de cerrarse), pero ese no fue el caso con el Python SimpleHTTPServer, y la causa principal resultó ser mi culpa.

NB: hay algunos errores en Android pre-Froyo (2.2) relacionados con las conexiones para mantener vivo, pero no creo que haya suficiente información en esta pregunta para afirmar que hay errores de Android en las nuevas versiones.


Primero, verifique si su URL contiene una nueva línea inesperada (''/ n'' o ''/ r / n''), si la tiene, obtendrá la excepción EOFException al leer la respuesta. La nueva línea troncalizará los paquetes HTTP y el servidor cree que el cliente tiene más datos para enviar, por lo que no hay respuesta. Cada intento de leer la respuesta obtendrá EOF inmediatamente.

Después de asegurarse de que su solicitud sea válida, pruebe las soluciones proporcionadas por otros usuarios.


Utilizo NetHttpTransport de google-api-java-client por lo que no era realmente evidente cómo configurar la propiedad de solicitud, cambié a usar ApacheHttpTransport y el problema desapareció.