web-dev-qa-db-fra.com

Eofexception Android HttpsUrlConnection

J'ai un problème où mon HttpsURLConnection lève une EOFException quand j'essaye de lire n'importe quelle entrée. Le code fonctionne pour certains appels réseau, mais échoue pour d'autres. Si j'essaie de lire quelque chose sur la connexion, cela échoue avec l'erreur susmentionnée.

Exemple:

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

Voici la trace de la pile pour chacun:

avoir une réponse:

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)

Merci pour toute aide,

Meule

EDIT J'ai trouvé ma réponse:

Ce n'était pas une réponse bien documentée. Il apparaît dans certaines des versions les plus récentes d'Android, il existe un bogue avec les connexions d'URL recyclées. Pour résoudre ce problème (bien qu'il puisse y avoir des problèmes de performances), j'avais besoin d'ajouter:

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

Merci!

Meule

41
user1883083

Quelqu'un a demandé que je réponde à ma propre question au lieu de le modifier. Alors voici la réponse à nouveau. 

Ce n'était pas une réponse bien documentée. Il apparaît dans certaines des versions les plus récentes d'Android, il existe un bogue avec les connexions d'URL recyclées. Pour résoudre ce problème (bien qu'il puisse y avoir des problèmes de performances), j'avais besoin d'ajouter:

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

Vous ne spécifiez pas votre serveur, il s'agit donc potentiellement d'un serveur personnalisé que vous avez implémenté vous-même. Il est possible que vos réponses ne soient pas tout à fait correctes selon les spécifications HTTP.

Mon serveur utilisait python SimpleHTTPServer et je supposais à tort que tout ce que je devais faire pour indiquer que le succès était le suivant était le suivant:

self.send_response(200)

Cela envoie la ligne d'en-tête de réponse initiale, un serveur et un en-tête de date, mais laisse le flux dans l'état dans lequel vous pouvez également envoyer des en-têtes supplémentaires. HTTP nécessite une nouvelle ligne supplémentaire après les en-têtes pour indiquer qu'ils sont terminés. Il semble que si cette nouvelle ligne n’est pas présente lorsque vous tentez d’obtenir le corps de résultat InputStream ou le code de réponse, etc. avec HttpURLConnection, une exception EOFException (ce qui est réellement raisonnable, y réfléchissez). Certains clients HTTP ont accepté la réponse courte et ont signalé le code de résultat de réussite qui m'a amené à pointer peut-être injustement du doigt vers HttpURLConnection.

J'ai changé mon serveur pour faire cela à la place (en ajoutant Content-Length pour une bonne mesure):

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

Pas plus EOFException avec ce code. Il est possible que les solutions "Connexion: fermer" déclenchent certains comportements sur certains serveurs (par exemple, s'assurer que la réponse est valide avant de fermer), mais ce n'était pas le cas avec SimpleHTTPServer python, et la cause principale s'est avérée être ma faute.

NB: Il y a quelques bugs sur Android pré-Froyo (2.2) relatifs aux connexions Keep-Alive, mais je ne pense pas qu'il y ait assez d'informations dans cette question pour affirmer qu'il y a des bugs Android sur les nouvelles versions.

1
tangobravo

Commencez par vérifier si votre URL contient une nouvelle ligne inattendue ('\ n' ou '\ r\n'). Si c'est le cas, vous obtiendrez EOFException lors de la lecture de la réponse. La nouvelle ligne envoie les paquets HTTP et le serveur pense que le client a plus de données à envoyer, il n’ya donc pas de réponse. Chaque tentative de lecture de réponse obtiendra immédiatement EOF.

Après vous être assuré que votre demande est valide, essayez les solutions proposées par d’autres personnes.

1
alexhilton

J'utilise NetHttpTransport à partir de google-api-Java-client, de sorte qu'il n'était pas vraiment évident de définir le RequestProperty, j'ai changé pour utiliser ApacheHttpTransport et le problème a disparu.

0
Phuah Yee Keat