Infinite Javascript Redirect Loop when Stop/Starting Jetty

150 views
Skip to first unread message

Antonio Salazar Cardozo

unread,
Apr 12, 2010, 9:11:07 PM4/12/10
to Lift
Hello all,
We are running into an issue where essentially if we stop and restart
Jetty, the comet request that would usually reload the page with a
window.location call ends up starting a chain reaction that keeps
sending back window.location calls, apparently confusing the browser
and making it make a bunch of requests to that location, while not
actually leaving this page to escape the comet requests.

We managed to trace the redirect itself to the comet code -- it is the
redirect to LiftRules.noCometSessionPage.

Now that I've described the problem, a bit about how it came about to
begin with. Usually this does not happen; however, we are trying to
make it so that sessions will survive a jetty restart, since we're in
early alpha and would like to be able to quickly deploy bug fixes
without worrying about kicking people off. The application also
consists of two parallel services, one of which is not based on Lift,
both of which are proxied to by nginx. Due to an earlier need for both
to have access to the session, we persist the session to the database
and use the JSESSIONID as a lookup token. So as to avoid the issues
with JSESSIONID changing over jetty restarts, we changed to having a
parallel cookie that can let us keep the stored session's token in
sync with a changing session id.

The key here is that the above bug is triggered when we intercept a
call to fetch the current session and reload it from the database if
it is absent and the token cookie is present for us to perform the
lookup. This sets a SessionVar with the session object. If we don't
set the SessionVar, things work fine. If we do set it, things explode
in a shower of sparks.

I'm a little uncertain of how exactly to whittle this down to a
simpler test case, but I'll see what I can do. In the meantime, I was
hoping perhaps at least for some pointers as to debugging options. The
end effect, at least, seems to be pretty deep in Lift, so I'm not
entirely sure where to start (though grepping in the repository did
help pinpoint where the redirect was coming from, at least).
Thanks,
Antonio

David Pollak

unread,
Apr 13, 2010, 1:07:22 PM4/13/10
to lif...@googlegroups.com
Antonio,

Yikes.

The first place I'd suggest looking is at ProtoExtendedSession.scala in Mapper.  This code demonstrates how to do extended sessions in Lift.  The key code is:

  private object myWrapper extends LoanWrapper {
    def apply[N](f: => N): N = {
      (recoverUserId, S.findCookie(CookieName)) match {
        case (Empty, Full(c)) =>
          find(By(cookieId, c.value openOr "")) match {
            case Full(es) if es.expiration.is < millis => es.delete_!
            case Full(es) => logUserIdIn(es.userId)
            case _ =>
          }

        case _ =>
      }
      f
    }
  }

This code wraps the entry into S (statefull) and re-logs-in a User if they are not logged in.

See you can insert code into your app that uses this mechanism.... if it doesn't work, we'll keep cycling to try to make things work for you.

Thanks,

David


--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

Marius

unread,
Apr 13, 2010, 2:01:14 PM4/13/10
to Lift
Do you see this in FF? ... can you reproduce it with Chrome or
Safari ?

Daniel Spiewak had a similar problem as the redirect to
LiftRules.noCometSessionPage didn't actually work on FF. The problem
was window.location. I forgot how Daniel worked around this in his
app, but FF is picky on window.location stuff. I think we need to fix
this on Lift side, but first would be helpful if you can confirm that
this is the behavior you're experiencing.

Br's,
Marius

On Apr 13, 4:11 am, Antonio Salazar Cardozo <savedfastc...@gmail.com>
wrote:

Antonio Salazar Cardozo

unread,
Apr 13, 2010, 4:14:38 PM4/13/10
to Lift
Hah. I should have been paying closer attention to the thread. Yes, I
just realized it's FF only (somehow I forgot cardinal rule #1 of web
development: check in other browsers).

FF is successfully trying to change locations, but doesn't correctly
stop the current page when that happens. So basically, it looks like
the regular Lift comet refresh that sends another comet request to
keep the connection alive is getting a chance to fire even after it
receives a window.location redirect. The reason we are seeing this
happening seems to be timing: if /home (the target of
noCometSessionPage) loads fast enough, then everything works out fine.
It looks like the session refresh code is causing just long enough a
delay that Firefox gets a chance to pay attention to the next
window.location setting, and then the next one, etc. Stopping jetty at
this point will reveal all of the requests are live but never get a
chance to complete, probably because Firefox abandons them in an
attempt to run after the next one.

Webkit, on the other hand, seems to properly abandon the current page
and not run any more scripts on it when it receives that
window.location setting.

I'm trying to think through how we want to fix this in our app. Is
there an early response mechanism where we can basically cancel Lift's
response altogether if we detect a window.location response has
already been sent? I feel like the comet request handlers are low
enough in the priority list that maybe the usual dispatch mechanism
can be used for this.
Thanks,
Antonio

Antonio Salazar Cardozo

unread,
Apr 13, 2010, 5:35:10 PM4/13/10
to Lift
Ok, I've assembled a working fix for this and put it up at
http://gist.github.com/365111 .

Basically at the end of the dispatch table I check for the same
situation that the noCometSessionPage redirect does, and use a
SessionVar to only send back the response once (sending back a 404
otherwise). This correctly stops Firefox from freaking out.

Let me know if this is inefficient (I tried to minimize that by
appending to the dispatch queue, but it still means the check for no
comet session is done twice per comet request) or if anything else
looks ugly.
Thanks,
Antonio

On Apr 13, 4:14 pm, Antonio Salazar Cardozo <savedfastc...@gmail.com>

Marius

unread,
Apr 14, 2010, 2:39:41 AM4/14/10
to Lift
In CometActor you have the unWatch method. Essentially this sends down
to client a JS message cause the Comet script to remove this Comet ID
from it's list. If the list on client side is empty the client won't
send up other comet requests. This is a mechanism that allows you to
avoid noCometSessionPage scenarios. I'm not sure if this is suitable
to your scenarios but just FYI.


Br's,
Marius

On Apr 14, 12:35 am, Antonio Salazar Cardozo

Antonio Salazar Cardozo

unread,
Apr 14, 2010, 12:50:11 PM4/14/10
to Lift
It would be great if that could work :) But in this situation, the
server has been restarted, so all the CometActors are gone. Perhaps
part of what Lift sends down in the same response as the
noCometSessionPage redirect should be a message to the comet script to
clear its list of actors?
Thanks,
Antonio

Marius

unread,
Apr 14, 2010, 1:10:11 PM4/14/10
to Lift
Could you please open a ticket and assign it to me?

On Apr 14, 7:50 pm, Antonio Salazar Cardozo <savedfastc...@gmail.com>

Antonio Salazar Cardozo

unread,
Apr 14, 2010, 1:59:44 PM4/14/10
to Lift
For which one, making noCometSessionPage redirect only once, or making
it clear the actor list?

Marius

unread,
Apr 14, 2010, 3:57:28 PM4/14/10
to Lift
For the initial problem reported that window.location is not reliable
on FF in such circumstances. You don't really need to describe the
solution in the ticket, just your findings.

On Apr 14, 8:59 pm, Antonio Salazar Cardozo <savedfastc...@gmail.com>

Antonio Salazar Cardozo

unread,
Apr 15, 2010, 1:09:54 AM4/15/10
to Lift

Marius

unread,
Apr 15, 2010, 2:44:28 AM4/15/10
to Lift
Thank you.

On Apr 15, 8:09 am, Antonio Salazar Cardozo <savedfastc...@gmail.com>
wrote:
> Ok, cool. Filed it athttps://liftweb.assembla.com/spaces/liftweb/tickets/474-redirects-inv...

Reply all
Reply to author
Forward
0 new messages