root/eaccelerator/tags/0.9.5-beta2/content.c

Revision 182, 21.9 kB (checked in by bart, 3 years ago)

Set the svn keywords property to some files

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