source: github/program/include/session.inc @ 3e48d2ee

HEADcourier-fixdev-browser-capabilitiespdorelease-0.6release-0.7release-0.8
Last change on this file since 3e48d2ee was 3e48d2ee, checked in by alecpl <alec@…>, 5 years ago
  • Increase speed of session destroy and garbage clean up
  • Fix session timeout when DB server got clock skew (#1485490)
  • Property mode set to 100644
File size: 5.0 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/include/session.inc                                           |
6 |                                                                       |
7 | This file is part of the RoundCube Webmail client                     |
8 | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland                 |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   Provide database supported session management                       |
13 |                                                                       |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16 +-----------------------------------------------------------------------+
17
18 $Id$
19
20*/
21
22
23function rcube_sess_open($save_path, $session_name)
24{
25  return true;
26}
27
28
29function rcube_sess_close()
30{
31  return true;
32}
33
34
35// read session data
36function rcube_sess_read($key)
37{
38  global $SESS_CHANGED, $SESS_CLIENT_IP;
39 
40  $DB = rcmail::get_instance()->get_dbh();
41 
42  if ($DB->is_error()) {
43    return false;
44  }
45 
46  $sql_result = $DB->query(
47    "SELECT vars, ip, " . $DB->unixtimestamp('changed') . " AS changed
48     FROM " . get_table_name('session') . "
49     WHERE  sess_id=?",
50    $key);
51
52  if ($sql_arr = $DB->fetch_assoc($sql_result)) {
53    $SESS_CHANGED = $sql_arr['changed'];
54    $SESS_CLIENT_IP = $sql_arr['ip'];
55
56    if (strlen($sql_arr['vars']))
57      return $sql_arr['vars'];
58  }
59
60  return false;
61}
62 
63
64// save session data
65function rcube_sess_write($key, $vars)
66{
67  $DB = rcmail::get_instance()->get_dbh();
68 
69  if ($DB->is_error()) {
70    return false;
71  }
72
73  $sql_result = $DB->query(
74    "SELECT 1 FROM " . get_table_name('session') . "
75     WHERE  sess_id=?",
76    $key);
77
78  $now = $DB->fromunixtime(time());
79
80  if ($DB->num_rows($sql_result)) {
81    $DB->query(
82      "UPDATE " . get_table_name('session') . "
83       SET    vars=?, changed= " . $now . "
84       WHERE  sess_id=?",
85      $vars,
86      $key);
87  }
88  else {
89    $DB->query(
90      "INSERT INTO " . get_table_name('session') . "
91       (sess_id, vars, ip, created, changed)
92       VALUES (?, ?, ?, " . $now . ", " . $now .")",
93      $key,
94      $vars,
95      (string)$_SERVER['REMOTE_ADDR']);
96  }
97
98  return true;
99}
100
101
102// handler for session_destroy()
103function rcube_sess_destroy($key)
104{
105  $rcmail = rcmail::get_instance();
106  $DB = $rcmail->get_dbh();
107 
108  if ($DB->is_error()) {
109    return false;
110  }
111
112  $DB->query("DELETE FROM " . get_table_name('session') . " WHERE sess_id=?", $key);
113
114  // delete session entries in cache table
115  // on databases wthout foreign keys
116  if ($rcmail->config->get('enable_caching') && $DB->db_provider != 'pgsql') {
117    $DB->query("DELETE FROM " . get_table_name('cache') . " WHERE session_id=?", $key);
118  }
119
120  return true;
121}
122
123
124// garbage collecting function
125function rcube_sess_gc($maxlifetime)
126{
127  $rcmail = rcmail::get_instance();
128  $DB = $rcmail->get_dbh();
129
130  if ($DB->is_error()) {
131    return false;
132  }
133
134  $now = $DB->fromunixtime(time() - $maxlifetime);
135
136  // delete session entries in cache table
137  if ($rcmail->config->get('enable_caching')) {
138
139    // on databases wthout foreign keys...
140    if($DB->db_provider != 'pgsql') {
141
142      // get all expired sessions
143      $sql_result = $DB->query(
144        "SELECT sess_id FROM " . get_table_name('session') . "
145            WHERE changed < " . $now);
146
147      $exp_sessions = array();
148      while ($sql_arr = $DB->fetch_assoc($sql_result)) {
149        $exp_sessions[] = $sql_arr['sess_id'];
150      }
151
152      if (sizeof($exp_sessions)) {
153        $exp_sessions = "'" . join("','", $exp_sessions) . "'";
154        // delete session cache records
155        $DB->query("DELETE FROM " . get_table_name('cache') . "
156            WHERE session_id IN (" . $exp_sessions . ")");
157      }
158    }
159    // also run message cache GC
160    rcmail_message_cache_gc();
161  }
162
163  // just delete all expired sessions
164  $DB->query("DELETE FROM " . get_table_name('session') . "
165    WHERE changed < " . $now);
166
167  rcmail_temp_gc();
168
169  return true;
170}
171
172
173function rcube_sess_regenerate_id()
174{
175  $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
176
177  for ($random = "", $i=1; $i <= 32; $i++) {
178    $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
179  }
180
181  // use md5 value for id or remove capitals from string $randval
182  $random = md5($random);
183
184  // delete old session record
185  rcube_sess_destroy(session_id());
186
187  session_id($random);
188
189  $cookie   = session_get_cookie_params();
190  $lifetime = $cookie['lifetime'] ? time() + $cookie['lifetime'] : 0;
191
192  rcmail::setcookie(session_name(), $random, $lifetime);
193
194  return true;
195}
196
197
198// set custom functions for PHP session management
199session_set_save_handler('rcube_sess_open', 'rcube_sess_close', 'rcube_sess_read', 'rcube_sess_write', 'rcube_sess_destroy', 'rcube_sess_gc');
200
201?>
Note: See TracBrowser for help on using the repository browser.