KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > session > SessionModule


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.lib.session;
31
32 import com.caucho.quercus.annotation.Optional;
33 import com.caucho.quercus.env.*;
34 import com.caucho.quercus.lib.OutputModule;
35 import com.caucho.quercus.module.AbstractQuercusModule;
36 import com.caucho.quercus.module.ModuleStartupListener;
37 import com.caucho.util.L10N;
38
39 import javax.servlet.http.Cookie JavaDoc;
40 import javax.servlet.http.HttpServletResponse JavaDoc;
41 import java.util.HashMap JavaDoc;
42 import java.util.Map JavaDoc;
43 import java.util.logging.Logger JavaDoc;
44
45 /**
46  * Quercus session handling
47  */

48 public class SessionModule extends AbstractQuercusModule
49   implements ModuleStartupListener {
50   private static final L10N L = new L10N(SessionModule.class);
51   private static final Logger JavaDoc log
52     = Logger.getLogger(SessionModule.class.getName());
53
54   private static final HashMap JavaDoc<String JavaDoc,StringValue> _iniMap
55     = new HashMap JavaDoc<String JavaDoc,StringValue>();
56
57   /**
58    * Returns the default php.ini values.
59    */

60   public Map JavaDoc<String JavaDoc,StringValue> getDefaultIni()
61   {
62     return _iniMap;
63   }
64
65   public String JavaDoc []getLoadedExtensions()
66   {
67     return new String JavaDoc[] { "session" };
68   }
69
70   public void startup(Env env)
71   {
72     if (env.getConfigVar("session.auto_start").toBoolean())
73       session_start(env);
74   }
75
76   /**
77    * Returns and/or sets the value of session.cache_limiter, affecting the
78    * cache related headers that are sent as a result of a call to
79    * {@link #session_start(Env)}.
80    *
81    * If the optional parameter is not supplied, this function simply returns the existing value.
82    * If the optional parameter is supplied, the returned value
83    * is the old value that was set before the new value is applied.
84    *
85    * Valid values are "nocache" (the default), "private", "private_no_expire",
86    * and "public". If a value other than these values is supplied, then a warning is produced
87    * and no cache related headers will be sent to the client.
88    */

89   public Value session_cache_limiter(Env env, @Optional String JavaDoc newValue)
90   {
91     Value value = env.getIni("session.cache_limiter");
92
93     if (newValue == null || "".equals(newValue)) // XXX: php/1k16
94
return value;
95
96     env.setIni("session.cache_limiter", newValue);
97
98     return value;
99   }
100
101   public Value session_cache_expire(Env env, @Optional LongValue newValue)
102   {
103     Value value = (LongValue) env.getSpecialValue("cache_expire");
104
105     if (value == null)
106       value = env.getIni("session.cache_expire");
107
108     if (newValue != null && ! newValue.isNull())
109       env.setSpecialValue("cache_expire", newValue);
110
111     return LongValue.create(value.toLong());
112   }
113
114   /**
115    * Alias of session_write_close.
116    */

117   public static Value session_commit(Env env)
118   {
119     return session_write_close(env);
120   }
121
122   /**
123    * Encodes the session values.
124    */

125   public static boolean session_decode(Env env, StringValue value)
126   {
127     Value session = env.getGlobalValue("_SESSION");
128
129     if (! (session instanceof SessionArrayValue)) {
130       env.warning(L.l("session_decode requires valid session"));
131       return false;
132     }
133
134     return ((SessionArrayValue)session).decode(env, value.toString());
135   }
136
137   /**
138    * Encodes the session values.
139    */

140   public static String JavaDoc session_encode(Env env)
141   {
142     Value session = env.getGlobalValue("_SESSION");
143
144     if (! (session instanceof SessionArrayValue)) {
145       env.warning(L.l("session_encode requires valid session"));
146       return null;
147     }
148
149     return ((SessionArrayValue)session).encode();
150   }
151
152   /**
153    * Destroys the session
154    */

155   public static boolean session_destroy(Env env)
156   {
157     SessionArrayValue session = env.getSession();
158
159     if (session == null)
160       return false;
161
162     env.destroySession(session.getId());
163
164     return true;
165   }
166
167   /**
168    * Returns the session cookie parameters
169    */

170   public static ArrayValue session_get_cookie_params(Env env)
171   {
172     ArrayValue array = new ArrayValueImpl();
173
174     array.put("lifetime", env.getIniLong("session.cookie_lifetime"));
175     array.put("path", env.getIniString("session.cookie_path"));
176     array.put("domain", env.getIniString("session.cookie_domain"));
177     array.put("secure", env.getIniBoolean("session.cookie_secure"));
178
179     return array;
180   }
181
182   /**
183    * Returns the session id
184    */

185   public static String JavaDoc session_id(Env env, @Optional String JavaDoc id)
186   {
187     Value sessionIdValue = (Value) env.getSpecialValue("caucho.session_id");
188
189     String JavaDoc oldValue;
190
191     if (sessionIdValue != null)
192       oldValue = sessionIdValue.toString();
193     else
194       oldValue = "";
195
196     if (id != null && ! "".equals(id))
197       env.setSpecialValue("caucho.session_id", new StringValueImpl(id));
198
199     return oldValue;
200   }
201
202   /**
203    * Returns true if a session variable is registered.
204    */

205   public static boolean session_is_registered(Env env, String JavaDoc name)
206   {
207     return env.getGlobalValue("_SESSION").get(new StringValueImpl(name)).isset();
208   }
209
210   /**
211    * Returns the object's class name
212    */

213   public Value session_module_name(Env env, @Optional String JavaDoc newValue)
214   {
215     Value value = env.getIni("session.save_handler");
216
217     if (newValue != null && ! newValue.equals(""))
218       env.setIni("session.save_handler", newValue);
219
220     return value;
221   }
222
223   /**
224    * Returns the object's class name
225    */

226   public Value session_name(Env env, @Optional String JavaDoc newValue)
227   {
228     Value value = env.getIni("session.name");
229
230     if (newValue != null && ! newValue.equals(""))
231       env.setIni("session.name", newValue);
232
233     return value;
234   }
235
236   /**
237    * Regenerates the session id
238    */

239   public static boolean session_regenerate_id(Env env,
240                                               @Optional boolean deleteOld)
241   {
242     SessionArrayValue session = env.getSession();
243
244     if (deleteOld)
245       session_destroy(env);
246
247     env.setSession(null);
248
249     String JavaDoc sessionId = env.generateSessionId();
250
251     session_id(env, sessionId);
252
253     session_start(env);
254
255     SessionArrayValue newSession = env.getSession();
256
257     if (session != null) {
258       for (Map.Entry JavaDoc<Value,Value> entry : session.entrySet())
259         newSession.put(entry.getKey(), entry.getValue());
260     }
261
262     return true;
263   }
264
265   /**
266    * Registers global variables in the session.
267    */

268   public boolean session_register(Env env, Value []values)
269   {
270     Value session = env.getGlobalValue("_SESSION");
271
272     if (! session.isArray()) {
273       session_start(env);
274       session = env.getGlobalValue("_SESSION");
275     }
276
277     for (int i = 0; i < values.length; i++)
278       sessionRegisterImpl(env, (ArrayValue) session, values[i]);
279
280     return true;
281   }
282
283   /**
284    * Registers global variables in the session.
285    */

286   private void sessionRegisterImpl(Env env, ArrayValue session, Value nameV)
287   {
288     nameV = nameV.toValue();
289
290     if (nameV instanceof StringValue) {
291       String JavaDoc name = nameV.toString();
292
293       Value var = env.getGlobalVar(name);
294
295       Value value = session.get(nameV);
296
297       if (value.isset())
298     var.set(value);
299
300       session.put(nameV, var);
301     } else if (nameV.isArray()) {
302       ArrayValue array = (ArrayValue) nameV.toValue();
303
304       for (Value subValue : array.values()) {
305         sessionRegisterImpl(env, session, subValue);
306       }
307     }
308   }
309
310   /**
311    * Returns the session's save path
312    */

313   public Value session_save_path(Env env, @Optional String JavaDoc newValue)
314   {
315     Value value = env.getIni("session.save_path");
316
317     if (newValue != null && ! newValue.equals(""))
318       env.setIni("session.save_path", newValue);
319
320     return value;
321   }
322
323   /**
324    * Sets the session cookie parameters
325    */

326   public Value session_set_cookie_params(Env env,
327                                          long lifetime,
328                                          @Optional Value path,
329                                          @Optional Value domain,
330                                          @Optional Value secure)
331   {
332     env.setIni("session.cookie_lifetime", String.valueOf(lifetime));
333
334     if (path.isset())
335       env.setIni("session.cookie_path", path.toString());
336
337     if (domain.isset())
338       env.setIni("session.cookie_domain", domain.toString());
339
340     if (secure.isset())
341       env.setIni("session.cookie_secure", secure.toBoolean() ? "1" : "0");
342
343     return NullValue.NULL;
344   }
345
346   /**
347    * Sets the session save handler
348    */

349   public boolean session_set_save_handler(Env env,
350                                           Callback open,
351                                           Callback close,
352                                           Callback read,
353                                           Callback write,
354                                           Callback directory,
355                                           Callback gc)
356
357   {
358     SessionCallback cb = new SessionCallback(open,
359                                              close,
360                                              read,
361                                              write,
362                                              directory,
363                                              gc);
364
365     env.setSessionCallback(cb);
366
367     return true;
368   }
369
370   /**
371    * Start the session
372    */

373   public static boolean session_start(Env env)
374   {
375     if (env.getSession() != null) {
376       env.notice(L.l("session has already been started"));
377       return true;
378     }
379
380     SessionCallback callback = env.getSessionCallback();
381
382     Value sessionIdValue = (Value) env.getSpecialValue("caucho.session_id");
383     String JavaDoc sessionId = null;
384
385     final HttpServletResponse JavaDoc response = env.getResponse();
386
387     env.removeConstant("SID");
388
389     String JavaDoc cookieName = env.getIni("session.name").toString();
390     boolean generateCookie = true;
391     boolean create = false;
392
393     if (callback != null)
394       callback.open(env, env.getWorkDir().getPath(), cookieName);
395
396     //
397
// Use cookies to transmit session id
398
//
399
if (env.getIni("session.use_cookies").toBoolean()) {
400       if (sessionIdValue != null)
401         sessionId = sessionIdValue.toString();
402
403       if (sessionId == null || "".equals(sessionId)) {
404         Cookie JavaDoc []cookies = env.getRequest().getCookies();
405
406         for (int i = 0; cookies != null && i < cookies.length; i++) {
407           if (cookies[i].getName().equals(cookieName) &&
408               ! "".equals(cookies[i].getValue())) {
409             sessionId = cookies[i].getValue();
410             generateCookie = false;
411           }
412         }
413       }
414
415       if (! generateCookie)
416         env.addConstant("SID", StringValue.EMPTY, false);
417       else if (sessionId == null || "".equals(sessionId)) {
418         sessionId = env.generateSessionId();
419         create = true;
420       }
421     }
422     
423     //
424
// Use URL rewriting to transmit session id
425
//
426
if (env.getIni("session.use_trans_sid").toBoolean() &&
427         ! env.getIni("session.use_only_cookies").toBoolean()) {
428       
429       if (sessionId != null) {
430       }
431       else {
432         if (sessionIdValue != null)
433           sessionId = sessionIdValue.toString();
434
435         if (sessionId == null || "".equals(sessionId)) {
436           String JavaDoc queryString = env.getRequest().getQueryString();
437           if (queryString != null) {
438             String JavaDoc [] queryElements = queryString.split("&");
439
440             for (String JavaDoc queryElement : queryElements) {
441               String JavaDoc [] nameValue = queryElement.split("=");
442
443               if (nameValue.length == 2 && nameValue[0].equals(cookieName))
444                 sessionId = nameValue[1];
445             }
446           }
447         }
448
449         if (sessionId == null || "".equals(sessionId)) {
450           sessionId = env.generateSessionId();
451           create = true;
452         }
453       }
454
455       env.addConstant("SID", new StringValueImpl(cookieName + '=' + sessionId),
456                       false);
457       
458       OutputModule.pushUrlRewriter(env);
459     }
460
461     if (response.isCommitted())
462       env.warning(L.l("cannot send session cache limiter headers because response is committed"));
463     else {
464       Value cacheLimiterValue = env.getIni("session.cache_limiter");
465       String JavaDoc cacheLimiter = String.valueOf(cacheLimiterValue);
466
467       Value cacheExpireValue = (LongValue)env.getSpecialValue("cache_expire");
468
469       if (cacheExpireValue == null)
470         cacheExpireValue = env.getIni("session.cache_expire");
471
472       int cacheExpire = cacheExpireValue.toInt() * 60;
473
474       if ("nocache".equals(cacheLimiter)) {
475         response.setHeader("Expires", "Thu, 19 Nov 1981 08:52:00 GMT");
476         response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
477         response.setHeader("Pragma", "no-cache");
478       }
479       else if ("private".equals(cacheLimiter)) {
480         response.setHeader("Cache-Control", "private, max-age=" + cacheExpire + ", pre-check=" + cacheExpire);
481       }
482       else if ("private_no_expire".equals(cacheLimiter)) {
483         response.setHeader("Cache-Control", "private, max-age=" + cacheExpire + ", pre-check=" + cacheExpire);
484       }
485       else if ("public".equals(cacheLimiter)) {
486         response.setHeader("Cache-Control", "max-age=" + cacheExpire + ", pre-check=" + cacheExpire);
487       }
488     }
489
490     SessionArrayValue session = env.createSession(sessionId, create);
491     sessionId = session.getId();
492
493     if (! env.getIni("session.use_trans_sid").toBoolean() && generateCookie) {
494       env.addConstant("SID",
495           new StringValueImpl(cookieName + '=' + sessionId),
496           false);
497
498       Cookie JavaDoc cookie = new Cookie JavaDoc(cookieName, sessionId);
499       cookie.setVersion(1);
500
501       if (response.isCommitted()) {
502         env.warning(L.l("cannot send session cookie because response is committed"));
503       }
504       else {
505         Value path = env.getIni("session.cookie_path");
506         cookie.setPath(path.toString());
507
508         Value maxAge = env.getIni("session.cookie_lifetime");
509
510         if (maxAge.toInt() != 0)
511           cookie.setMaxAge(maxAge.toInt());
512
513         Value domain = env.getIni("session.cookie_domain");
514         cookie.setDomain(domain.toString());
515
516         Value secure = env.getIni("session.cookie_secure");
517         cookie.setSecure(secure.toBoolean());
518
519         response.addCookie(cookie);
520       }
521     }
522
523     env.setSpecialValue("caucho.session_id", new StringValueImpl(sessionId));
524
525     return true;
526   }
527
528   /**
529    * Unsets the specified session values
530    */

531   public boolean session_unregister(Env env, Value key)
532   {
533     Value value = env.getGlobalValue("_SESSION");
534
535     if (! value.isArray())
536       return false;
537
538     value.remove(key);
539
540     return true;
541   }
542
543   /**
544    * Unsets the session values
545    */

546   public Value session_unset(Env env)
547   {
548     Value value = env.getGlobalValue("_SESSION");
549
550     if (! value.isArray())
551       return NullValue.NULL;
552
553     for (Value key : value.getKeyArray())
554       value.remove(key);
555
556     return NullValue.NULL;
557   }
558
559   /**
560    * Writes the session and closes it.
561    */

562   public static Value session_write_close(Env env)
563   {
564     env.sessionWriteClose();
565
566     return NullValue.NULL;
567   }
568
569   /**
570    * Converts an integer to a printable character
571    */

572   private static char encode(long code)
573   {
574     code = code & 0x3f;
575
576     if (code < 26)
577       return (char) ('a' + code);
578     else if (code < 52)
579       return (char) ('A' + code - 26);
580     else if (code < 62)
581       return (char) ('0' + code - 52);
582     else if (code == 62)
583       return '_';
584     else
585       return '-';
586   }
587
588   static {
589     addIni(_iniMap, "session.save_path", "", PHP_INI_ALL);
590     addIni(_iniMap, "session.name", "PHPSESSID", PHP_INI_ALL);
591     addIni(_iniMap, "session.save_handler", "files", PHP_INI_ALL);
592     addIni(_iniMap, "session.auto_start", "0", PHP_INI_ALL);
593     addIni(_iniMap, "session.gc_probability_start", "1", PHP_INI_ALL);
594     addIni(_iniMap, "session.gc_divisor", "100", PHP_INI_ALL);
595     addIni(_iniMap, "session.gc_maxlifetime", "1440", PHP_INI_ALL);
596     addIni(_iniMap, "session.serialize_handler", "quercus", PHP_INI_ALL);
597     addIni(_iniMap, "session.cookie_lifetime", "0", PHP_INI_ALL);
598     addIni(_iniMap, "session.cookie_path", "/", PHP_INI_ALL);
599     addIni(_iniMap, "session.cookie_domain", "", PHP_INI_ALL);
600     addIni(_iniMap, "session.cookie_secure", "", PHP_INI_ALL);
601     addIni(_iniMap, "session.use_cookies", "1", PHP_INI_ALL);
602     addIni(_iniMap, "session.use_only_cookies", "0", PHP_INI_ALL);
603     addIni(_iniMap, "session.referer_check", "", PHP_INI_ALL);
604     addIni(_iniMap, "session.entropy_file", "", PHP_INI_ALL);
605     addIni(_iniMap, "session.entropy_length", "0", PHP_INI_ALL);
606     addIni(_iniMap, "session.cache_limiter", "nocache", PHP_INI_ALL);
607     addIni(_iniMap, "session.cache_expire", "180", PHP_INI_ALL);
608     addIni(_iniMap, "session.use_trans_sid", "0", PHP_INI_ALL);
609     addIni(_iniMap, "session.bug_compat_42", "1", PHP_INI_ALL);
610     addIni(_iniMap, "session.bug_compat_warn", "1", PHP_INI_ALL);
611     addIni(_iniMap, "session.hash_function", "0", PHP_INI_ALL);
612     addIni(_iniMap, "session.hash_bits_per_character", "4", PHP_INI_ALL);
613     addIni(_iniMap, "url_rewriter.tags", "a=href,area=href,frame=src,form=,fieldset=", PHP_INI_ALL);
614   }
615 }
616
Popular Tags