103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.security;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.security.SecureRandom;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Random;
2503928aee4356845252ac6b662d5c72c29903813eJake Slack
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.Cookie;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletRequest;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletResponse;
2903928aee4356845252ac6b662d5c72c29903813eJake Slack
3003928aee4356845252ac6b662d5c72c29903813eJake Slack/**
3103928aee4356845252ac6b662d5c72c29903813eJake Slack * @version $Rev: 4660 $ $Date: 2009-02-25 17:29:53 +0100 (Wed, 25 Feb 2009) $
3203928aee4356845252ac6b662d5c72c29903813eJake Slack */
3303928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class HashCrossContextPsuedoSession<T> implements CrossContextPsuedoSession<T>
3403928aee4356845252ac6b662d5c72c29903813eJake Slack{
3503928aee4356845252ac6b662d5c72c29903813eJake Slack    private final String _cookieName;
3603928aee4356845252ac6b662d5c72c29903813eJake Slack
3703928aee4356845252ac6b662d5c72c29903813eJake Slack    private final String _cookiePath;
3803928aee4356845252ac6b662d5c72c29903813eJake Slack
3903928aee4356845252ac6b662d5c72c29903813eJake Slack    private final Random _random = new SecureRandom();
4003928aee4356845252ac6b662d5c72c29903813eJake Slack
4103928aee4356845252ac6b662d5c72c29903813eJake Slack    private final Map<String, T> _data = new HashMap<String, T>();
4203928aee4356845252ac6b662d5c72c29903813eJake Slack
4303928aee4356845252ac6b662d5c72c29903813eJake Slack    public HashCrossContextPsuedoSession(String cookieName, String cookiePath)
4403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
4503928aee4356845252ac6b662d5c72c29903813eJake Slack        this._cookieName = cookieName;
4603928aee4356845252ac6b662d5c72c29903813eJake Slack        this._cookiePath = cookiePath == null ? "/" : cookiePath;
4703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
4803928aee4356845252ac6b662d5c72c29903813eJake Slack
4903928aee4356845252ac6b662d5c72c29903813eJake Slack    public T fetch(HttpServletRequest request)
5003928aee4356845252ac6b662d5c72c29903813eJake Slack    {
5103928aee4356845252ac6b662d5c72c29903813eJake Slack        for (Cookie cookie : request.getCookies())
5203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
5303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (_cookieName.equals(cookie.getName()))
5403928aee4356845252ac6b662d5c72c29903813eJake Slack            {
5503928aee4356845252ac6b662d5c72c29903813eJake Slack                String key = cookie.getValue();
5603928aee4356845252ac6b662d5c72c29903813eJake Slack                return _data.get(key);
5703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
5803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
5903928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
6003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
6103928aee4356845252ac6b662d5c72c29903813eJake Slack
6203928aee4356845252ac6b662d5c72c29903813eJake Slack    public void store(T datum, HttpServletResponse response)
6303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
6403928aee4356845252ac6b662d5c72c29903813eJake Slack        String key;
6503928aee4356845252ac6b662d5c72c29903813eJake Slack
6603928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_data)
6703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
6803928aee4356845252ac6b662d5c72c29903813eJake Slack            // Create new ID
6903928aee4356845252ac6b662d5c72c29903813eJake Slack            while (true)
7003928aee4356845252ac6b662d5c72c29903813eJake Slack            {
7103928aee4356845252ac6b662d5c72c29903813eJake Slack                key = Long.toString(Math.abs(_random.nextLong()), 30 + (int) (System.currentTimeMillis() % 7));
7203928aee4356845252ac6b662d5c72c29903813eJake Slack                if (!_data.containsKey(key)) break;
7303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
7403928aee4356845252ac6b662d5c72c29903813eJake Slack
7503928aee4356845252ac6b662d5c72c29903813eJake Slack            _data.put(key, datum);
7603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
7703928aee4356845252ac6b662d5c72c29903813eJake Slack
7803928aee4356845252ac6b662d5c72c29903813eJake Slack        Cookie cookie = new Cookie(_cookieName, key);
7903928aee4356845252ac6b662d5c72c29903813eJake Slack        cookie.setPath(_cookiePath);
8003928aee4356845252ac6b662d5c72c29903813eJake Slack        response.addCookie(cookie);
8103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
8203928aee4356845252ac6b662d5c72c29903813eJake Slack
8303928aee4356845252ac6b662d5c72c29903813eJake Slack    public void clear(HttpServletRequest request)
8403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8503928aee4356845252ac6b662d5c72c29903813eJake Slack        for (Cookie cookie : request.getCookies())
8603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
8703928aee4356845252ac6b662d5c72c29903813eJake Slack            if (_cookieName.equals(cookie.getName()))
8803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
8903928aee4356845252ac6b662d5c72c29903813eJake Slack                String key = cookie.getValue();
9003928aee4356845252ac6b662d5c72c29903813eJake Slack                _data.remove(key);
9103928aee4356845252ac6b662d5c72c29903813eJake Slack                break;
9203928aee4356845252ac6b662d5c72c29903813eJake Slack            }
9303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
9403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
9503928aee4356845252ac6b662d5c72c29903813eJake Slack}
96