Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Detecting Servlet timeout using ajax/post.

 
marten kay
Ranch Hand
Posts: 178
Java jQuery Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I am developing a one page app with a lot of ajax interaction using the post method. When the server session times out the web page remains interactive with client script but the server calls fail silently. I would like to detect the timeout and then alert the client using some script already on the client.

My client functions calling the server use the $.globalEval(data) method and looks like this


When the server times out it returns the following which I can access through firebug.



I have attempted to identify the timeout using the .error() method on the jqXHR Object with no success, as there is no error.

Is there a neat way of doing this?

Thanks
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 64824
86
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In other words, your server code sends you to the login page regardless of whether the request is an Ajax request or not? Correct?

Fix your server0side code to return an error rather than the login page when the request is an Ajax request. (Look at the request headers.)
 
marten kay
Ranch Hand
Posts: 178
Java jQuery Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you are correct, but where can I get access to the headers? The request does not seem to arrive at requested servlet when the session is timed out so I can't do anything there.

I'm using form based authentication out of the box, so as I understand the Container replies with login page, and I'm not sure how I intercept that?

Do I need to go poking around the container?
 
Tim Holloway
Saloon Keeper
Pie
Posts: 18152
52
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
marten kay wrote:
I'm using form based authentication out of the box, so as I understand the Container replies with login page, and I'm not sure how I intercept that?


You can't. For one thing, the architecture of the J2EE security system isolates the login process completely from the application. If you wanted to switch from FORM-based authentication to BASIC authentication, no program logic changes apply - you just change the setting in web.xml.

Servlets don't timeout. That's because HTTP is not a fully-conversational client/server protocol where you'd connect, chat back and forth, and finally hang up. In HTTP, the end of each servlet response causes the server to disconnect and no further communication will ever be done unless the client makes another request, when the cycle repeats itself.

Sessions timeout. However, every URL request you make causes the session timeout clock to be reset to the beginning. So you can't "poll for timeout" on a session. AJAX requests are URL requests, so they, too reset the session timeout clock.

I didn't totally understand the question, but if the point is that your AJAX requests are coming in far enough apart that the user session has timed out and redirected the AJAX request to the login form, you need to either find a way to avoid the timeout (via setting a long session time, "keep-alive" polling, or whatever) or you need to sensitize the jQuery to the fact that the user has timed out. I DON'T recommend that the jQuery attempt a login itself, since making the JavaScript retain user credentials is a security risk that you should only venture in carefully-controlled environments.
 
marten kay
Ranch Hand
Posts: 178
Java jQuery Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Tim

The scenario is that the user interacts with the page on the client, most interactions use functions loaded to the client on load, for other interactions an asynchronos call is made to server, such as to save content on the server. So if a user comes back to the page after being away for a while and the session has timed out, the server no longer sends back the required content and the page just sits there. My preference would be for the user to be redirected to a login screen when this happens.

As you say I can't change the behaviour of the container, and the best solution probably is to

sensitize the jQuery to the fact that the user has timed out


So I need to figure out a way of detecting that the session has timed out, perhaps by saying, if the server returns

then make a get to the login page. But this does not seem elegant.

I will see if there is anything in the headers sent back to client that client can access and use to determine if it is logged out.

Cheers
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 64824
86
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah... yes, using servlet authentication certainly changes the scenario. I do not believe that there will be any indication on the response that the request was Ajax-originated.
 
Sean Clark
Rancher
Posts: 377
Android Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,

Could you not write a Filter which only intercepts AJAX requests (either by looking for a parameter e.g ajax=true or extension e.g. /page.ajax) and check to see whether the current HttpSession is valid using HttpServletRequest isRequestedSessionIdValid() and if it is not valid send back an error code, otherwise allow it to continue?

[Edit: ah I'm not sure that would work using container authentication, sorry]

Sean
 
Tim Holloway
Saloon Keeper
Pie
Posts: 18152
52
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Moving in reverse order:

1. No, you can't use a servlet filter. The container intercepts the URL first, and if it doesn't like it, the app (and servlet filter) never get informed at all.

2. While it might be possible to scan for AJAX signatures, there's no standard "I'm an AJAX" call info. What I did in one app, however, was use AJAX-REST and pass an "ajax=true" parameter to the responding servlet.

3. You CANNOT explicitly request the login page via a URL. If you try, you'll simply get a page that won't submit properly. So if your AJAX client detects a logged-out condition, what it needs to do is forward to a protected page - any protected page. If you have a protected application Home page (or alternate URL to the Home page that's protected), that's a good one to use.

Another alternative is to forward to an error-reporting page, which can then have a login button/link that references a protected URL.
 
marten kay
Ranch Hand
Posts: 178
Java jQuery Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks

I will try and get the client to request a secured page (and not the login page)

But I'm not able to determine anything from the response headers.

using the following code


I get the same headers for both timed in and timed out sessions, mainly
  • Server:Apache-Coyote/1.1
  • Content-Type:text/html;charset=UTF-8
  • Content-Length:xxx
  • Date: xxx,xxxxxx xx:xx:xx GMT


  • cheers
     
    Tim Holloway
    Saloon Keeper
    Pie
    Posts: 18152
    52
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    marten kay wrote:thanks

    But I'm not able to determine anything from the response headers.


    I'm not surprised. However, since the Login and LoginFail form pages are JSPs, you could always add a "signature header" of your own to the JSP definitions and look for that.

    Something like

    X-Login-Form: true
     
    marten kay
    Ranch Hand
    Posts: 178
    Java jQuery Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    where do I add headers to the Container's JSP definitions? does the security allow this?

    In the meantime, this is a hack that works

    this works but is a bit of a hack, a valid server response containing the string "j_security_check" will always appear as timed out at the client.

     
    Tim Holloway
    Saloon Keeper
    Pie
    Posts: 18152
    52
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Not only does security allow it, it encourages it. In fact, certain custom headers such as content-type have their own special JSP directives. I'd have to RTFM to get the exact syntax.

    Just make sure that the headers are declared before any of the HTML, because once you start sending HTML, you'll get an InvalidStateException. All headers go out before any content.

    It's not especially kludgy to be scanning for the j_security_check, since it's always in login pages, and never useful for anything else. Just usually a little more convenient/efficient to look at headers than scan the page content.
     
    marten kay
    Ranch Hand
    Posts: 178
    Java jQuery Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Tim!

    got it.

    so on the server side login servlet I have


    which I check on the client side using


    I had totally forgotton that I actually control the login serlvet/jsp, i thought it was the container's.

    Thanks to all , I learnt a lot from this. First time I have travelled into the murky world of headers!

    Cheers
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic