Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing HttpURLConnection so as to keep session alive

We have an Android application that requires the user to enter an answer to a Captcha. The Captcha is generated on our server. When the replies, it is sent to the server for verifying.

Problem is that since I have to close the HttpURLConnection after the request for the Captcha I then find that the reply is running on a different session on the sever. Because of this the Captcha check fails since it is session dependant.

Is there a way to keep the connection alive or should I be following a different path? I know that in the equivalent iPhone application they remain "connected" and thus have the same sessionid.

Edit:

    CookieManager cookieManager = new CookieManager();  
    CookieHandler.setDefault(cookieManager);

    URL urlObj = new URL(urlPath);
    conn = (HttpURLConnection) urlObj.openConnection();

    if (urlPath.toLowerCase().startsWith("https:")) {
        initializeHttpsConnection((HttpsURLConnection) conn);
    }
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Language", "en-US");
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setRequestProperty("Content-Length", Integer.toString(bodyData.length));
    if (_sessionIdCookie != null) {
        conn.setRequestProperty("Cookie", _sessionIdCookie);
    }
    // Connect
    conn.setDoInput(true);
    conn.setDoOutput(true);
    conn.connect();
like image 830
theblitz Avatar asked May 23 '12 06:05

theblitz


People also ask

Can I reuse HttpURLConnection?

You don't. You close this one and create a new one.

Do we need to disconnect HttpURLConnection?

Yes you need to close the inputstream first and close httpconnection next. As per javadoc.

Is HttpURLConnection deprecated?

Deprecated. it is misplaced and shouldn't have existed. HTTP Status-Code 401: Unauthorized. HTTP Status-Code 503: Service Unavailable.

What is the difference between URLConnection and HttpURLConnection?

URLConnection is the base class. HttpURLConnection is a derived class which you can use when you need the extra API and you are dealing with HTTP or HTTPS only. HttpsURLConnection is a 'more derived' class which you can use when you need the 'more extra' API and you are dealing with HTTPS only.


2 Answers

To maintain session using HttpURLConnection you need to execute this part

CookieManager cookieManager = new CookieManager();  
CookieHandler.setDefault(cookieManager);

only once and not on every connection. Good candidate can be on application launch inside Application.onCreate();

like image 100
Grigori A. Avatar answered Sep 20 '22 17:09

Grigori A.


Normally, sessions are not kept based on the http connection itself. That wouldn't make any sense. Sessions are normally kept alive through a cookie on the client side and session information on the server side. What you gotta do is save the cookie(s) you're receiving and then setting that(those) cookie(s) next time you connect to the server.

To learn more about how to work with sessions and cookies with the HttpUrlConnection class, read the documentation: http://developer.android.com/reference/java/net/HttpURLConnection.html

Here a little excerpt to get you started:

To establish and maintain a potentially long-lived session between client and server, HttpURLConnection includes an extensible cookie manager. Enable VM-wide cookie management using CookieHandler and CookieManager:

CookieManager cookieManager = new CookieManager();  
CookieHandler.setDefault(cookieManager);

EDIT:

For those working with API levels 8 or lower, you'll need to use Apache's library!

Here's some reference code:

 // Create a local instance of cookie store
    CookieStore cookieStore = new BasicCookieStore();

    // Create local HTTP context
    HttpContext localContext = new BasicHttpContext();
    // Bind custom cookie store to the local context
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

    HttpGet httpget = new HttpGet("http://www.google.com/"); 

    System.out.println("executing request " + httpget.getURI());

    // Pass local context as a parameter
    HttpResponse response = httpclient.execute(httpget, localContext);

The code above was taken from the Apache's library examples. It can be found here: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.java

EDIT 2: Making it clear:

For the Apache library you need to somehow "connect" the cookie management object with the connection object and you do that through the HttpContext object.

In HttpUrlConnection's case that's not necessary. when you use CookieHandler's static method setDefault, you're setting the system-wide cookieHandler. Below is an excerpt from CookieHandler.java. Note the variable name (from the Android Open Source Project's (AOSP) repository):

 37 /**
 38      * Sets the system-wide cookie handler.
 39      */
 40     public static void setDefault(CookieHandler cHandler) {
 41         systemWideCookieHandler = cHandler;
 42     }
like image 29
DallaRosa Avatar answered Sep 19 '22 17:09

DallaRosa