root/eaccelerator/tags/0.9.3-rc2/content.c

Revision 67, 22.0 kB (checked in by zoeloelip, 3 years ago)

Reverted added efree. Stupid stupid mistake from me.

  • 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
32 #ifdef HAVE_EACCELERATOR
33 #ifdef WITH_EACCELERATOR_CONTENT_CACHING
34
35 #include "cache.h"
36 #include "content.h"
37 #include "SAPI.h"
38
39 #define EACCELERATOR_COMPRESS_MIN 128
40
41 eaccelerator_cache_place eaccelerator_content_cache_place = eaccelerator_shm_and_disk;
42
43 static int (*eaccelerator_old_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC);
44
45 PHP_INI_MH (eaccelerator_OnUpdateContentCachePlace)
46 {
47         if (strncasecmp ("shm_and_disk", new_value,
48                 sizeof ("shm_and_disk")) == 0)
49         {
50                 eaccelerator_content_cache_place = eaccelerator_shm_and_disk;
51         }
52         else if (strncasecmp ("shm", new_value,
53                 sizeof ("shm")) == 0)
54         {
55                 eaccelerator_content_cache_place = eaccelerator_shm;
56         }
57         else if (strncasecmp ("shm_only", new_value,
58                 sizeof ("shm_only")) == 0)
59         {
60                 eaccelerator_content_cache_place = eaccelerator_shm_only;
61         }
62         else if (strncasecmp ("disk_only", new_value,
63                 sizeof ("disk_only")) == 0)
64         {
65                 eaccelerator_content_cache_place = eaccelerator_disk_only;
66         }
67         else if (strncasecmp ("none", new_value,
68                 sizeof ("none")) == 0)
69         {
70                 eaccelerator_content_cache_place = eaccelerator_none;
71         }
72         return SUCCESS;
73 }
74
75 static int eaccelerator_check_compression(sapi_header_struct *sapi_header TSRMLS_DC) {
76   if (strstr(sapi_header->header, "Content-Type") == sapi_header->header) {
77     char *ch = sapi_header->header + sizeof("Content-Type") - 1;
78     while (*ch != '\0' && *ch != ':') {ch++;}
79     if (*ch == ':') {ch++;}
80     while (*ch == ' ') {ch++;}
81     if (strstr(ch, "text") != ch) {
82       MMCG(compress_content) = 0;
83       return 0;
84     }
85   } else if (strstr(sapi_header->header, "Content-Encoding") == sapi_header->header) {
86     MMCG(compress_content) = 0;
87     return 0;
88   }
89   return 1;
90 }
91
92 static void eaccelerator_free_header(sapi_header_struct *sapi_header) {
93   efree(sapi_header->header);
94 }
95
96 static int eaccelerator_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) {
97   if (MMCG(content_headers) != NULL) {
98     sapi_header_struct x;
99     memcpy(&x, sapi_header, sizeof(sapi_header_struct));
100     x.header = estrndup(sapi_header->header, sapi_header->header_len);
101     zend_llist_add_element(MMCG(content_headers), &x);
102   }
103   eaccelerator_check_compression(sapi_header TSRMLS_CC);
104   if (eaccelerator_old_header_handler) {
105     return eaccelerator_old_header_handler(sapi_header, sapi_headers TSRMLS_CC);
106   } else {
107     return SAPI_HEADER_ADD;
108   }
109 }
110
111 void eaccelerator_content_cache_startup() {
112   if (eaccelerator_content_cache_place != eaccelerator_none) {
113     eaccelerator_old_header_handler = sapi_module.header_handler;
114     sapi_module.header_handler = eaccelerator_header_handler;
115   }
116 }
117
118 void eaccelerator_content_cache_shutdown() {
119   if (eaccelerator_content_cache_place != eaccelerator_none) {
120     sapi_module.header_handler = eaccelerator_old_header_handler;
121   }
122 }
123
124 static int eaccelerator_is_not_modified(zval* return_value TSRMLS_DC) {
125   char  etag[256];
126   zval  **server_vars, **match;
127
128   if (!SG(headers_sent)) {
129     sprintf(etag,"ETag: eaccelerator-%u",eaccelerator_crc32(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value)));
130     sapi_add_header(etag, strlen(etag), 1);
131     if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
132         Z_TYPE_PP(server_vars) == IS_ARRAY &&
133         zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_IF_NONE_MATCH", sizeof("HTTP_IF_NONE_MATCH"), (void **) &match)==SUCCESS &&
134         Z_TYPE_PP(match) == IS_STRING) {
135       if (strcmp(etag+6,Z_STRVAL_PP(match)) == 0 &&
136           sapi_add_header("HTTP/1.0 304", sizeof("HTTP/1.0 304") - 1, 1) == SUCCESS &&
137           sapi_add_header("Status: 304 Not Modified", sizeof("Status: 304 Not Modified") - 1, 1) == SUCCESS) {
138         zval_dtor(return_value);
139         return_value->value.str.val = empty_string;
140         return_value->value.str.len = 0;
141         /*fprintf(stderr,"\nnot-modified\n");*/
142         return 1;
143       }
144     }
145   }
146   return 0;
147 }
148
149 static void eaccelerator_put_page(const char* key, int key_len, zval* content, time_t ttl  TSRMLS_DC) {
150   zval cache_array;
151   zval *cache_content;
152   INIT_ZVAL(cache_array);
153   array_init(&cache_array);
154   MAKE_STD_ZVAL(cache_content);
155   if (MMCG(content_headers) && (MMCG(content_headers)->count > 0)) {
156     zend_llist_element *p = MMCG(content_headers)->head;
157     zval *headers;
158     MAKE_STD_ZVAL(headers);
159     array_init(headers);
160     while (p != NULL) {
161       sapi_header_struct* h = (sapi_header_struct*)&p->data;
162       char* s = emalloc(h->header_len+2);
163       s[0] = h->replace?'1':'0';
164       memcpy(s+1, h->header, h->header_len+1);
165       add_next_index_stringl(headers, s, h->header_len+1, 0);
166       p = p->next;
167     }
168     add_assoc_zval(&cache_array, "headers", headers);
169   }
170   memcpy(cache_content, content, sizeof(zval));
171   zval_copy_ctor(cache_content);
172   cache_content->is_ref = 0;
173   cache_content->refcount = 1;
174   add_assoc_zval(&cache_array, "content", cache_content);
175   eaccelerator_put(key, key_len , &cache_array, ttl, eaccelerator_content_cache_place TSRMLS_CC);
176   zval_dtor(&cache_array);
177 }
178
179 static int eaccelerator_send_header(zval **header TSRMLS_DC) {
180   sapi_add_header_ex(Z_STRVAL_PP(header)+1, Z_STRLEN_PP(header)-1, 1,
181                      (zend_bool)((Z_STRVAL_PP(header)[0] == '0')?0:1) TSRMLS_CC);
182   return SUCCESS;
183 }
184
185 static int eaccelerator_get_page(const char* key, int key_len, zval* return_value TSRMLS_DC) {
186   int   ret = 0;
187   zval cache_array;
188   zval **headers;
189   zval **content;
190   if (eaccelerator_get(key, key_len, &cache_array, eaccelerator_content_cache_place TSRMLS_CC)) {
191     if (Z_TYPE(cache_array) == IS_ARRAY) {
192       if (zend_hash_find(Z_ARRVAL(cache_array),"content",sizeof("content"),(void**)&content) == SUCCESS &&
193          Z_TYPE_PP(content) == IS_STRING) {
194         if (zend_hash_find(Z_ARRVAL(cache_array),"headers",sizeof("headers"),(void**)&headers) == SUCCESS &&
195            Z_TYPE_PP(headers) == IS_ARRAY) {
196           zend_hash_apply(Z_ARRVAL_PP(headers), (apply_func_t)eaccelerator_send_header TSRMLS_CC);
197         }
198         memcpy(return_value,*content, sizeof(zval));
199         zval_copy_ctor(return_value);
200         ret = 1;
201       }
202     }
203     zval_dtor(&cache_array);
204   }
205   return ret;
206 }
207
208 static void eaccelerator_compress(char* key, int key_len, zval* return_value, time_t ttl TSRMLS_DC) {
209   zval  **server_vars, **encoding;
210
211   if (MMCG(compression_enabled) &&
212       MMCG(compress_content) &&
213       !SG(headers_sent) &&
214       zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
215       Z_TYPE_PP(server_vars) == IS_ARRAY &&
216       zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void **) &encoding)==SUCCESS &&
217       Z_TYPE_PP(encoding) == IS_STRING &&
218       Z_TYPE_P(return_value) == IS_STRING &&
219       Z_STRLEN_P(return_value) >= EACCELERATOR_COMPRESS_MIN) {
220     char* zkey = NULL;
221     int   zkey_len;
222     char* enc;
223     zval  func;
224     zval* params[2];
225     zval  gzstring;
226     int   gzip = 0;
227     zval  level;
228
229     zend_llist_element *p = SG(sapi_headers).headers.head;
230     while (p != NULL) {
231       sapi_header_struct* h = (sapi_header_struct*)&p->data;
232       if (!eaccelerator_check_compression(h TSRMLS_CC)) {
233         eaccelerator_is_not_modified(return_value TSRMLS_CC);
234         return;
235       }
236       p = p->next;
237     }
238
239     if (strstr(Z_STRVAL_PP(encoding),"x-gzip")) {
240       zkey_len = sizeof("gzip_") + key_len - 1;
241       zkey = emalloc(zkey_len+1);
242       memcpy(zkey,"gzip_",sizeof("gzip_")-1);
243       memcpy(zkey+sizeof("gzip_")-1,key,key_len+1);
244       ZVAL_STRING(&func, "gzcompress", 0);
245       enc = "Content-Encoding: x-gzip";
246       params[0] = return_value;
247       gzip = 1;
248     } else if (strstr(Z_STRVAL_PP(encoding),"gzip")) {
249       zkey_len = sizeof("gzip_") + key_len - 1;
250       zkey = emalloc(zkey_len+1);
251       memcpy(zkey,"gzip_",sizeof("gzip_")-1);
252       memcpy(zkey+sizeof("gzip_")-1,key,key_len+1);
253       ZVAL_STRING(&func, "gzcompress", 0);
254       enc = "Content-Encoding: gzip";
255       params[0] = return_value;
256       gzip = 1;
257     } else if (strstr(Z_STRVAL_PP(encoding),"deflate")) {
258       zkey_len = sizeof("deflate_") + key_len - 1;
259       zkey = emalloc(zkey_len+1);
260       memcpy(zkey,"deflate_",sizeof("deflate_")-1);
261       memcpy(zkey+sizeof("deflate_")-1,key,key_len+1);
262       ZVAL_STRING(&func, "gzdeflate", 0);
263       enc = "Content-Encoding: deflate";
264       params[0] = return_value;
265     } else {
266       eaccelerator_is_not_modified(return_value TSRMLS_CC);
267       return;
268     }
269     INIT_ZVAL(level);
270     ZVAL_LONG(&level,MMCG(compress_level));
271     params[1] = &level;
272     if (zkey != NULL &&
273         zend_hash_exists(EG(function_table), Z_STRVAL(func), Z_STRLEN(func)+1) &&
274         call_user_function(CG(function_table), (zval**)NULL, &func, &gzstring, 2, params TSRMLS_CC) == SUCCESS &&
275         gzstring.type == IS_STRING) {
276       if (gzip) {
277         char* ret = emalloc(gzstring.value.str.len+13);
278         unsigned long crc32 = eaccelerator_crc32(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value));
279         ret[0] = '\x1f';
280         ret[1] = '\x8b';
281         ret[2] = '\x08';
282         ret[3] = '\x00';
283         ret[4] = '\x00';
284         ret[5] = '\x00';
285         ret[6] = '\x00';
286         ret[7] = '\x00';
287         ret[8] = '\x00';
288         ret[9] = '\x03';
289         memcpy(ret+10,gzstring.value.str.val+2,gzstring.value.str.len-6);
290         ret[gzstring.value.str.len+4]  = (char)(crc32 & 0xff);
291         ret[gzstring.value.str.len+5]  = (char)((crc32 >> 8) & 0xff);
292         ret[gzstring.value.str.len+6]  = (char)((crc32 >> 16) & 0xff);
293         ret[gzstring.value.str.len+7]  = (char)((crc32 >> 24) & 0xff);
294         ret[gzstring.value.str.len+8]  = (char)(return_value->value.str.len & 0xff);
295         ret[gzstring.value.str.len+9]  = (char)((return_value->value.str.len >> 8) & 0xff);
296         ret[gzstring.value.str.len+10] = (char)((return_value->value.str.len >> 16) & 0xff);
297         ret[gzstring.value.str.len+11] = (char)((return_value->value.str.len >> 24) & 0xff);
298         ret[gzstring.value.str.len+12] = '\x00';
299         STR_FREE(gzstring.value.str.val);
300         gzstring.value.str.val = ret;
301         gzstring.value.str.len += 12;
302       }
303       eaccelerator_put_page(zkey, zkey_len, &gzstring, ttl TSRMLS_CC);
304       if (!eaccelerator_is_not_modified(&gzstring TSRMLS_CC) &&
305           sapi_add_header(enc, strlen(enc), 1) == SUCCESS &&
306           sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1) == SUCCESS) {
307       }
308       efree(zkey);
309       zval_dtor(return_value);
310       memcpy(return_value,&gzstring,sizeof(zval));
311       return;
312     }
313     if (zkey != NULL) {
314       efree(zkey);
315     }
316   }
317   eaccelerator_is_not_modified(return_value TSRMLS_CC);
318 }
319
320 static void eaccelerator_destroy_headers(TSRMLS_D) {
321   if (MMCG(content_headers) != NULL) {
322     zend_llist_destroy(MMCG(content_headers));
323     efree(MMCG(content_headers));
324     MMCG(content_headers) = NULL;
325   }
326 }
327
328 PHP_FUNCTION(_eaccelerator_output_handler) {
329   zval* content;
330   long  status;
331   char* s;
332   char* key;
333   int   key_len = 0;
334   time_t ttl = 0;
335
336   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
337                             "z|l", &content, &status) == FAILURE) {
338     eaccelerator_destroy_headers(TSRMLS_C);
339     return;
340   }
341   memcpy(return_value, content, sizeof(zval));
342   s = key = return_value->value.str.val;
343   if ((status & PHP_OUTPUT_HANDLER_START) != 0) {
344     while (*s) {++s;}
345     ttl = atoi(key);
346     s = key = s+1;
347     if (s - return_value->value.str.val > return_value->value.str.len) {
348       zval_copy_ctor(return_value);
349       eaccelerator_destroy_headers(TSRMLS_C);
350       return;
351     }
352     while (*s) {++s;}
353     key_len = atoi(key);
354     s = key = s+1;
355     if (s - return_value->value.str.val > return_value->value.str.len) {
356       zval_copy_ctor(return_value);
357       eaccelerator_destroy_headers(TSRMLS_C);
358       return;
359     }
360     while (*s) {++s;}
361     ++s;
362     if (s - return_value->value.str.val > return_value->value.str.len) {
363       zval_copy_ctor(return_value);
364       eaccelerator_destroy_headers(TSRMLS_C);
365       return;
366     }
367   }
368   return_value->value.str.len -= (s-return_value->value.str.val);
369   return_value->value.str.val = s;
370   zval_copy_ctor(return_value);
371   if ((status & PHP_OUTPUT_HANDLER_START) != 0 &&
372       (status & PHP_OUTPUT_HANDLER_END) != 0 &&
373       !(PG(connection_status) & PHP_CONNECTION_ABORTED) != 0) {
374     eaccelerator_put_page(key, key_len , return_value, ttl TSRMLS_CC);
375     eaccelerator_compress(key, key_len, return_value, ttl TSRMLS_CC);
376   }
377   eaccelerator_destroy_headers(TSRMLS_C);
378 }
379
380 PHP_FUNCTION(eaccelerator_cache_page) {
381   char* key;
382   int   key_len;
383   long  ttl = 0;
384   zval  **server_vars, **encoding;
385
386   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
387                           "s|l", &key, &key_len, &ttl) == FAILURE) {
388     RETURN_FALSE;
389   }
390   if (eaccelerator_content_cache_place == eaccelerator_none) {
391     RETURN_FALSE;
392   }
393   if (MMCG(content_headers) != NULL) {
394     RETURN_FALSE;
395   }
396   if (MMCG(compression_enabled) &&
397       MMCG(compress_content) &&
398       !SG(headers_sent) &&
399       zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
400       Z_TYPE_PP(server_vars) == IS_ARRAY &&
401       zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void **) &encoding)==SUCCESS &&
402       Z_TYPE_PP(encoding) == IS_STRING) {
403     char* zkey = NULL;
404     char* enc = NULL;
405     int   zkey_len = 0;
406     if (strstr(Z_STRVAL_PP(encoding),"x-gzip")) {
407       zkey_len = sizeof("gzip_") + key_len - 1;
408       zkey = emalloc(zkey_len+1);
409       memcpy(zkey,"gzip_",sizeof("gzip_")-1);
410       memcpy(zkey+sizeof("gzip_")-1,key,key_len+1);
411       enc = "Content-Encoding: x-gzip";
412     } else if (strstr(Z_STRVAL_PP(encoding),"gzip")) {
413       zkey_len = sizeof("gzip_") + key_len - 1;
414       zkey = emalloc(zkey_len+1);
415       memcpy(zkey,"gzip_",sizeof("gzip_")-1);
416       memcpy(zkey+sizeof("gzip_")-1,key,key_len+1);
417       enc = "Content-Encoding: gzip";
418     } else if (strstr(Z_STRVAL_PP(encoding),"deflate")) {
419       zkey_len = sizeof("deflate_") + key_len - 1;
420       zkey = emalloc(zkey_len+1);
421       memcpy(zkey,"deflate_",sizeof("deflate_")-1);
422       memcpy(zkey+sizeof("deflate_")-1,key,key_len+1);
423       enc = "Content-Encoding: deflate";
424     }
425     if (zkey != NULL &&
426         eaccelerator_get_page(zkey, zkey_len, return_value TSRMLS_CC) &&
427         return_value->type == IS_STRING) {
428       if (!eaccelerator_is_not_modified(return_value TSRMLS_CC) &&
429           sapi_add_header(enc, strlen(enc), 1) == SUCCESS &&
430           sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1) == SUCCESS) {
431         ZEND_WRITE(return_value->value.str.val, return_value->value.str.len);
432       }
433       efree(zkey);
434       zend_bailout();
435       RETURN_TRUE;
436     }
437     if (zkey != NULL) {
438       efree(zkey);
439     }
440   }
441   if (eaccelerator_get_page(key, key_len, return_value TSRMLS_CC) &&
442       return_value->type == IS_STRING) {
443     /*  Output is cached. Print it. */
444     if (!(PG(connection_status) & PHP_CONNECTION_ABORTED)) {
445       eaccelerator_compress(key, key_len, return_value, ttl TSRMLS_CC);
446     }
447     ZEND_WRITE(return_value->value.str.val, return_value->value.str.len);
448     zend_bailout();
449     RETURN_TRUE;
450   } else {
451     /* Output is not cached. Install Handler. */
452     char ch = '\000';
453 #ifdef PHP_OUTPUT_HANDLER_USER
454 #if defined(PHP_MAJOR_VERSION) && defined(PHP_MINOR_VERSION) && \
455     ((PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION >= 3) || \
456      (PHP_MAJOR_VERSION > 4))
457     /* PHP 4.3.0 and above */
458     zval handler;
459     ZVAL_STRING(&handler, "_eaccelerator_output_handler", 0);
460     php_start_ob_buffer(&handler, 0, 0 TSRMLS_CC);
461     if (OG(active_ob_buffer).handler_name == NULL ||
462         strcmp(OG(active_ob_buffer).handler_name,"_eaccelerator_output_handler") != 0) {
463 #else
464     /* PHP 4.2.* */
465     zval *handler;
466     ALLOC_INIT_ZVAL(handler);
467     ZVAL_STRING(handler, "_eaccelerator_output_handler", 1);
468     php_start_ob_buffer(handler, 0, 0 TSRMLS_CC);
469     if (OG(active_ob_buffer).handler_name == NULL ||
470         strcmp(OG(active_ob_buffer).handler_name,"_eaccelerator_output_handler") != 0) {
471 #endif
472 #else
473     /* PHP 4.1.2 and before */
474     zval *handler;
475     ALLOC_INIT_ZVAL(handler);
476     ZVAL_STRING(handler, "_eaccelerator_output_handler", 1);
477     if (php_start_ob_buffer(handler, 0 TSRMLS_CC) == FAILURE) {
478 #endif
479       RETURN_FALSE;
480     }
481     zend_printf("%ld",ttl);
482     ZEND_PUTC(ch);
483     zend_printf("%d",key_len);
484     ZEND_PUTC(ch);
485     zend_printf("%s",key);
486     ZEND_PUTC(ch);
487     /* Init headers cache */
488     MMCG(content_headers) = emalloc(sizeof(zend_llist));
489     zend_llist_init(MMCG(content_headers), sizeof(sapi_header_struct), (void (*)(void *))eaccelerator_free_header, 0);
490     RETURN_TRUE;
491   }
492   RETURN_FALSE;
493 }
494
495 PHP_FUNCTION(eaccelerator_rm_page) {
496   char* key;
497   int   key_len;
498   char* zkey;
499   int   zkey_len;
500
501   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
502                           "s", &key, &key_len) == FAILURE) {
503     return;
504   }
505   if (eaccelerator_content_cache_place == eaccelerator_none) {
506     RETURN_NULL();
507   }
508   zkey = do_alloca(key_len+16);
509   eaccelerator_rm(key, key_len, eaccelerator_content_cache_place TSRMLS_CC);
510   zkey_len = sizeof("gzip_") + key_len - 1;
511   memcpy(zkey,"gzip_",sizeof("gzip_")-1);
512   memcpy(zkey+sizeof("gzip_")-1,key,key_len+1);
513   eaccelerator_rm(zkey, zkey_len, eaccelerator_content_cache_place TSRMLS_CC);
514   zkey_len = sizeof("deflate_") + key_len - 1;
515   memcpy(zkey,"deflate_",sizeof("deflate_")-1);
516   memcpy(zkey+sizeof("deflate_")-1,key,key_len+1);
517   eaccelerator_rm(zkey, zkey_len, eaccelerator_content_cache_place TSRMLS_CC);
518   RETURN_NULL();
519 }
520
521 PHP_FUNCTION(eaccelerator_cache_output) {
522   char* key;
523   int   key_len;
524   char* code;
525   int   code_len;
526   long  ttl = 0;
527   char* eval_name;
528   int ret = 0;
529
530   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
531                           "ss|l", &key, &key_len, &code, &code_len, &ttl) == FAILURE) {
532     return;
533   }
534   if (eaccelerator_content_cache_place == eaccelerator_none) {
535     eval_name = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
536     zend_eval_string(code, NULL, eval_name TSRMLS_CC);
537     efree(eval_name);
538     RETURN_FALSE;
539   } else if (eaccelerator_get(key, key_len, return_value, eaccelerator_content_cache_place TSRMLS_CC) &&
540       return_value->type == IS_STRING) {
541     /*  Output is cached. Print it. */
542     ZEND_WRITE(return_value->value.str.val, return_value->value.str.len);
543     zval_dtor(return_value);
544     RETURN_TRUE;
545   } else {
546     /* Output is not cached. Generate it and print. */
547     eval_name = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
548 #ifdef PHP_OUTPUT_HANDLER_USER
549     /* PHP 4.2.0 and above */
550     if (php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC) == FAILURE) {
551 #else
552     /* PHP 4.1.2 and before */
553     if (php_start_ob_buffer(NULL, 0 TSRMLS_CC) == FAILURE) {
554 #endif
555       zend_eval_string(code, NULL, eval_name TSRMLS_CC);
556       efree(eval_name);
557       RETURN_FALSE;
558     }
559     if (zend_eval_string(code, NULL, eval_name TSRMLS_CC) == SUCCESS) {
560       if (php_ob_get_buffer(return_value TSRMLS_CC) == SUCCESS) {
561         ret = eaccelerator_put(key, key_len, return_value, ttl, eaccelerator_content_cache_place TSRMLS_CC);
562         zval_dtor(return_value);
563       }
564     }
565     efree(eval_name);
566     php_end_ob_buffer(1, 0 TSRMLS_CC);
567     if (ret) {
568       RETURN_TRUE;
569     }
570   }
571   RETURN_FALSE;
572 }
573
574 PHP_FUNCTION(eaccelerator_cache_result) {
575   char* key;
576   int   key_len;
577   char* code;
578   int   code_len;
579   long  ttl = 0;
580   char* eval_name;
581
582   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
583                           "ss|l", &key, &key_len, &code, &code_len, &ttl) == FAILURE) {
584     return;
585   }
586   if ((eaccelerator_content_cache_place != eaccelerator_none) &&
587       eaccelerator_get(key, key_len, return_value, eaccelerator_content_cache_place TSRMLS_CC)) {
588     /*  Return value is cached. Return it. */
589     return;
590   } else {
591     /* Return value is not cached. Generate it and return. */
592     eval_name = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
593     if (zend_eval_string(code, return_value, eval_name TSRMLS_CC) == SUCCESS &&
594         eaccelerator_content_cache_place != eaccelerator_none) {
595
596       /* clean garbage */
597       while (EG(garbage_ptr)) {
598         zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
599       }
600
601       eaccelerator_put(key, key_len, return_value, ttl, eaccelerator_content_cache_place TSRMLS_CC);
602     }
603     efree(eval_name);
604     return;
605   }
606 }
607
608 #endif
609 #endif
Note: See TracBrowser for help on using the browser.