root/eaccelerator/tags/0.9.3/session.c

Revision 99, 12.2 kB (checked in by zoeloelip, 3 years ago)

The session lifetime patch only fixed the problem when using one type of session handler. It's now
also fixed for the other type of session handler.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2005 eAccelerator                               |
6    | http://eaccelerator.net                                              |
7    +----------------------------------------------------------------------+
8    | This program is free software; you can redistribute it and/or        |
9    | modify it under the terms of the GNU General Public License          |
10    | as published by the Free Software Foundation; either version 2       |
11    | of the License, or (at your option) any later version.               |
12    |                                                                      |
13    | This program is distributed in the hope that it will be useful,      |
14    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
15    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
16    | GNU General Public License for more details.                         |
17    |                                                                      |
18    | You should have received a copy of the GNU General Public License    |
19    | along with this program; if not, write to the Free Software          |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
21    | MA  02111-1307, USA.                                                 |
22    |                                                                      |
23    | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
24    +----------------------------------------------------------------------+
25    | Author(s): Dmitry Stogov <dstogov@users.sourceforge.net>             |
26    +----------------------------------------------------------------------+
27    $Id$
28 */
29
30 #include "eaccelerator.h"
31 #include "session.h"
32
33 #ifdef WITH_EACCELERATOR_SESSIONS
34
35 #include "cache.h"
36 #include "ext/standard/md5.h"
37 #include <fcntl.h>
38
39 #ifdef WIN32
40 #       include "win32/time.h"
41 #endif
42
43 #if defined(HAVE_PHP_SESSIONS_SUPPORT) && defined(PS_CREATE_SID_ARGS)
44 #       include "ext/standard/php_lcg.h"
45 #endif
46
47 eaccelerator_cache_place eaccelerator_sessions_cache_place =
48         eaccelerator_shm_and_disk;
49 int eaccelerator_sessions_registered = 0;
50 extern eaccelerator_mm *eaccelerator_mm_instance;
51
52 /* set the updated ini value of the cache place */
53 PHP_INI_MH (eaccelerator_OnUpdateSessionCachePlace)
54 {
55         if (strncasecmp ("shm_and_disk", new_value, sizeof ("shm_and_disk")) == 0) {
56                 eaccelerator_sessions_cache_place = eaccelerator_shm_and_disk;
57         } else if (strncasecmp ("shm", new_value, sizeof ("shm")) == 0) {
58                 eaccelerator_sessions_cache_place = eaccelerator_shm;
59         } else if (strncasecmp ("shm_only", new_value, sizeof ("shm_only")) == 0) {
60                 eaccelerator_sessions_cache_place = eaccelerator_shm_only;
61         } else if (strncasecmp ("disk_only", new_value, sizeof ("disk_only")) == 0) {
62                 eaccelerator_sessions_cache_place = eaccelerator_disk_only;
63         } else if (strncasecmp ("none", new_value, sizeof ("none")) == 0) {
64                 eaccelerator_sessions_cache_place = eaccelerator_none;
65         }
66         return SUCCESS;
67 }
68
69 /* session unlock */
70 static int do_session_unlock (TSRMLS_D)
71 {
72         if (MMCG (session) != NULL) {
73                 eaccelerator_unlock (MMCG (session), strlen (MMCG (session)) TSRMLS_CC);
74                 efree (MMCG (session));
75                 MMCG (session) = NULL;
76         }
77         return 1;
78 }
79
80 /* session locking */
81 static int do_session_lock (const char *sess_name TSRMLS_DC)
82 {
83         if (MMCG (session) != NULL) {
84                 if (strcmp (MMCG (session), sess_name) == 0) {
85                         return 1;
86                 } else {
87                         do_session_unlock (TSRMLS_C);
88                 }
89         }
90         if (eaccelerator_lock (sess_name, strlen (sess_name) TSRMLS_CC)) {
91                 MMCG (session) = estrdup (sess_name);
92                 return 1;
93         } else {
94                 return 0;
95         }
96 }
97
98 #ifdef HAVE_PHP_SESSIONS_SUPPORT  /* PHP_SESSION_API >= 20020306 */
99 /******************************************************************************/
100 /* Session api functions                                                                                                          */
101 /******************************************************************************/
102
103 PS_OPEN_FUNC (eaccelerator)
104 {
105         if (eaccelerator_mm_instance == NULL) {
106                 return FAILURE;
107         }
108         PS_SET_MOD_DATA ((void *) 1);
109         return SUCCESS;
110 }
111
112 PS_CLOSE_FUNC (eaccelerator)
113 {
114         if (eaccelerator_mm_instance == NULL) {
115                 return FAILURE;
116         }
117         do_session_unlock (TSRMLS_C);
118         return SUCCESS;
119 }
120
121 PS_READ_FUNC (eaccelerator)
122 {
123         char *skey;
124         int len;
125         zval ret;
126
127         len = sizeof ("sess_") + strlen (key);
128         skey = do_alloca (len + 1);
129         strcpy (skey, "sess_");
130         strcat (skey, key);
131         do_session_lock (skey TSRMLS_CC);
132         if (eaccelerator_get
133                 (skey, len, &ret, eaccelerator_sessions_cache_place TSRMLS_CC)
134                 && ret.type == IS_STRING) {
135                 *val = estrdup (ret.value.str.val);
136                 *vallen = ret.value.str.len;
137                 zval_dtor (&ret);
138         } else {
139                 *val = emalloc (1);
140                 (*val)[0] = '\0';
141                 *vallen = 0;
142         }
143         free_alloca (skey);
144         return SUCCESS;
145 }
146
147 PS_WRITE_FUNC (eaccelerator)
148 {
149         char *skey;
150         int len;
151         char *tmp;
152         time_t ttl;
153         zval sval;
154
155         len = sizeof ("sess_") + strlen (key);
156         skey = do_alloca (len + 1);
157         strcpy (skey, "sess_");
158         strcat (skey, key);
159         ttl = PS(gc_maxlifetime);
160         if (ttl < 0)
161                 ttl = 1440;
162         sval.type = IS_STRING;
163         sval.value.str.val = (char *) val;
164         sval.value.str.len = vallen;
165
166         do_session_lock (skey TSRMLS_CC);
167         if (eaccelerator_put
168                 (skey, len, &sval, ttl, eaccelerator_sessions_cache_place TSRMLS_CC)) {
169                 free_alloca (skey);
170                 return SUCCESS;
171         } else {
172                 free_alloca (skey);
173                 return FAILURE;
174         }
175 }
176
177 PS_DESTROY_FUNC (eaccelerator)
178 {
179         char *skey;
180         int len;
181
182         len = sizeof ("sess_") + strlen (key);
183         skey = do_alloca (len + 1);
184         strcpy (skey, "sess_");
185         strcat (skey, key);
186         if (eaccelerator_rm
187                 (skey, len, eaccelerator_sessions_cache_place TSRMLS_CC)) {
188                 free_alloca (skey);
189                 return SUCCESS;
190         } else {
191                 free_alloca (skey);
192                 return FAILURE;
193         }
194 }
195
196 PS_GC_FUNC (eaccelerator)
197 {
198         if (eaccelerator_mm_instance == NULL) {
199                 return FAILURE;
200         }
201         eaccelerator_gc (TSRMLS_C);
202         return SUCCESS;
203 }
204
205 #ifdef PS_CREATE_SID_ARGS
206 PS_CREATE_SID_FUNC (eaccelerator)
207 {
208         static char hexconvtab[] = "0123456789abcdef";
209         PHP_MD5_CTX context;
210         unsigned char digest[16];
211         char buf[256];
212         struct timeval tv;
213         int i;
214         int j = 0;
215         unsigned char c;
216
217         long entropy_length;
218         char *entropy_file;
219
220         if (cfg_get_string ("session.entropy_length", &entropy_file) == FAILURE) {
221                 entropy_length = 0;
222         } else {
223                 entropy_length = atoi (entropy_file);
224         }
225         if (cfg_get_string ("session.entropy_file", &entropy_file) == FAILURE) {
226                 entropy_file = empty_string;
227         }
228
229         gettimeofday (&tv, NULL);
230         PHP_MD5Init (&context);
231
232         sprintf (buf, "%ld%ld%0.8f", tv.tv_sec, tv.tv_usec,
233                          php_combined_lcg (TSRMLS_C) * 10);
234         PHP_MD5Update (&context, (unsigned char *) buf, strlen (buf));
235
236         if (entropy_length > 0) {
237                 int fd;
238
239                 fd = VCWD_OPEN (entropy_file, O_RDONLY);
240                 if (fd >= 0) {
241                         unsigned char buf[2048];
242                         int n;
243                         int to_read = entropy_length;
244
245                         while (to_read > 0) {
246                                 n = read (fd, buf, MIN (to_read, sizeof (buf)));
247                                 if (n <= 0)
248                                         break;
249                                 PHP_MD5Update (&context, buf, n);
250                                 to_read -= n;
251                         }
252                         close (fd);
253                 }
254         }
255
256         PHP_MD5Final (digest, &context);
257
258         for (i = 0; i < 16; i++) {
259                 c = digest[i];
260                 buf[j++] = hexconvtab[c >> 4];
261                 buf[j++] = hexconvtab[c & 15];
262         }
263         buf[j] = '\0';
264
265         if (newlen)
266                 *newlen = j;
267         return estrdup (buf);
268 }
269 #endif
270
271 #else
272 /******************************************************************************/
273 /* PHP function to register as user session handlers when the session api         */
274 /* available.                                                                                                                             */
275 /******************************************************************************/
276
277 PHP_FUNCTION (_eaccelerator_session_open)
278 {
279         if (eaccelerator_mm_instance == NULL) {
280                 RETURN_FALSE;
281         }
282         RETURN_TRUE;
283 }
284
285 PHP_FUNCTION (_eaccelerator_session_close)
286 {
287         if (eaccelerator_mm_instance == NULL) {
288                 RETURN_FALSE;
289         }
290         do_session_unlock (TSRMLS_C);
291         RETURN_TRUE;
292 }
293
294 PHP_FUNCTION (_eaccelerator_session_read)
295 {
296         zval **arg_key;
297         char *key;
298         int len;
299
300         if (ZEND_NUM_ARGS () != 1
301                 || zend_get_parameters_ex (1, &arg_key) == FAILURE) {
302                 WRONG_PARAM_COUNT;
303         }
304         len = sizeof ("sess_") + (*arg_key)->value.str.len;
305         key = do_alloca (len + 1);
306         strcpy (key, "sess_");
307         strcat (key, (*arg_key)->value.str.val);
308         do_session_lock (key TSRMLS_CC);
309         if (eaccelerator_get
310                 (key, len, return_value, eaccelerator_sessions_cache_place TSRMLS_CC)) {
311                 free_alloca (key);
312                 return;
313         } else {
314                 free_alloca (key);
315                 RETURN_EMPTY_STRING ();
316         }
317 }
318
319 PHP_FUNCTION (_eaccelerator_session_write)
320 {
321         zval **arg_key, **arg_val;
322         char *key;
323         int len;
324         char *tmp;
325         time_t ttl;
326
327         if (ZEND_NUM_ARGS () != 2
328                 || zend_get_parameters_ex (2, &arg_key, &arg_val) == FAILURE) {
329                 WRONG_PARAM_COUNT;
330         }
331         len = sizeof ("sess_") + (*arg_key)->value.str.len;
332         key = do_alloca (len + 1);
333         strcpy (key, "sess_");
334         strcat (key, (*arg_key)->value.str.val);
335         ttl = PS(gc_maxlifetime);
336         if (ttl < 0)
337                 ttl = 1440;
338         do_session_lock (key TSRMLS_CC);
339         if (eaccelerator_put
340                 (key, len, *arg_val, ttl,
341                  eaccelerator_sessions_cache_place TSRMLS_CC)) {
342                 free_alloca (key);
343                 RETURN_TRUE;
344         } else {
345                 free_alloca (key);
346                 RETURN_FALSE;
347         }
348 }
349
350 PHP_FUNCTION (_eaccelerator_session_destroy)
351 {
352         zval **arg_key;
353         char *key;
354         int len;
355
356         if (ZEND_NUM_ARGS () != 1
357                 || zend_get_parameters_ex (1, &arg_key) == FAILURE) {
358                 WRONG_PARAM_COUNT;
359         }
360         len = sizeof ("sess_") + (*arg_key)->value.str.len;
361         key = do_alloca (len + 1);
362         strcpy (key, "sess_");
363         strcat (key, (*arg_key)->value.str.val);
364         if (eaccelerator_rm (key, len, eaccelerator_sessions_cache_place TSRMLS_CC)) {
365                 free_alloca (key);
366                 RETURN_TRUE;
367         } else {
368                 free_alloca (key);
369                 RETURN_FALSE;
370         }
371 }
372
373 PHP_FUNCTION (_eaccelerator_session_gc)
374 {
375         if (eaccelerator_mm_instance == NULL) {
376                 RETURN_FALSE;
377         }
378         eaccelerator_gc (TSRMLS_C);
379         RETURN_TRUE;
380 }
381 #endif                                                  /* ELSE HAVE_PHP_SESSIONS_SUPPORT */
382
383 ps_module ps_mod_eaccelerator = {
384 #ifdef PS_CREATE_SID_ARGS
385         PS_MOD_SID (eaccelerator)
386 #else
387         PS_MOD (eaccelerator)
388 #endif
389 };
390
391 /* is the eA registered as session handler */
392 int eaccelerator_session_registered ()
393 {
394         return !(eaccelerator_sessions_cache_place != eaccelerator_none &&
395                          eaccelerator_sessions_registered == 0);
396 }
397
398 /* register ea as session handler */
399 void eaccelerator_register_session ()
400 {
401         php_session_register_module (&ps_mod_eaccelerator);
402         eaccelerator_sessions_registered = 1;
403 }
404
405 /* register ea as the custom session handler */
406 int eaccelerator_set_session_handlers (TSRMLS_D)
407 {
408         zval func;
409         zval retval;
410         int ret = 1;
411 #ifdef HAVE_PHP_SESSIONS_SUPPORT // do it with the session api
412         zval param;
413         zval *params[1];
414 /*
415   if (php_session_register_module(&ps_mod_eaccelerator) != 0) {
416     return 0;
417   }
418 */
419         if (eaccelerator_sessions_cache_place == eaccelerator_none) {
420                 return 0;
421         }
422         ZVAL_STRING (&func, "session_module_name", 0);
423         INIT_ZVAL (param);
424         params[0] = &param;
425         ZVAL_STRING (params[0], "eaccelerator", 0);
426         if (call_user_function (EG (function_table), NULL, &func, &retval,
427                                                         1, params TSRMLS_CC) == FAILURE) {
428                 ret = 0;
429         }
430         zval_dtor (&retval);
431         return ret;
432 #else // register the functions as custom user functions
433         zval *params[6];
434         int i;
435
436         if (eaccelerator_sessions_cache_place == eaccelerator_none) {
437                 return 0;
438         }
439         if (eaccelerator_mm_instance == NULL) {
440                 return 0;
441         }
442         if (!zend_hash_exists
443                 (EG (function_table), "session_set_save_handler",
444                  sizeof ("session_set_save_handler"))) {
445                 return 0;
446         }
447
448         ZVAL_STRING (&func, "session_set_save_handler", 0);
449         MAKE_STD_ZVAL (params[0]);
450         ZVAL_STRING (params[0], "_eaccelerator_session_open", 1);
451         MAKE_STD_ZVAL (params[1]);
452         ZVAL_STRING (params[1], "_eaccelerator_session_close", 1);
453         MAKE_STD_ZVAL (params[2]);
454         ZVAL_STRING (params[2], "_eaccelerator_session_read", 1);
455         MAKE_STD_ZVAL (params[3]);
456         ZVAL_STRING (params[3], "_eaccelerator_session_write", 1);
457         MAKE_STD_ZVAL (params[4]);
458         ZVAL_STRING (params[4], "_eaccelerator_session_destroy", 1);
459         MAKE_STD_ZVAL (params[5]);
460         ZVAL_STRING (params[5], "_eaccelerator_session_gc", 1);
461         if (call_user_function (EG (function_table), NULL, &func, &retval,
462                                                         6, params TSRMLS_CC) == FAILURE) {
463                 ret = 0;
464         }
465         zval_dtor (&retval);
466         for (i = 0; i < 6; i++)
467                 zval_ptr_dtor (&params[i]);
468         return ret;
469 #endif
470 }
471
472 /* function to call from a php script to register ea as session handler */
473 PHP_FUNCTION (eaccelerator_set_session_handlers)
474 {
475         if (eaccelerator_set_session_handlers (TSRMLS_C)) {
476                 RETURN_TRUE;
477         } else {
478                 RETURN_FALSE;
479         }
480 }
481
482 #endif /* HAVE_EACCELERATOR_SESSIONS */
Note: See TracBrowser for help on using the browser.