root/eaccelerator/trunk/content.c

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