1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.statelessfilter.backend.memcache;
17
18 import java.io.IOException;
19 import java.net.InetSocketAddress;
20 import java.security.SignatureException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import net.sourceforge.statelessfilter.backend.ISessionData;
29 import net.sourceforge.statelessfilter.backend.support.CookieBackendSupport;
30 import net.sourceforge.statelessfilter.backend.support.CookieDataSupport;
31 import net.spy.memcached.MemcachedClient;
32
33 import org.apache.commons.lang.StringUtils;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class MemcacheBackend extends CookieBackendSupport {
53 private static final String DESERIALIZE_ERROR = "Cannot deserialize session. A new one will be created";
54 private static final String ID = "memcache";
55 private static final String PARAM_SERVER = "server";
56 private static final char SEPARATOR = ':';
57 private static final String SESSION_ID = "stateless.memcache.id";
58 MemcachedClient c = null;
59 Logger logger = LoggerFactory.getLogger(MemcacheBackend.class);
60
61 public MemcacheBackend() {
62 setCookieName("mid");
63 }
64
65
66
67
68 @Override
69 public void destroy() {
70 c.shutdown();
71 }
72
73
74
75
76 @Override
77 public String getId() {
78 return ID;
79 }
80
81
82
83
84 @Override
85 public void init(Map<String, String> config) throws Exception {
86 super.init(config);
87
88
89 ArrayList<InetSocketAddress> servers = new ArrayList<InetSocketAddress>();
90 int i = 1;
91 String server = null;
92 String[] memcacheServer = null;
93 while ((server = config.get(PARAM_SERVER + i)) != null) {
94 memcacheServer = StringUtils.split(server, SEPARATOR);
95 servers.add(new InetSocketAddress(memcacheServer[0], Integer
96 .parseInt(memcacheServer[1])));
97 i++;
98 if (logger.isInfoEnabled()) {
99 logger.info("Adding server: " + memcacheServer[0] + " port: "
100 + memcacheServer[1]);
101 }
102 }
103
104
105 if (servers.size() == 0) {
106 servers.add(new InetSocketAddress("localhost", 11211));
107 }
108
109
110 c = new MemcachedClient(servers);
111 }
112
113
114
115
116 @Override
117 public ISessionData restore(HttpServletRequest request) {
118 try {
119 byte[] data = getCookieData(request, null);
120
121 if (data != null) {
122 String id = new String(data);
123 request.setAttribute(SESSION_ID, id);
124
125 CookieDataSupport s = (CookieDataSupport) c.get(id);
126 if (s != null && s.isValid()
127 && s.getRemoteAddress().equals(getFullRemoteAddr(request))) {
128 return s;
129 }
130 }
131 } catch (SignatureException e) {
132 logger.info(DESERIALIZE_ERROR, e);
133 }
134 return null;
135 }
136
137
138
139
140
141
142 @Override
143 public void save(ISessionData session, List<String> dirtyAttributes,
144 HttpServletRequest request, HttpServletResponse response)
145 throws IOException {
146 try {
147 if (session != null) {
148 CookieDataSupport cookieData = new CookieDataSupport(session);
149 cookieData.setRemoteAddress(getFullRemoteAddr(request));
150
151 c.set(session.getId(), 3600, cookieData);
152
153 if (request.getAttribute(SESSION_ID) == null) {
154 setCookieData(request, response, session.getId().getBytes());
155 }
156 } else {
157 setCookieData(request, response, null);
158 }
159
160 } catch (SignatureException e) {
161 throw new IOException(e);
162 }
163 }
164 }