root/eaccelerator/trunk/session.c

Revision 350, 7.7 kB (checked in by bart, 7 months ago)

Failed to stage the commit properly

  • 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 - 2007 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 "ext/standard/php_lcg.h"
36 #include <fcntl.h>
37
38 #ifdef WIN32
39 #       include "win32/time.h"
40 #endif
41
42 ea_cache_place eaccelerator_sessions_cache_place = ea_shm_and_disk;
43 int eaccelerator_sessions_registered = 0;
44 extern eaccelerator_mm *eaccelerator_mm_instance;
45
46 /* set the updated ini value of the cache place */
47 PHP_INI_MH(eaccelerator_OnUpdateSessionCachePlace)
48 {
49         if (strncasecmp("shm_and_disk", new_value, sizeof("shm_and_disk")) == 0) {
50                 eaccelerator_sessions_cache_place = ea_shm_and_disk;
51         } else if (strncasecmp("shm", new_value, sizeof ("shm")) == 0) {
52                 eaccelerator_sessions_cache_place = ea_shm;
53         } else if (strncasecmp("shm_only", new_value, sizeof ("shm_only")) == 0) {
54                 eaccelerator_sessions_cache_place = ea_shm_only;
55         } else if (strncasecmp("disk_only", new_value, sizeof ("disk_only")) == 0) {
56                 eaccelerator_sessions_cache_place = ea_disk_only;
57         } else if (strncasecmp("none", new_value, sizeof ("none")) == 0) {
58                 eaccelerator_sessions_cache_place = ea_none;
59         }
60         return SUCCESS;
61 }
62
63 /* session unlock */
64 static int do_session_unlock(TSRMLS_D)
65 {
66         if (EAG (session) != NULL) {
67                 eaccelerator_unlock(EAG(session), strlen(EAG(session)) TSRMLS_CC);
68                 efree(EAG(session));
69                 EAG(session) = NULL;
70         }
71         return 1;
72 }
73
74 /* session locking */
75 static int do_session_lock(const char *sess_name TSRMLS_DC)
76 {
77         if (EAG(session) != NULL) {
78                 if (strcmp(EAG(session), sess_name) == 0) {
79                         return 1;
80                 } else {
81                         do_session_unlock(TSRMLS_C);
82                 }
83         }
84         if (eaccelerator_lock(sess_name, strlen(sess_name) TSRMLS_CC)) {
85                 EAG(session) = estrdup(sess_name);
86                 return 1;
87         } else {
88                 return 0;
89         }
90 }
91
92 /******************************************************************************/
93 /* Session api functions                                                                                                          */
94 /******************************************************************************/
95 PS_OPEN_FUNC(eaccelerator)
96 {
97         if (eaccelerator_mm_instance == NULL) {
98                 return FAILURE;
99         }
100         PS_SET_MOD_DATA((void *) 1);
101         return SUCCESS;
102 }
103
104 PS_CLOSE_FUNC(eaccelerator)
105 {
106         if (eaccelerator_mm_instance == NULL) {
107                 return FAILURE;
108         }
109         do_session_unlock(TSRMLS_C);
110         return SUCCESS;
111 }
112
113 PS_READ_FUNC(eaccelerator)
114 {
115         char *skey;
116         int len;
117         zval ret;
118 #ifdef ZEND_ENGINE_2_3
119     ALLOCA_FLAG(use_heap);
120 #endif
121
122         len = sizeof("sess_") + strlen(key);
123 #ifdef ZEND_ENGINE_2_3
124         skey = do_alloca(len + 1, use_heap);
125 #else
126         skey = do_alloca(len + 1);
127 #endif
128         strcpy(skey, "sess_");
129         strcat(skey, key);
130         do_session_lock(skey TSRMLS_CC);
131         if (eaccelerator_get(skey, len, &ret, eaccelerator_sessions_cache_place TSRMLS_CC)
132                     && ret.type == IS_STRING) {
133                 *val = estrdup(Z_STRVAL(ret));
134                 *vallen = Z_STRLEN(ret);
135                 zval_dtor(&ret);
136         } else {
137                 *val = emalloc(1);
138                 (*val)[0] = '\0';
139                 *vallen = 0;
140         }
141 #ifdef ZEND_ENGINE_2_3
142     free_alloca(skey, use_heap);
143 #else
144         free_alloca(skey);
145 #endif
146         return SUCCESS;
147 }
148
149 PS_WRITE_FUNC(eaccelerator)
150 {
151         char *skey;
152         int len;
153     int result;
154         time_t ttl = INI_INT("session.gc_maxlifetime");
155         zval sval;
156 #ifdef ZEND_ENGINE_2_3
157     ALLOCA_FLAG(use_heap);
158 #endif
159
160         len = sizeof("sess_") + strlen(key);
161 #ifdef ZEND_ENGINE_2_3
162         skey = do_alloca(len + 1, use_heap);
163 #else
164         skey = do_alloca(len + 1);
165 #endif
166         strcpy(skey, "sess_");
167         strcat(skey, key);
168         if (!ttl) {
169                 ttl = 1440;
170         }
171         Z_TYPE(sval) = IS_STRING;
172         Z_STRVAL(sval) = (char *) val;
173         Z_STRLEN(sval) = vallen;
174
175         do_session_lock(skey TSRMLS_CC);
176         if (eaccelerator_put(skey, len, &sval, ttl, eaccelerator_sessions_cache_place TSRMLS_CC)) {
177                 result = SUCCESS;
178         } else {
179                 result = FAILURE;
180         }
181
182 #ifdef ZEND_ENGINE_2_3
183     free_alloca(skey, use_heap);
184 #else
185         free_alloca(skey);
186 #endif
187
188     return result;
189 }
190
191 PS_DESTROY_FUNC(eaccelerator)
192 {
193         char *skey;
194         int len;
195     int result;
196 #ifdef ZEND_ENGINE_2_3
197     ALLOCA_FLAG(use_heap);
198 #endif
199
200         len = sizeof("sess_") + strlen(key);
201 #ifdef ZEND_ENGINE_2_3
202         skey = do_alloca(len + 1, use_heap);
203 #else
204         skey = do_alloca(len + 1);
205 #endif
206         strcpy(skey, "sess_");
207         strcat(skey, key);
208         if (eaccelerator_rm(skey, len, eaccelerator_sessions_cache_place TSRMLS_CC)) {
209                 result = SUCCESS;
210         } else {
211                 result = FAILURE;
212         }
213
214 #ifdef ZEND_ENGINE_2_3
215     free_alloca(skey, use_heap);
216 #else
217         free_alloca(skey);
218 #endif
219
220     return result;
221 }
222
223 PS_GC_FUNC(eaccelerator)
224 {
225         if (eaccelerator_mm_instance == NULL) {
226                 return FAILURE;
227         }
228         eaccelerator_gc(TSRMLS_C);
229         return SUCCESS;
230 }
231
232 PS_CREATE_SID_FUNC(eaccelerator)
233 {
234         static char hexconvtab[] = "0123456789abcdef";
235         PHP_MD5_CTX context;
236         unsigned char digest[16];
237         char buf[256];
238         struct timeval tv;
239         int i;
240         int j = 0;
241         unsigned char c;
242
243         long entropy_length = INI_INT("session.entropy_length");
244         char *entropy_file = INI_STR("session.entropy_file");
245
246         if (!entropy_length) {
247                 entropy_length = 0;
248         }
249         if (!entropy_file) {
250                 entropy_file = empty_string;
251         }
252
253         gettimeofday(&tv, NULL);
254         PHP_MD5Init(&context);
255
256         sprintf(buf, "%ld%ld%0.8f", tv.tv_sec, tv.tv_usec, php_combined_lcg (TSRMLS_C) * 10);
257         PHP_MD5Update(&context, (unsigned char *)buf, strlen(buf));
258
259         if (entropy_length > 0) {
260                 int fd;
261
262                 fd = VCWD_OPEN(entropy_file, O_RDONLY);
263                 if (fd >= 0) {
264                         unsigned char buf[2048];
265                         int n;
266                         size_t to_read = entropy_length;
267
268                         while (to_read > 0) {
269                                 n = read(fd, buf, MIN (to_read, sizeof(buf)));
270                                 if (n <= 0)
271                                         break;
272                                 PHP_MD5Update(&context, buf, n);
273                                 to_read -= n;
274                         }
275                         close(fd);
276                 }
277         }
278
279         PHP_MD5Final(digest, &context);
280
281         for (i = 0; i < 16; i++) {
282                 c = digest[i];
283                 buf[j++] = hexconvtab[c >> 4];
284                 buf[j++] = hexconvtab[c & 15];
285         }
286         buf[j] = '\0';
287
288         if (newlen)
289                 *newlen = j;
290         return estrdup (buf);
291 }
292
293 ps_module ps_mod_eaccelerator = {
294         PS_MOD_SID(eaccelerator)
295 };
296
297 /* register ea as session handler */
298 void eaccelerator_register_session()
299 {
300         if (eaccelerator_sessions_cache_place != ea_none && eaccelerator_sessions_registered == 0) {
301                 if (php_session_register_module(&ps_mod_eaccelerator) != 0) {
302                         zend_error(E_CORE_ERROR, "Could not register eAccelerator session handler!");   
303                 }
304                 eaccelerator_sessions_registered = 1;
305                 return;
306         }
307 }
308
309 #endif /* HAVE_EACCELERATOR_SESSIONS */
Note: See TracBrowser for help on using the browser.