View Javadoc

1   /*
2    * Copyright 2009-2010 Capgemini
3    * Licensed under the Apache License, Version 2.0 (the "License"); 
4    * you may not use this file except in compliance with the License. 
5    * You may obtain a copy of the License at 
6    * 
7    * http://www.apache.org/licenses/LICENSE-2.0 
8    * 
9    * Unless required by applicable law or agreed to in writing, software 
10   * distributed under the License is distributed on an "AS IS" BASIS, 
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
12   * See the License for the specific language governing permissions and 
13   * limitations under the License. 
14   * 
15   */
16  package net.sourceforge.statelessfilter.backend.plaincookie;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.ByteArrayOutputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.io.OutputStream;
25  import java.security.SignatureException;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.zip.GZIPInputStream;
29  import java.util.zip.GZIPOutputStream;
30  
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  import net.sourceforge.statelessfilter.backend.ISessionData;
35  import net.sourceforge.statelessfilter.backend.support.CookieBackendSupport;
36  import net.sourceforge.statelessfilter.backend.support.CookieDataSupport;
37  
38  import org.apache.commons.lang.StringUtils;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  /**
43   * Backend based on an uncrypted cookie. Can be used for non sensitive data.
44   * Cookie can be compressed to save bandwidth.
45   * 
46   * <p>
47   * Parameters :
48   * </p>
49   * <ul>
50   * <li>cookiename : name of the cookie</li>
51   * <li>compress : enable cookie compression (gzip) when value is "true"</li>
52   * </ul>
53   * 
54   * @author Nicolas Richeton - Capgemini
55   * 
56   */
57  public class PlainCookieBackend extends CookieBackendSupport {
58  	private static final String DESERIALIZE_ERROR = "Cannot deserialize session. A new one will be created"; //$NON-NLS-1$
59  	private static final String ID = "plaincookie"; //$NON-NLS-1$
60  	private static final String PARAM_COMPRESS = "compress"; //$NON-NLS-1$
61  	private static final String PARAM_KEY = "key"; //$NON-NLS-1$
62  	private boolean compress = true;
63  	private String key = null;
64  	Logger logger = LoggerFactory.getLogger(PlainCookieBackend.class);
65  
66  	public PlainCookieBackend() {
67  		setCookieName("s"); //$NON-NLS-1$
68  	}
69  
70  	/**
71  	 * @see com.capgemini.stateless.backend.plaincookie.ISessionBackend#destroy()
72  	 */
73  	@Override
74  	public void destroy() {
75  		// Nothing to do
76  	}
77  
78  	/**
79  	 * @see com.capgemini.stateless.backend.plaincookie.ISessionBackend#getId()
80  	 */
81  	@Override
82  	public String getId() {
83  		return ID;
84  	}
85  
86  	/**
87  	 * @see com.capgemini.stateless.backend.plaincookie.ISessionBackend#init(java.util.Map)
88  	 */
89  	@Override
90  	public void init(Map<String, String> config) throws Exception {
91  		super.init(config);
92  
93  		String compress = config.get(PARAM_COMPRESS);
94  		if (!StringUtils.isEmpty(compress)) {
95  			this.compress = Boolean.parseBoolean(compress);
96  		}
97  		
98  		String key = config.get(PARAM_KEY);
99  		if (!StringUtils.isEmpty(key)) {
100 			this.key = key;
101 		}
102 
103 		if (logger.isInfoEnabled()) {
104 			logger.info("Cookie name: '" + cookieName + "', compression: '" //$NON-NLS-1$//$NON-NLS-2$
105 					+ this.compress + "'"  ); //$NON-NLS-1$
106 			
107 			if( key != null ){
108 				logger.info( "Cookie signature : " + (key != null) );
109 			}
110 		}
111 	}
112 
113 	/**
114 	 * @see com.capgemini.stateless.backend.plaincookie.ISessionBackend#restore(javax.servlet.http.HttpServletRequest)
115 	 */
116 	@Override
117 	public ISessionData restore(HttpServletRequest request) {
118 
119 		try {
120 			byte[] data = getCookieData(request, null, key !=null, key);
121 
122 			if (data != null) {
123 				InputStream inputStream = new ByteArrayInputStream(data);
124 				if (compress) {
125 					inputStream = new GZIPInputStream(inputStream);
126 				}
127 
128 				ObjectInputStream ois = new ObjectInputStream(inputStream);
129 				CookieDataSupport s = (CookieDataSupport) ois.readObject();
130 
131 				if (s.isValid()
132 						&& s.getRemoteAddress().equals(getFullRemoteAddr(request))) {
133 					return s;
134 				}
135 			}
136 		} catch (Exception e) {
137 			logger.info(DESERIALIZE_ERROR, e);
138 		}
139 
140 		return null;
141 	}
142 
143 	/**
144 	 * @see net.sourceforge.statelessfilter.backend.support.CookieBackendSupport#save(net.sourceforge.statelessfilter.backend.ISessionData,
145 	 *      java.util.List, javax.servlet.http.HttpServletRequest,
146 	 *      javax.servlet.http.HttpServletResponse)
147 	 */
148 	@Override
149 	public void save(ISessionData session, List<String> dirtyAttributes,
150 			HttpServletRequest request, HttpServletResponse response)
151 			throws IOException {
152 		try {
153 			if (session != null) {
154 				CookieDataSupport cookieData = new CookieDataSupport(session);
155 				cookieData.setRemoteAddress(getFullRemoteAddr(request));
156 
157 				ByteArrayOutputStream baos = new ByteArrayOutputStream();
158 				OutputStream outputStream = baos;
159 				if (compress) {
160 					outputStream = new GZIPOutputStream(outputStream);
161 				}
162 
163 				ObjectOutputStream oos = new ObjectOutputStream(outputStream);
164 				oos.writeObject(cookieData);
165 				oos.close();
166 				outputStream.close();
167 				baos.close();
168 
169 				setCookieData(request, response, baos.toByteArray(), key !=null, key);
170 
171 				if (logger.isInfoEnabled()) {
172 					logger.info("Cookie size : " + baos.toByteArray().length); //$NON-NLS-1$
173 				}
174 			} else {
175 				setCookieData(request, response, null,key !=null, key);
176 			}
177 		} catch (SignatureException e) {
178 			throw new IOException(e);
179 		}
180 	}
181 }