Search code examples
androidhttpurlconnectioneofexceptionhttpsurlconnection

HttpsUrlConnection EOFException


I'm using the following code for post requests

public String executeHttpPost(String uri, String data) {

    HttpURLConnection conn = null;
    URL url = null;
    String s = null;

    try {

        url = new URL(uri);

         conn = (HttpURLConnection) url.openConnection();

        if (conn instanceof HttpsURLConnection) {
            Log.d("HTTPS", "HttpsUrl");
        }

        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(data);
        wr.flush();

        DisplayResponseHeaders(conn);

        s = readStream(conn.getInputStream());
        Log.d("body", s);

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        s = null;
        e.printStackTrace();
    } finally {
        conn.disconnect();
    }
    return s;
  }

When I use it over http, all works good , but over https I get

 java.io.EOFException
 at libcore.io.Streams.readAsciiLine(Streams.java:203)
 at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
 at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
 at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
 libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
 libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
 ru.fors.remsmed.fragment.NetHelper.executeHttpPost(NetHelper.java:234)
 ru.fors.remsmed.LoginActivity$UserLoginTask.doInBackground(LoginActivity.java:424)
 ru.fors.remsmed.LoginActivity$UserLoginTask.doInBackground(LoginActivity.java:1)
 android.os.AsyncTask$2.call(AsyncTask.java:287)
 java.util.concurrent.FutureTask.run(FutureTask.java:234)
 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
 java.lang.Thread.run(Thread.java:856)
 threadid=14: thread exiting with uncaught exception (group=0x40a71930)

I found the issue about recycling connections bug in httpsurlconnection and possible solution :

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

But it isn't work for me.


Solution

  • Try to change your code like this:

        conn.setRequestProperty("Content-Type",
                                "application/x-www-form-urlencoded; charset: UTF-8");
        byte[] output = data.getBytes("UTF-8");
        conn.setFixedLengthStreamingMode(output.length);
    
        os = conn.getOutputStream();
        os.write(output);
        os.flush();
        os.close();
    
        DisplayResponseHeaders(conn);
    
        if (conn.getResponseCode() == 200) { // or other 2xx code like 204
    
            s = readStream(conn.getInputStream());
            Log.d("body", s);
        }
        else {
    
            // handle error conditions like 404, 400, 500, ...
    
            // now it may be necessary to read the error stream
    
            InputStream errorStream = conn.getErrorStream();
    
            // ...
        }
    

    AFAIK you should always close all streams you opened. I'm not sure whether conn.disconnect() is doing that for you.

    If you want to code your HTTP(S) requests more conveniently, you can have a look at DavidWebb where you have a list of libraries helping you to avoid using cumbersome HttpURLConnection.