7

In my android app, I am trying to pull data from server by doing a POST request.

I'm using HttpURLConnection class to make the requests as Apache's HttpClient is no longer maintained by android.

Here's what I'm doing.

private boolean callWS() {
    try {

        // To avoid the bug in httpurlconnection prior froyo which
        // causes the getInputStream to return headers along with response
        if (Build.VERSION.SDK_INT < 8)
            System.setProperty("http.keepAlive", "false");

        mHttpResponseCode = 0;
        mErrorMessage = "";

        // Initialize connection
        URL connectURL = new URL(mServerUrl);

        HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(true);
        conn.setReadTimeout(30000); 
        conn.setConnectTimeout(15000); 
        conn.setRequestMethod("POST");

        // Set some headers
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
        connection.setRequestProperty("Content-Length", mParameters.length() + "");

        // Connect to host
        conn.connect();

        // Write parameters to connection
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(mParameters);
        writer.flush();
        writer.close();

        // Wait for http response code
        mHttpResponseCode = conn.getResponseCode();

        // Read response from connection
        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int read = 0;
        int bufSize = 1024;
        byte[] buffer = new byte[bufSize];

        while (true) {
            read = bis.read(buffer);
            if (read == -1)
                break;
            baf.append(buffer, 0, read);
        }

        // Decompress gzipped response
        if (conn.getHeaderField("Content-Encoding") != null && conn.getHeaderField("Content-Encoding").contains("gzip"))
            mResponseString = decompress(baf.toByteArray());
        else
            mResponseString = new String(baf.toByteArray());

        mResponse.setResponse(mResponseString);         
        isWSCallSuccessfull = true;
    } catch(UnknownHostException unknownHostException) {
        isWSCallSuccessfull = false;
        mErrorMessage = "Unknown host exception";
        unknownHostException.printStackTrace();
        mLogger.putStacktrace(unknownHostException);
    } catch(SocketException socketException) {
        isWSCallSuccessfull = false;
        mErrorMessage = "Socket Exception";
        socketException.printStackTrace();
        mLogger.putStacktrace(socketException);
    } catch(SocketTimeoutException socketTimeOutException) {
        isWSCallSuccessfull = false;
        mErrorMessage = "Socket Timeout Exception";
        socketTimeOutException.printStackTrace();
        mLogger.putStacktrace(socketTimeOutException);
    } catch(SSLException sslException) {
        isWSCallSuccessfull = false;
        mErrorMessage = "SSL Exception";
        sslException.printStackTrace();
        mLogger.putStacktrace(sslException);
    } catch(IOException ioException) {
        isWSCallSuccessfull = false;
        mErrorMessage = "IO Exception " + ioException.getMessage();
        ioException.printStackTrace();
        mLogger.putStacktrace(ioException);
    }

    mResponse.setHttpResponseCode(mHttpResponseCode);
    mResponse.setErrorMessage(mErrorMessage);
    mResponse.isWSCallSuccessful(isWSCallSuccessfull);

    return isWSCallSuccessfull;
}

This works fine on every device except devices running 2.2 (did not try it on 2.1).

In 2.2, it works fine. But if I leave this part of code idle for more than 30s, it returns me with -1 as http response code the very next time.

Another thing to note is that this happens only with HTTPS urls and not with HTTP Urls. I do not want to use HttpsURLConnection class because at times I may want to use http as well.

I'm not closing the connection just to keep the connection alive. What am I doing wrong?

Sudarshan Bhat
  • 3,722
  • 2
  • 24
  • 51
  • do Https connections automatically close after a certain period of time (If nothing is being transferred I mean)? I don't really know much about https connections so this may be totally wrong. (Reading it back I'm not even sure what I said makes sense lol) – Jon Taylor Jul 25 '12 at 11:29
  • -1 is usually when a connection failed for a reason that isn't specified by HTTP code - in your case it sounds like a timeout but it might also be DNS resolution failure, etc... Now, as to _why_ a specific version of Android is timing out, I don't know... – Basic Jul 25 '12 at 13:59
  • Well my idea is if I'm not doing anything wrong, then is this problem only with me? Because searching across web, i found no one having this problem. – Sudarshan Bhat Jul 25 '12 at 14:01
  • 1
    You might simply be running into one of many infamous bugs concerning `HttpUrlConnection`. That class is buggy in Froyo and below. Which is why the Android Engineers suggest using Apache's `HttpClient` in Froyo and below. Check out this post, esp the last paragraph: http://android-developers.blogspot.com/2011/09/androids-http-clients.html – Tony Chan Sep 12 '12 at 17:57
  • @Turbo Yeah I read about that. Using HttpClient only for froyo and lower seems unnecessary complication to me. I am now handling it with retries which works. – Sudarshan Bhat Sep 13 '12 at 05:17

1 Answers1

0

If you want to use Https and Http at the same time and does not want to create a seperate connection -and if HttpsUrlConnection solves your "-1 issue" you can use the following approach:

URLConnection conn = new URL(url).openConnection();
if (conn instanceof HttpsURLConnection) {
  // do stuff with cast to HttpsUrlConection
}
else {
  // do stuff with cast to HttpUrlConnection
}

I took this answer as a reference

Community
  • 1
  • 1
C.d.
  • 9,504
  • 6
  • 37
  • 50