source: eaccelerator/trunk/session.c @ 176

Revision 176, 12.0 KB checked in by bart, 5 years ago (diff)

The nigthly cvs tarballs of sf aren't that nigthly at all. The commits from
march weren't included.

  • 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 - 2006 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   $Id$
26*/
27
28#include "eaccelerator.h"
29#include "session.h"
30
31#ifdef WITH_EACCELERATOR_SESSIONS
32
33#include "cache.h"
34#include "ext/standard/md5.h"
35#include <fcntl.h>
36
37#ifdef WIN32
38#       include "win32/time.h"
39#endif
40
41#if defined(HAVE_PHP_SESSIONS_SUPPORT) && defined(PS_CREATE_SID_ARGS)
42#       include "ext/standard/php_lcg.h"
43#endif
44
45eaccelerator_cache_place eaccelerator_sessions_cache_place =
46        eaccelerator_shm_and_disk;
47int eaccelerator_sessions_registered = 0;
48extern eaccelerator_mm *eaccelerator_mm_instance;
49
50/* set the updated ini value of the cache place */
51PHP_INI_MH (eaccelerator_OnUpdateSessionCachePlace)
52{
53        if (strncasecmp ("shm_and_disk", new_value, sizeof ("shm_and_disk")) == 0) {
54                eaccelerator_sessions_cache_place = eaccelerator_shm_and_disk;
55        } else if (strncasecmp ("shm", new_value, sizeof ("shm")) == 0) {
56                eaccelerator_sessions_cache_place = eaccelerator_shm;
57        } else if (strncasecmp ("shm_only", new_value, sizeof ("shm_only")) == 0) {
58                eaccelerator_sessions_cache_place = eaccelerator_shm_only;
59        } else if (strncasecmp ("disk_only", new_value, sizeof ("disk_only")) == 0) {
60                eaccelerator_sessions_cache_place = eaccelerator_disk_only;
61        } else if (strncasecmp ("none", new_value, sizeof ("none")) == 0) {
62                eaccelerator_sessions_cache_place = eaccelerator_none;
63        }
64        return SUCCESS;
65}
66
67/* session unlock */
68static int do_session_unlock (TSRMLS_D)
69{
70        if (EAG (session) != NULL) {
71                eaccelerator_unlock (EAG (session), strlen (EAG (session)) TSRMLS_CC);
72                efree (EAG (session));
73                EAG (session) = NULL;
74        }
75        return 1;
76}
77
78/* session locking */
79static int do_session_lock (const char *sess_name TSRMLS_DC)
80{
81        if (EAG (session) != NULL) {
82                if (strcmp (EAG (session), sess_name) == 0) {
83                        return 1;
84                } else {
85                        do_session_unlock (TSRMLS_C);
86                }
87        }
88        if (eaccelerator_lock (sess_name, strlen (sess_name) TSRMLS_CC)) {
89                EAG (session) = estrdup (sess_name);
90                return 1;
91        } else {
92                return 0;
93        }
94}
95
96#ifdef HAVE_PHP_SESSIONS_SUPPORT        /* PHP_SESSION_API >= 20020306 */
97/******************************************************************************/
98/* Session api functions                                                                                                          */
99/******************************************************************************/
100
101PS_OPEN_FUNC (eaccelerator)
102{
103        if (eaccelerator_mm_instance == NULL) {
104                return FAILURE;
105        }
106        PS_SET_MOD_DATA ((void *) 1);
107        return SUCCESS;
108}
109
110PS_CLOSE_FUNC (eaccelerator)
111{
112        if (eaccelerator_mm_instance == NULL) {
113                return FAILURE;
114        }
115        do_session_unlock (TSRMLS_C);
116        return SUCCESS;
117}
118
119PS_READ_FUNC (eaccelerator)
120{
121        char *skey;
122        int len;
123        zval ret;
124
125        len = sizeof ("sess_") + strlen (key);
126        skey = do_alloca (len + 1);
127        strcpy (skey, "sess_");
128        strcat (skey, key);
129        do_session_lock (skey TSRMLS_CC);
130        if (eaccelerator_get
131                (skey, len, &ret, eaccelerator_sessions_cache_place TSRMLS_CC)
132                && ret.type == IS_STRING) {
133                *val = estrdup (ret.value.str.val);
134                *vallen = ret.value.str.len;
135                zval_dtor (&ret);
136        } else {
137                *val = emalloc (1);
138                (*val)[0] = '\0';
139                *vallen = 0;
140        }
141        free_alloca (skey);
142        return SUCCESS;
143}
144
145PS_WRITE_FUNC (eaccelerator)
146{
147        char *skey;
148        int len;
149        time_t ttl;
150        zval sval;
151        char *tmp;
152
153        len = sizeof ("sess_") + strlen (key);
154        skey = do_alloca (len + 1);
155        strcpy (skey, "sess_");
156        strcat (skey, key);
157        if (cfg_get_string ("session.gc_maxlifetime", &tmp) == FAILURE) {
158                ttl = 1440;
159        } else {
160                ttl = atoi (tmp);
161        }
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
177PS_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
196PS_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
206PS_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                        size_t 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
277PHP_FUNCTION (_eaccelerator_session_open)
278{
279        if (eaccelerator_mm_instance == NULL) {
280                RETURN_FALSE;
281        }
282        RETURN_TRUE;
283}
284
285PHP_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
294PHP_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
319PHP_FUNCTION (_eaccelerator_session_write)
320{
321        zval **arg_key, **arg_val;
322        char *key;
323        int len;
324        time_t ttl;
325
326        if (ZEND_NUM_ARGS () != 2
327                || zend_get_parameters_ex (2, &arg_key, &arg_val) == FAILURE) {
328                WRONG_PARAM_COUNT;
329        }
330        len = sizeof ("sess_") + (*arg_key)->value.str.len;
331        key = do_alloca (len + 1);
332        strcpy (key, "sess_");
333        strcat (key, (*arg_key)->value.str.val);
334        ttl = PS (gc_maxlifetime);
335        if (ttl < 0)
336                ttl = 1440;
337        do_session_lock (key TSRMLS_CC);
338        if (eaccelerator_put
339                (key, len, *arg_val, ttl,
340                 eaccelerator_sessions_cache_place TSRMLS_CC)) {
341                free_alloca (key);
342                RETURN_TRUE;
343        } else {
344                free_alloca (key);
345                RETURN_FALSE;
346        }
347}
348
349PHP_FUNCTION (_eaccelerator_session_destroy)
350{
351        zval **arg_key;
352        char *key;
353        int len;
354
355        if (ZEND_NUM_ARGS () != 1
356                || zend_get_parameters_ex (1, &arg_key) == FAILURE) {
357                WRONG_PARAM_COUNT;
358        }
359        len = sizeof ("sess_") + (*arg_key)->value.str.len;
360        key = do_alloca (len + 1);
361        strcpy (key, "sess_");
362        strcat (key, (*arg_key)->value.str.val);
363        if (eaccelerator_rm (key, len, eaccelerator_sessions_cache_place TSRMLS_CC)) {
364                free_alloca (key);
365                RETURN_TRUE;
366        } else {
367                free_alloca (key);
368                RETURN_FALSE;
369        }
370}
371
372PHP_FUNCTION (_eaccelerator_session_gc)
373{
374        if (eaccelerator_mm_instance == NULL) {
375                RETURN_FALSE;
376        }
377        eaccelerator_gc (TSRMLS_C);
378        RETURN_TRUE;
379}
380#endif /* ELSE HAVE_PHP_SESSIONS_SUPPORT */
381
382ps_module ps_mod_eaccelerator = {
383#ifdef PS_CREATE_SID_ARGS
384        PS_MOD_SID (eaccelerator)
385#else
386        PS_MOD (eaccelerator)
387#endif
388};
389
390/* is the eA registered as session handler */
391int eaccelerator_session_registered ()
392{
393        return !(eaccelerator_sessions_cache_place != eaccelerator_none &&
394                         eaccelerator_sessions_registered == 0);
395}
396
397/* register ea as session handler */
398void eaccelerator_register_session ()
399{
400        php_session_register_module (&ps_mod_eaccelerator);
401        eaccelerator_sessions_registered = 1;
402}
403
404/* register ea as the custom session handler */
405int eaccelerator_set_session_handlers (TSRMLS_D)
406{
407        zval func;
408        zval retval;
409        int ret = 1;
410#ifdef HAVE_PHP_SESSIONS_SUPPORT        // do it with the session api
411        zval param;
412        zval *params[1];
413/*
414  if (php_session_register_module(&ps_mod_eaccelerator) != 0) {
415    return 0;
416  }
417*/
418        if (eaccelerator_sessions_cache_place == eaccelerator_none) {
419                return 0;
420        }
421        ZVAL_STRING (&func, "session_module_name", 0);
422        INIT_ZVAL (param);
423        params[0] = &param;
424        ZVAL_STRING (params[0], "eaccelerator", 0);
425        if (call_user_function (EG (function_table), NULL, &func, &retval,
426                                                        1, params TSRMLS_CC) == FAILURE) {
427                ret = 0;
428        }
429        zval_dtor (&retval);
430        return ret;
431#else // register the functions as custom user functions
432        zval *params[6];
433        int i;
434
435        if (eaccelerator_sessions_cache_place == eaccelerator_none) {
436                return 0;
437        }
438        if (eaccelerator_mm_instance == NULL) {
439                return 0;
440        }
441        if (!zend_hash_exists
442                (EG (function_table), "session_set_save_handler",
443                 sizeof ("session_set_save_handler"))) {
444                return 0;
445        }
446
447        ZVAL_STRING (&func, "session_set_save_handler", 0);
448        MAKE_STD_ZVAL (params[0]);
449        ZVAL_STRING (params[0], "_eaccelerator_session_open", 1);
450        MAKE_STD_ZVAL (params[1]);
451        ZVAL_STRING (params[1], "_eaccelerator_session_close", 1);
452        MAKE_STD_ZVAL (params[2]);
453        ZVAL_STRING (params[2], "_eaccelerator_session_read", 1);
454        MAKE_STD_ZVAL (params[3]);
455        ZVAL_STRING (params[3], "_eaccelerator_session_write", 1);
456        MAKE_STD_ZVAL (params[4]);
457        ZVAL_STRING (params[4], "_eaccelerator_session_destroy", 1);
458        MAKE_STD_ZVAL (params[5]);
459        ZVAL_STRING (params[5], "_eaccelerator_session_gc", 1);
460        if (call_user_function (EG (function_table), NULL, &func, &retval,
461                                                        6, params TSRMLS_CC) == FAILURE) {
462                ret = 0;
463        }
464        zval_dtor (&retval);
465        for (i = 0; i < 6; i++)
466                zval_ptr_dtor (&params[i]);
467        return ret;
468#endif
469}
470
471/* function to call from a php script to register ea as session handler */
472PHP_FUNCTION (eaccelerator_set_session_handlers)
473{
474        if (eaccelerator_set_session_handlers (TSRMLS_C)) {
475                RETURN_TRUE;
476        } else {
477                RETURN_FALSE;
478        }
479}
480
481#endif /* HAVE_EACCELERATOR_SESSIONS */
Note: See TracBrowser for help on using the repository browser.