1 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 ; 40 import javax.servlet.http.HttpServletResponse ; 41 import java.util.HashMap ; 42 import java.util.Map ; 43 import java.util.logging.Logger ; 44 45 48 public class SessionModule extends AbstractQuercusModule 49 implements ModuleStartupListener { 50 private static final L10N L = new L10N(SessionModule.class); 51 private static final Logger log 52 = Logger.getLogger(SessionModule.class.getName()); 53 54 private static final HashMap <String ,StringValue> _iniMap 55 = new HashMap <String ,StringValue>(); 56 57 60 public Map <String ,StringValue> getDefaultIni() 61 { 62 return _iniMap; 63 } 64 65 public String []getLoadedExtensions() 66 { 67 return new String [] { "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 89 public Value session_cache_limiter(Env env, @Optional String newValue) 90 { 91 Value value = env.getIni("session.cache_limiter"); 92 93 if (newValue == null || "".equals(newValue)) 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 117 public static Value session_commit(Env env) 118 { 119 return session_write_close(env); 120 } 121 122 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 140 public static String 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 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 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 185 public static String session_id(Env env, @Optional String id) 186 { 187 Value sessionIdValue = (Value) env.getSpecialValue("caucho.session_id"); 188 189 String 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 205 public static boolean session_is_registered(Env env, String name) 206 { 207 return env.getGlobalValue("_SESSION").get(new StringValueImpl(name)).isset(); 208 } 209 210 213 public Value session_module_name(Env env, @Optional String 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 226 public Value session_name(Env env, @Optional String 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 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 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 <Value,Value> entry : session.entrySet()) 259 newSession.put(entry.getKey(), entry.getValue()); 260 } 261 262 return true; 263 } 264 265 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 286 private void sessionRegisterImpl(Env env, ArrayValue session, Value nameV) 287 { 288 nameV = nameV.toValue(); 289 290 if (nameV instanceof StringValue) { 291 String 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 313 public Value session_save_path(Env env, @Optional String 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 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 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 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 sessionId = null; 384 385 final HttpServletResponse response = env.getResponse(); 386 387 env.removeConstant("SID"); 388 389 String 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 if (env.getIni("session.use_cookies").toBoolean()) { 400 if (sessionIdValue != null) 401 sessionId = sessionIdValue.toString(); 402 403 if (sessionId == null || "".equals(sessionId)) { 404 Cookie []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 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 queryString = env.getRequest().getQueryString(); 437 if (queryString != null) { 438 String [] queryElements = queryString.split("&"); 439 440 for (String queryElement : queryElements) { 441 String [] 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 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 cookie = new Cookie (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 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 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 562 public static Value session_write_close(Env env) 563 { 564 env.sessionWriteClose(); 565 566 return NullValue.NULL; 567 } 568 569 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 |