Menu

session caching bug

2009-12-01
2013-05-30
  • Jeff Johnston

    Jeff Johnston - 2009-12-01

    Using Freemarker's FreemarkerServlet is giving me problems in that the HttpSessionHashModel caches the HttpSession. This is a problem because if the session is invalidated then an exception is thrown.  

    The problem presented itself when using Spring Security. What happens is that Spring Security creates a new HttpSession, invalidates the old one, and then copies over all the attributes upon a successful login. One of the parameters that gets copied over is the HttpSessionHashModel, which has the old HttpSession inside it.  So we essentially get a session inside a session.

    The code that is causing problems is this  (FreemarkerServlet.createModel()).

    HttpSession session = request.getSession(false);
    if(session != null) {
    sessionModel = (HttpSessionHashModel) session.getAttribute(ATTR_SESSION_MODEL);
    if (sessionModel == null || sessionModel.isZombie()) {
        sessionModel = new HttpSessionHashModel(session, wrapper);
        session.setAttribute(ATTR_SESSION_MODEL, sessionModel);
        if(!sessionModel.isZombie()) {
        initializeSession(request, response);
        }
    }
    }

    The only way to ensure that the HttpSessionHashModel has the current session is to create a new one on every request. The only real downside is that the initializeSession() callback does not make sense because it would be called each time.

        HttpSession session = request.getSession(false);
        if(session != null) {
            sessionModel = (HttpSessionHashModel) session.getAttribute(ATTR_SESSION_MODEL);
            sessionModel = new HttpSessionHashModel(session, wrapper);
            session.setAttribute(ATTR_SESSION_MODEL, sessionModel);
        }

    Any thoughts? Its really a pretty nasty bug! For right now I overwrote the createModel() method and modified it accordingly. 

     
  • Attila Szegedi

    Attila Szegedi - 2009-12-05

    It is a standard practice to store session-specific objects as session attributes. I'd say that the practice of Spring Security, where it invalidates the session, creates a new one, and copies all attributes is an odd one and the one actually responsible for the bug.

    There is an easy way to fix this though: I changed the HttpSessionHashModel.isZombie() method from:

        boolean isZombie()
        {
            return session == null && request == null;
        }                        

    to:

        boolean isOrphaned(HttpSession currentSession)
        {
            return session != currentSession || (session == null && request == null);
        }

    and the code in FreeMarkerServlet#createModel() is now calling isOrphaned accordingly and creating a new HttpSessionHashModel when it returns true. This ensures that initializeSession() is not run too often.

    I fixed this in the tip of the 2.3 branch - can you grab it from the SVN from  and see whether it now works as you'd expect it to.

      : https://freemarker.svn.sourceforge.net/svnroot/freemarker/branches/2.3/freemarker "SVN 2.3.x branch"

     
  • Nobody/Anonymous

    Or just download the freemarker.jar build from ; will be automatically generated soon.

      : http://freemarker.org/builds/

     
  • Jeff Johnston

    Jeff Johnston - 2009-12-07

    Works great! Thanks!!

    I also admire how easy it is to get the source and run the ant build file. Makes it very easy to work with freemarker from the source directly.

     
  • Attila Szegedi

    Attila Szegedi - 2009-12-07

    Yeah, we're lazy - we got tired of assisting people building it, or having to build it for them, so we figured we might as well make it build out-of-the-box ;-)

     

Log in to post a comment.

MongoDB Logo MongoDB