+++ /dev/null
-diff -Naur a/ext/apc/apc_bin.c b/ext/apc/apc_bin.c
---- a/ext/apc/apc_bin.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_bin.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,987 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_bin.c 324017 2012-03-08 09:46:22Z pajoye $ */
-+
-+/* Creates a binary architecture specific output to a string or file containing
-+ * the current cache contents for both fies and user variables. This is accomplished
-+ * via the apc_copy_* functions and "swizzling" pointer values to a position
-+ * independent value, and unswizzling them on restoration.
-+ */
-+
-+#include "apc_globals.h"
-+#include "apc_bin.h"
-+#include "apc_zend.h"
-+#include "apc_php.h"
-+#include "apc_sma.h"
-+#include "apc_pool.h"
-+#include "ext/standard/md5.h"
-+#include "ext/standard/crc32.h"
-+
-+extern apc_cache_t* apc_cache;
-+extern apc_cache_t* apc_user_cache;
-+
-+extern int _apc_store(char *strkey, int strkey_len, const zval *val, const uint ttl, const int exclusive TSRMLS_DC); /* this is hacky */
-+
-+#define APC_BINDUMP_DEBUG 0
-+
-+
-+#if APC_BINDUMP_DEBUG
-+
-+#define SWIZZLE(bd, ptr) \
-+ do { \
-+ if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \
-+ printf("SWIZZLE: %x ~> ", ptr); \
-+ ptr = (void*)((long)(ptr) - (long)(bd)); \
-+ printf("%x in %s on line %d", ptr, __FILE__, __LINE__); \
-+ } else if((long)ptr > bd->size) { /* not swizzled */ \
-+ apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \
-+ return; \
-+ } \
-+ printf("\n"); \
-+ } while(0);
-+
-+#define UNSWIZZLE(bd, ptr) \
-+ do { \
-+ printf("UNSWIZZLE: %x -> ", ptr); \
-+ ptr = (void*)((long)(ptr) + (long)(bd)); \
-+ printf("%x in %s on line %d \n", ptr, __FILE__, __LINE__); \
-+ } while(0);
-+
-+#else /* !APC_BINDUMP_DEBUG */
-+
-+#define SWIZZLE(bd, ptr) \
-+ do { \
-+ if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \
-+ ptr = (void*)((long)(ptr) - (long)(bd)); \
-+ } else if((ulong)ptr > bd->size) { /* not swizzled */ \
-+ apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \
-+ return NULL; \
-+ } \
-+ } while(0);
-+
-+#define UNSWIZZLE(bd, ptr) \
-+ do { \
-+ ptr = (void*)((long)(ptr) + (long)(bd)); \
-+ } while(0);
-+
-+#endif
-+
-+
-+static void *apc_bd_alloc(size_t size TSRMLS_DC);
-+static void apc_bd_free(void *ptr TSRMLS_DC);
-+static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC);
-+
-+typedef void (*apc_swizzle_cb_t)(apc_bd_t *bd, zend_llist *ll, void *ptr TSRMLS_DC);
-+
-+#if APC_BINDUMP_DEBUG
-+#define apc_swizzle_ptr(bd, ll, ptr) _apc_swizzle_ptr(bd, ll, (void*)ptr, __FILE__, __LINE__ TSRMLS_CC)
-+#else
-+#define apc_swizzle_ptr(bd, ll, ptr) _apc_swizzle_ptr(bd, ll, (void*)ptr, NULL, 0 TSRMLS_CC)
-+#endif
-+
-+static void _apc_swizzle_ptr(apc_bd_t *bd, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC);
-+static void apc_swizzle_function(apc_bd_t *bd, zend_llist *ll, zend_function *func TSRMLS_DC);
-+static void apc_swizzle_class_entry(apc_bd_t *bd, zend_llist *ll, zend_class_entry *ce TSRMLS_DC);
-+static void apc_swizzle_hashtable(apc_bd_t *bd, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC);
-+static void apc_swizzle_zval(apc_bd_t *bd, zend_llist *ll, zval *zv TSRMLS_DC);
-+static void apc_swizzle_op_array(apc_bd_t *bd, zend_llist *ll, zend_op_array *op_array TSRMLS_DC);
-+static void apc_swizzle_property_info(apc_bd_t *bd, zend_llist *ll, zend_property_info *pi TSRMLS_DC);
-+static void apc_swizzle_function_entry(apc_bd_t *bd, zend_llist *ll, const zend_function_entry *fe TSRMLS_DC);
-+static void apc_swizzle_arg_info_array(apc_bd_t *bd, zend_llist *ll, const zend_arg_info* arg_info_array, uint num_args TSRMLS_DC);
-+
-+static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC);
-+static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC);
-+
-+
-+/* {{{ apc_bd_alloc
-+ * callback for copy_* functions */
-+static void *apc_bd_alloc(size_t size TSRMLS_DC) {
-+ return apc_bd_alloc_ex(NULL, size TSRMLS_CC);
-+} /* }}} */
-+
-+
-+/* {{{ apc_bd_free
-+ * callback for copy_* functions */
-+static void apc_bd_free(void *ptr TSRMLS_DC) {
-+ size_t *size;
-+ if(zend_hash_index_find(&APCG(apc_bd_alloc_list), (ulong)ptr, (void**)&size) == FAILURE) {
-+ apc_error("apc_bd_free could not free pointer (not found in list: %x)" TSRMLS_CC, ptr);
-+ return;
-+ }
-+ APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) - *size);
-+ zend_hash_index_del(&APCG(apc_bd_alloc_list), (ulong)ptr);
-+} /* }}} */
-+
-+
-+/* {{{ apc_bd_alloc_ex
-+ * set ranges or allocate a block of data from an already (e)malloc'd range.
-+ * if ptr_new is not NULL, it will reset the pointer to start at ptr_new,
-+ * with a range of size. If ptr_new is NULL, returns the next available
-+ * block of given size.
-+ */
-+static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC) {
-+ void *rval;
-+
-+ rval = APCG(apc_bd_alloc_ptr);
-+ if(ptr_new != NULL) { /* reset ptrs */
-+ APCG(apc_bd_alloc_ptr) = ptr_new;
-+ APCG(apc_bd_alloc_ubptr) = (void*)((unsigned char *) ptr_new + size);
-+ } else { /* alloc block */
-+ APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) + size);
-+#if APC_BINDUMP_DEBUG
-+ apc_notice("apc_bd_alloc: rval: 0x%x ptr: 0x%x ubptr: 0x%x size: %d" TSRMLS_CC, rval, APCG(apc_bd_alloc_ptr), APCG(apc_bd_alloc_ubptr), size);
-+#endif
-+ if(APCG(apc_bd_alloc_ptr) > APCG(apc_bd_alloc_ubptr)) {
-+ apc_error("Exceeded bounds check in apc_bd_alloc_ex by %d bytes." TSRMLS_CC, (unsigned char *) APCG(apc_bd_alloc_ptr) - (unsigned char *) APCG(apc_bd_alloc_ubptr));
-+ return NULL;
-+ }
-+ zend_hash_index_update(&APCG(apc_bd_alloc_list), (ulong)rval, &size, sizeof(size_t), NULL);
-+ }
-+
-+ return rval;
-+} /* }}} */
-+
-+
-+/* {{{ _apc_swizzle_ptr */
-+static void _apc_swizzle_ptr(apc_bd_t *bd, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC) {
-+ if(*ptr) {
-+ if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) {
-+ zend_llist_add_element(ll, &ptr);
-+#if APC_BINDUMP_DEBUG
-+ printf("[%06d] apc_swizzle_ptr: %x -> %x ", zend_llist_count(ll), ptr, *ptr);
-+ printf(" in %s on line %d \n", file, line);
-+#endif
-+ } else if((ulong)ptr > bd->size) {
-+ apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, *ptr, ((long)bd + bd->size), file, line); \
-+ return;
-+ }
-+ }
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_op_array */
-+static void apc_swizzle_op_array(apc_bd_t *bd, zend_llist *ll, zend_op_array *op_array TSRMLS_DC) {
-+ uint i;
-+
-+#ifdef ZEND_ENGINE_2
-+ apc_swizzle_arg_info_array(bd, ll, op_array->arg_info, op_array->num_args TSRMLS_CC);
-+ apc_swizzle_ptr(bd, ll, &op_array->arg_info);
-+#else
-+ if (op_array->arg_types) {
-+ apc_swizzle_ptr(bd, ll, &op_array->arg_types);
-+ }
-+#endif
-+
-+ apc_swizzle_ptr(bd, ll, &op_array->function_name);
-+ apc_swizzle_ptr(bd, ll, &op_array->filename);
-+ apc_swizzle_ptr(bd, ll, &op_array->refcount);
-+
-+ /* swizzle op_array */
-+ for(i=0; i < op_array->last; i++) {
-+#ifndef ZEND_ENGINE_2_4
-+ if(op_array->opcodes[i].result.op_type == IS_CONST) {
-+ apc_swizzle_zval(bd, ll, &op_array->opcodes[i].result.u.constant TSRMLS_CC);
-+ }
-+ if(op_array->opcodes[i].op1.op_type == IS_CONST) {
-+ apc_swizzle_zval(bd, ll, &op_array->opcodes[i].op1.u.constant TSRMLS_CC);
-+ }
-+ if(op_array->opcodes[i].op2.op_type == IS_CONST) {
-+ apc_swizzle_zval(bd, ll, &op_array->opcodes[i].op2.u.constant TSRMLS_CC);
-+ }
-+#endif
-+ switch (op_array->opcodes[i].opcode) {
-+ case ZEND_JMP:
-+#ifdef ZEND_ENGINE_2_4
-+ apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op1.jmp_addr);
-+#else
-+ apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op1.u.jmp_addr);
-+#endif
-+ case ZEND_JMPZ:
-+ case ZEND_JMPNZ:
-+ case ZEND_JMPZ_EX:
-+ case ZEND_JMPNZ_EX:
-+#ifdef ZEND_ENGINE_2_4
-+ apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op2.jmp_addr);
-+#else
-+ apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op2.u.jmp_addr);
-+#endif
-+ }
-+ }
-+ apc_swizzle_ptr(bd, ll, &op_array->opcodes);
-+
-+ /* break-continue array ptr */
-+ if(op_array->brk_cont_array) {
-+ apc_swizzle_ptr(bd, ll, &op_array->brk_cont_array);
-+ }
-+
-+ /* static voriables */
-+ if(op_array->static_variables) {
-+ apc_swizzle_hashtable(bd, ll, op_array->static_variables, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+ apc_swizzle_ptr(bd, ll, &op_array->static_variables);
-+ }
-+
-+#ifdef ZEND_ENGINE_2
-+ /* try-catch */
-+ if(op_array->try_catch_array) {
-+ apc_swizzle_ptr(bd, ll, &op_array->try_catch_array);
-+ }
-+#endif
-+
-+#ifdef ZEND_ENGINE_2_1 /* PHP 5.1 */
-+ /* vars */
-+ if(op_array->vars) {
-+ for(i=0; (signed int) i < op_array->last_var; i++) {
-+ apc_swizzle_ptr(bd, ll, &op_array->vars[i].name);
-+ }
-+ apc_swizzle_ptr(bd, ll, &op_array->vars);
-+ }
-+#endif
-+
-+#ifdef ZEND_ENGINE_2
-+ /* doc comment */
-+ if(op_array->doc_comment) {
-+ apc_swizzle_ptr(bd, ll, &op_array->doc_comment);
-+ }
-+#endif
-+
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_function */
-+static void apc_swizzle_function(apc_bd_t *bd, zend_llist *ll, zend_function *func TSRMLS_DC) {
-+ apc_swizzle_op_array(bd, ll, &func->op_array TSRMLS_CC);
-+#ifdef ZEND_ENGINE_2
-+ if(func->common.scope) {
-+ apc_swizzle_ptr(bd, ll, &func->common.scope);
-+ }
-+#endif
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_class_entry */
-+static void apc_swizzle_class_entry(apc_bd_t *bd, zend_llist *ll, zend_class_entry *ce TSRMLS_DC) {
-+
-+ uint i;
-+
-+ if(ce->name) {
-+ apc_swizzle_ptr(bd, ll, &ce->name);
-+ }
-+
-+ if (ce->type == ZEND_USER_CLASS && ZEND_CE_DOC_COMMENT(ce)) {
-+ apc_swizzle_ptr(bd, ll, &ZEND_CE_DOC_COMMENT(ce));
-+ }
-+
-+#ifndef ZEND_ENGINE_2
-+ apc_swizzle_ptr(bd, ll, &ce->refcount);
-+#endif
-+
-+ apc_swizzle_hashtable(bd, ll, &ce->function_table, (apc_swizzle_cb_t)apc_swizzle_function, 0 TSRMLS_CC);
-+#ifdef ZEND_ENGINE_2_4
-+ if (ce->default_properties_table) {
-+ for (i = 0; i < ce->default_properties_count; i++) {
-+ if (ce->default_properties_table[i]) {
-+ apc_swizzle_ptr(bd, ll, &ce->default_properties_table[i]);
-+ apc_swizzle_zval(bd, ll, ce->default_properties_table[i] TSRMLS_CC);
-+ }
-+ }
-+ }
-+#else
-+ apc_swizzle_hashtable(bd, ll, &ce->default_properties, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+#endif
-+
-+#ifdef ZEND_ENGINE_2
-+ apc_swizzle_hashtable(bd, ll, &ce->properties_info, (apc_swizzle_cb_t)apc_swizzle_property_info, 0 TSRMLS_CC);
-+#endif
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (ce->default_static_members_table) {
-+ for (i = 0; i < ce->default_static_members_count; i++) {
-+ if (ce->default_static_members_table[i]) {
-+ apc_swizzle_ptr(bd, ll, &ce->default_static_members_table[i]);
-+ apc_swizzle_zval(bd, ll, ce->default_static_members_table[i] TSRMLS_CC);
-+ }
-+ }
-+ }
-+ ce->static_members_table = ce->default_static_members_table;
-+#else
-+ apc_swizzle_hashtable(bd, ll, &ce->default_static_members, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+
-+ if(ce->static_members != &ce->default_static_members) {
-+ apc_swizzle_hashtable(bd, ll, ce->static_members, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+ } else {
-+ apc_swizzle_ptr(bd, ll, &ce->static_members);
-+ }
-+#endif
-+
-+ apc_swizzle_hashtable(bd, ll, &ce->constants_table, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+
-+ if(ce->type == ZEND_INTERNAL_CLASS && ZEND_CE_BUILTIN_FUNCTIONS(ce)) {
-+ for(i=0; ZEND_CE_BUILTIN_FUNCTIONS(ce)[i].fname; i++) {
-+ apc_swizzle_function_entry(bd, ll, &ZEND_CE_BUILTIN_FUNCTIONS(ce)[i] TSRMLS_CC);
-+ }
-+ }
-+
-+ apc_swizzle_ptr(bd, ll, &ce->constructor);
-+ apc_swizzle_ptr(bd, ll, &ce->destructor);
-+ apc_swizzle_ptr(bd, ll, &ce->clone);
-+ apc_swizzle_ptr(bd, ll, &ce->__get);
-+ apc_swizzle_ptr(bd, ll, &ce->__set);
-+ apc_swizzle_ptr(bd, ll, &ce->__unset);
-+ apc_swizzle_ptr(bd, ll, &ce->__isset);
-+ apc_swizzle_ptr(bd, ll, &ce->__call);
-+ apc_swizzle_ptr(bd, ll, &ce->serialize_func);
-+ apc_swizzle_ptr(bd, ll, &ce->unserialize_func);
-+
-+#ifdef ZEND_ENGINE_2_2
-+ apc_swizzle_ptr(bd, ll, &ce->__tostring);
-+#endif
-+
-+ if (ce->type == ZEND_USER_CLASS) {
-+ apc_swizzle_ptr(bd, ll, &ZEND_CE_FILENAME(ce));
-+ }
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_property_info */
-+static void apc_swizzle_property_info(apc_bd_t *bd, zend_llist *ll, zend_property_info *pi TSRMLS_DC) {
-+ apc_swizzle_ptr(bd, ll, &pi->name);
-+ apc_swizzle_ptr(bd, ll, &pi->doc_comment);
-+
-+#ifdef ZEND_ENGINE_2_2
-+ apc_swizzle_ptr(bd, ll, &pi->ce);
-+#endif
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_function_entry */
-+static void apc_swizzle_function_entry(apc_bd_t *bd, zend_llist *ll, const zend_function_entry *fe TSRMLS_DC) {
-+ apc_swizzle_ptr(bd, ll, &fe->fname);
-+ apc_swizzle_arg_info_array(bd, ll, fe->arg_info, fe->num_args TSRMLS_CC);
-+ apc_swizzle_ptr(bd, ll, &fe->arg_info);
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_arg_info_array */
-+static void apc_swizzle_arg_info_array(apc_bd_t *bd, zend_llist *ll, const zend_arg_info* arg_info_array, uint num_args TSRMLS_DC) {
-+ if(arg_info_array) {
-+ uint i;
-+
-+ for(i=0; i < num_args; i++) {
-+ apc_swizzle_ptr(bd, ll, &arg_info_array[i].name);
-+ apc_swizzle_ptr(bd, ll, &arg_info_array[i].class_name);
-+ }
-+ }
-+
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_hashtable */
-+static void apc_swizzle_hashtable(apc_bd_t *bd, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC) {
-+ uint i;
-+ Bucket **bp, **bp_prev;
-+
-+ bp = &ht->pListHead;
-+ while(*bp) {
-+ bp_prev = bp;
-+ bp = &(*bp)->pListNext;
-+ if(is_ptr) {
-+ swizzle_cb(bd, ll, *(void**)(*bp_prev)->pData TSRMLS_CC);
-+ apc_swizzle_ptr(bd, ll, (*bp_prev)->pData);
-+ } else {
-+ swizzle_cb(bd, ll, (void**)(*bp_prev)->pData TSRMLS_CC);
-+ }
-+ apc_swizzle_ptr(bd, ll, &(*bp_prev)->pData);
-+ if((*bp_prev)->pDataPtr) {
-+ apc_swizzle_ptr(bd, ll, &(*bp_prev)->pDataPtr);
-+ }
-+ if((*bp_prev)->pListLast) {
-+ apc_swizzle_ptr(bd, ll, &(*bp_prev)->pListLast);
-+ }
-+ if((*bp_prev)->pNext) {
-+ apc_swizzle_ptr(bd, ll, &(*bp_prev)->pNext);
-+ }
-+ if((*bp_prev)->pLast) {
-+ apc_swizzle_ptr(bd, ll, &(*bp_prev)->pLast);
-+ }
-+ apc_swizzle_ptr(bd, ll, bp_prev);
-+ }
-+ for(i=0; i < ht->nTableSize; i++) {
-+ if(ht->arBuckets[i]) {
-+ apc_swizzle_ptr(bd, ll, &ht->arBuckets[i]);
-+ }
-+ }
-+ apc_swizzle_ptr(bd, ll, &ht->pListTail);
-+
-+ apc_swizzle_ptr(bd, ll, &ht->arBuckets);
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_zval */
-+static void apc_swizzle_zval(apc_bd_t *bd, zend_llist *ll, zval *zv TSRMLS_DC) {
-+
-+ if(APCG(copied_zvals).nTableSize) {
-+ if(zend_hash_index_exists(&APCG(copied_zvals), (ulong)zv)) {
-+ return;
-+ }
-+ zend_hash_index_update(&APCG(copied_zvals), (ulong)zv, (void**)&zv, sizeof(zval*), NULL);
-+ }
-+
-+ switch(zv->type & IS_CONSTANT_TYPE_MASK) {
-+ case IS_NULL:
-+ case IS_LONG:
-+ case IS_DOUBLE:
-+ case IS_BOOL:
-+ case IS_RESOURCE:
-+ /* nothing to do */
-+ break;
-+ case IS_CONSTANT:
-+ case IS_STRING:
-+ apc_swizzle_ptr(bd, ll, &zv->value.str.val);
-+ break;
-+ case IS_ARRAY:
-+ case IS_CONSTANT_ARRAY:
-+ apc_swizzle_hashtable(bd, ll, zv->value.ht, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
-+ apc_swizzle_ptr(bd, ll, &zv->value.ht);
-+ break;
-+ case IS_OBJECT:
-+ break;
-+ default:
-+ assert(0); /* shouldn't happen */
-+ }
-+} /* }}} */
-+
-+
-+/* {{{ apc_swizzle_bd */
-+static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC) {
-+ int count, i;
-+ PHP_MD5_CTX context;
-+ unsigned char digest[16];
-+ register php_uint32 crc;
-+ php_uint32 crcinit = 0;
-+ char *crc_p;
-+ void ***ptr;
-+ void ***ptr_list;
-+
-+ count = zend_llist_count(ll);
-+ ptr_list = emalloc(count * sizeof(void**));
-+ ptr = zend_llist_get_first(ll);
-+ for(i=0; i < count; i++) {
-+#if APC_BINDUMP_DEBUG
-+ printf("[%06d] ", i+1);
-+#endif
-+ SWIZZLE(bd, **ptr); /* swizzle ptr */
-+ if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) { /* exclude ptrs that aren't actually included in the ptr list */
-+#if APC_BINDUMP_DEBUG
-+ printf("[------] ");
-+#endif
-+ SWIZZLE(bd, *ptr); /* swizzle ptr list */
-+ ptr_list[i] = *ptr;
-+ }
-+ ptr = zend_llist_get_next(ll);
-+ }
-+ SWIZZLE(bd, bd->entries);
-+
-+ if(count > 0) {
-+ bd = erealloc(bd, bd->size + (count * sizeof(void**)));
-+ bd->num_swizzled_ptrs = count;
-+ bd->swizzled_ptrs = (void***)((unsigned char *)bd + bd->size -2); /* extra -1 for null termination */
-+ bd->size += count * sizeof(void**);
-+ memcpy(bd->swizzled_ptrs, ptr_list, count * sizeof(void**));
-+ SWIZZLE(bd, bd->swizzled_ptrs);
-+ } else {
-+ bd->num_swizzled_ptrs = 0;
-+ bd->swizzled_ptrs = NULL;
-+ }
-+ ((char*)bd)[bd->size-1] = 0; /* silence null termination for zval strings */
-+ efree(ptr_list);
-+ bd->swizzled = 1;
-+
-+ /* Generate MD5/CRC32 checksum */
-+ for(i=0; i<16; i++) { bd->md5[i] = 0; }
-+ bd->crc=0;
-+ PHP_MD5Init(&context);
-+ PHP_MD5Update(&context, (const unsigned char*)bd, bd->size);
-+ PHP_MD5Final(digest, &context);
-+ crc = crcinit^0xFFFFFFFF;
-+ crc_p = (char*)bd;
-+ for(i=bd->size; i--; ++crc_p) {
-+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*crc_p)) & 0xFF ];
-+ }
-+ memcpy(bd->md5, digest, 16);
-+ bd->crc = crc;
-+
-+ return bd;
-+} /* }}} */
-+
-+
-+/* {{{ apc_unswizzle_bd */
-+static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC) {
-+ int i;
-+ unsigned char md5_orig[16];
-+ unsigned char digest[16];
-+ PHP_MD5_CTX context;
-+ register php_uint32 crc;
-+ php_uint32 crcinit = 0;
-+ php_uint32 crc_orig;
-+ char *crc_p;
-+
-+ /* Verify the md5 or crc32 before we unswizzle */
-+ memcpy(md5_orig, bd->md5, 16);
-+ for(i=0; i<16; i++) { bd->md5[i] = 0; }
-+ crc_orig = bd->crc;
-+ bd->crc=0;
-+ if(flags & APC_BIN_VERIFY_MD5) {
-+ PHP_MD5Init(&context);
-+ PHP_MD5Update(&context, (const unsigned char*)bd, bd->size);
-+ PHP_MD5Final(digest, &context);
-+ if(memcmp(md5_orig, digest, 16)) {
-+ apc_error("MD5 checksum of binary dump failed." TSRMLS_CC);
-+ return -1;
-+ }
-+ }
-+ if(flags & APC_BIN_VERIFY_CRC32) {
-+ crc = crcinit^0xFFFFFFFF;
-+ crc_p = (char*)bd;
-+ for(i=bd->size; i--; ++crc_p) {
-+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*crc_p)) & 0xFF ];
-+ }
-+ if(crc_orig != crc) {
-+ apc_error("CRC32 checksum of binary dump failed." TSRMLS_CC);
-+ return -1;
-+ }
-+ }
-+ memcpy(bd->md5, md5_orig, 16); /* add back md5 checksum */
-+ bd->crc = crc_orig;
-+
-+ UNSWIZZLE(bd, bd->entries);
-+ UNSWIZZLE(bd, bd->swizzled_ptrs);
-+ for(i=0; i < bd->num_swizzled_ptrs; i++) {
-+ if(bd->swizzled_ptrs[i]) {
-+ UNSWIZZLE(bd, bd->swizzled_ptrs[i]);
-+ if(*bd->swizzled_ptrs[i] && (*bd->swizzled_ptrs[i] < (void*)bd)) {
-+ UNSWIZZLE(bd, *bd->swizzled_ptrs[i]);
-+ }
-+ }
-+ }
-+
-+ bd->swizzled=0;
-+
-+ return 0;
-+} /* }}} */
-+
-+
-+/* {{{ apc_bin_checkfilter */
-+static int apc_bin_checkfilter(HashTable *filter, const char *key, uint key_len) {
-+ zval **zptr;
-+
-+ if(filter == NULL) {
-+ return 1;
-+ }
-+
-+ if(zend_hash_find(filter, (char*)key, key_len, (void**)&zptr) == SUCCESS) {
-+ if(Z_TYPE_PP(zptr) == IS_LONG && Z_LVAL_PP(zptr) == 0) {
-+ return 0;
-+ }
-+ } else {
-+ return 0;
-+ }
-+
-+
-+ return 1;
-+} /* }}} */
-+
-+/* {{{ apc_bin_fixup_op_array */
-+static inline void apc_bin_fixup_op_array(zend_op_array *op_array) {
-+ ulong i;
-+ for (i = 0; i < op_array->last; i++) {
-+ op_array->opcodes[i].handler = zend_opcode_handlers[APC_OPCODE_HANDLER_DECODE(&op_array->opcodes[i])];
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ apc_bin_fixup_class_entry */
-+static inline void apc_bin_fixup_class_entry(zend_class_entry *ce) {
-+ zend_function *fe;
-+ HashPosition hpos;
-+
-+ /* fixup the opcodes in each method */
-+ zend_hash_internal_pointer_reset_ex(&ce->function_table, &hpos);
-+ while(zend_hash_get_current_data_ex(&ce->function_table, (void**)&fe, &hpos) == SUCCESS) {
-+ apc_bin_fixup_op_array(&fe->op_array);
-+ zend_hash_move_forward_ex(&ce->function_table, &hpos);
-+ }
-+
-+ /* fixup hashtable destructor pointers */
-+ ce->function_table.pDestructor = (dtor_func_t)zend_function_dtor;
-+#ifndef ZEND_ENGINE_2_4
-+ ce->default_properties.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
-+#endif
-+ ce->properties_info.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
-+#ifndef ZEND_ENGINE_2_4
-+ ce->default_static_members.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
-+ if (ce->static_members) {
-+ ce->static_members->pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
-+ }
-+#endif
-+ ce->constants_table.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
-+}
-+/* }}} */
-+
-+/* {{{ apc_bin_dump */
-+apc_bd_t* apc_bin_dump(HashTable *files, HashTable *user_vars TSRMLS_DC) {
-+
-+ int i;
-+ uint fcount;
-+ slot_t *sp;
-+ apc_bd_entry_t *ep;
-+ int count=0;
-+ apc_bd_t *bd;
-+ zend_llist ll;
-+ zend_function *efp, *sfp;
-+ long size=0;
-+ apc_context_t ctxt;
-+ void *pool_ptr;
-+
-+ zend_llist_init(&ll, sizeof(void*), NULL, 0);
-+ zend_hash_init(&APCG(apc_bd_alloc_list), 0, NULL, NULL, 0);
-+
-+ /* flip the hash for faster filter checking */
-+ files = apc_flip_hash(files);
-+ user_vars = apc_flip_hash(user_vars);
-+
-+ /* get size and entry counts */
-+ for(i=0; i < apc_user_cache->num_slots; i++) {
-+ sp = apc_user_cache->slots[i];
-+ for(; sp != NULL; sp = sp->next) {
-+ if(apc_bin_checkfilter(user_vars, sp->key.data.user.identifier, sp->key.data.user.identifier_len)) {
-+ size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t);
-+ size += sp->value->mem_size - (sizeof(apc_cache_entry_t) - sizeof(apc_cache_entry_value_t));
-+ count++;
-+ }
-+ }
-+ }
-+ for(i=0; i < apc_cache->num_slots; i++) {
-+ sp = apc_cache->slots[i];
-+ for(; sp != NULL; sp = sp->next) {
-+ if(sp->key.type == APC_CACHE_KEY_FPFILE) {
-+ if(apc_bin_checkfilter(files, sp->key.data.fpfile.fullpath, sp->key.data.fpfile.fullpath_len+1)) {
-+ size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t);
-+ size += sp->value->mem_size - (sizeof(apc_cache_entry_t) - sizeof(apc_cache_entry_value_t));
-+ count++;
-+ }
-+ } else {
-+ /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load */
-+ apc_warning("Excluding some files from apc_bin_dump[file]. Cached files must be included using full path with apc.stat=0." TSRMLS_CC);
-+ }
-+ }
-+ }
-+
-+ size += sizeof(apc_bd_t) +1; /* +1 for null termination */
-+ bd = emalloc(size);
-+ bd->size = size;
-+ pool_ptr = emalloc(sizeof(apc_pool));
-+ apc_bd_alloc_ex(pool_ptr, sizeof(apc_pool) TSRMLS_CC);
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_bd_alloc, apc_bd_free, NULL, NULL TSRMLS_CC); /* ideally the pool wouldn't be alloc'd as part of this */
-+ if (!ctxt.pool) { /* TODO need to cleanup */
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ return NULL;
-+ }
-+ ctxt.copy = APC_COPY_IN_USER; /* avoid stupid ALLOC_ZVAL calls here, hack */
-+ apc_bd_alloc_ex((void*)((long)bd + sizeof(apc_bd_t)), bd->size - sizeof(apc_bd_t) -1 TSRMLS_CC);
-+ bd->num_entries = count;
-+ bd->entries = apc_bd_alloc_ex(NULL, sizeof(apc_bd_entry_t) * count TSRMLS_CC);
-+
-+ /* User entries */
-+ zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
-+ count = 0;
-+ for(i=0; i < apc_user_cache->num_slots; i++) {
-+ sp = apc_user_cache->slots[i];
-+ for(; sp != NULL; sp = sp->next) {
-+ if(apc_bin_checkfilter(user_vars, sp->key.data.user.identifier, sp->key.data.user.identifier_len)) {
-+ ep = &bd->entries[count];
-+ ep->type = sp->value->type;
-+ ep->val.user.info = apc_bd_alloc(sp->value->data.user.info_len TSRMLS_CC);
-+ memcpy(ep->val.user.info, sp->value->data.user.info, sp->value->data.user.info_len);
-+ ep->val.user.info_len = sp->value->data.user.info_len;
-+ ep->val.user.val = apc_copy_zval(NULL, sp->value->data.user.val, &ctxt TSRMLS_CC);
-+ ep->val.user.ttl = sp->value->data.user.ttl;
-+
-+ /* swizzle pointers */
-+ apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.user.info);
-+ zend_hash_clean(&APCG(copied_zvals));
-+ apc_swizzle_zval(bd, &ll, bd->entries[count].val.user.val TSRMLS_CC);
-+ apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.user.val);
-+
-+ count++;
-+ }
-+ }
-+ }
-+ zend_hash_destroy(&APCG(copied_zvals));
-+ APCG(copied_zvals).nTableSize=0;
-+
-+ /* File entries */
-+ for(i=0; i < apc_cache->num_slots; i++) {
-+ for(sp=apc_cache->slots[i]; sp != NULL; sp = sp->next) {
-+ if(sp->key.type == APC_CACHE_KEY_FPFILE) {
-+ if(apc_bin_checkfilter(files, sp->key.data.fpfile.fullpath, sp->key.data.fpfile.fullpath_len+1)) {
-+ ep = &bd->entries[count];
-+ ep->type = sp->key.type;
-+ ep->val.file.filename = apc_bd_alloc(strlen(sp->value->data.file.filename) + 1 TSRMLS_CC);
-+ strcpy(ep->val.file.filename, sp->value->data.file.filename);
-+ ep->val.file.op_array = apc_copy_op_array(NULL, sp->value->data.file.op_array, &ctxt TSRMLS_CC);
-+
-+ for(ep->num_functions=0; sp->value->data.file.functions[ep->num_functions].function != NULL;) { ep->num_functions++; }
-+ ep->val.file.functions = apc_bd_alloc(sizeof(apc_function_t) * ep->num_functions TSRMLS_CC);
-+ for(fcount=0; fcount < ep->num_functions; fcount++) {
-+ memcpy(&ep->val.file.functions[fcount], &sp->value->data.file.functions[fcount], sizeof(apc_function_t));
-+ ep->val.file.functions[fcount].name = apc_xmemcpy(sp->value->data.file.functions[fcount].name, sp->value->data.file.functions[fcount].name_len+1, apc_bd_alloc TSRMLS_CC);
-+ ep->val.file.functions[fcount].name_len = sp->value->data.file.functions[fcount].name_len;
-+ ep->val.file.functions[fcount].function = apc_bd_alloc(sizeof(zend_function) TSRMLS_CC);
-+ efp = ep->val.file.functions[fcount].function;
-+ sfp = sp->value->data.file.functions[fcount].function;
-+ switch(sfp->type) {
-+ case ZEND_INTERNAL_FUNCTION:
-+ case ZEND_OVERLOADED_FUNCTION:
-+ efp->op_array = sfp->op_array;
-+ break;
-+ case ZEND_USER_FUNCTION:
-+ case ZEND_EVAL_CODE:
-+ apc_copy_op_array(&efp->op_array, &sfp->op_array, &ctxt TSRMLS_CC);
-+ break;
-+ default:
-+ assert(0);
-+ }
-+#ifdef ZEND_ENGINE_2
-+ efp->common.prototype = NULL;
-+ efp->common.fn_flags = sfp->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
-+#endif
-+ apc_swizzle_ptr(bd, &ll, &ep->val.file.functions[fcount].name);
-+ apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.functions[fcount].function);
-+ apc_swizzle_op_array(bd, &ll, &efp->op_array TSRMLS_CC);
-+ }
-+
-+
-+ for(ep->num_classes=0; sp->value->data.file.classes[ep->num_classes].class_entry != NULL;) { ep->num_classes++; }
-+ ep->val.file.classes = apc_bd_alloc(sizeof(apc_class_t) * ep->num_classes TSRMLS_CC);
-+ for(fcount=0; fcount < ep->num_classes; fcount++) {
-+ ep->val.file.classes[fcount].name = apc_xmemcpy(sp->value->data.file.classes[fcount].name, sp->value->data.file.classes[fcount].name_len + 1, apc_bd_alloc TSRMLS_CC);
-+ ep->val.file.classes[fcount].name_len = sp->value->data.file.classes[fcount].name_len;
-+ ep->val.file.classes[fcount].class_entry = apc_copy_class_entry(NULL, sp->value->data.file.classes[fcount].class_entry, &ctxt TSRMLS_CC);
-+ ep->val.file.classes[fcount].parent_name = apc_xstrdup(sp->value->data.file.classes[fcount].parent_name, apc_bd_alloc TSRMLS_CC);
-+
-+ apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].name);
-+ apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].parent_name);
-+ apc_swizzle_class_entry(bd, &ll, ep->val.file.classes[fcount].class_entry TSRMLS_CC);
-+ apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].class_entry);
-+ }
-+
-+ apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.file.filename);
-+ apc_swizzle_op_array(bd, &ll, bd->entries[count].val.file.op_array TSRMLS_CC);
-+ apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.file.op_array);
-+ apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.functions);
-+ apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.classes);
-+
-+ count++;
-+ } else {
-+ /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load */
-+ }
-+ }
-+ }
-+ }
-+
-+ /* append swizzle pointer list to bd */
-+ bd = apc_swizzle_bd(bd, &ll TSRMLS_CC);
-+ zend_llist_destroy(&ll);
-+ zend_hash_destroy(&APCG(apc_bd_alloc_list));
-+
-+ if(files) {
-+ zend_hash_destroy(files);
-+ efree(files);
-+ }
-+ if(user_vars) {
-+ zend_hash_destroy(user_vars);
-+ efree(user_vars);
-+ }
-+
-+ efree(pool_ptr);
-+
-+ return bd;
-+} /* }}} */
-+
-+
-+/* {{{ apc_bin_load */
-+int apc_bin_load(apc_bd_t *bd, int flags TSRMLS_DC) {
-+
-+ apc_bd_entry_t *ep;
-+ uint i, i2;
-+ int ret;
-+ time_t t;
-+ zend_op_array *alloc_op_array = NULL;
-+ apc_function_t *alloc_functions = NULL;
-+ apc_class_t *alloc_classes = NULL;
-+ apc_cache_entry_t *cache_entry;
-+ apc_cache_key_t cache_key;
-+ apc_context_t ctxt;
-+
-+ if (bd->swizzled) {
-+ if(apc_unswizzle_bd(bd, flags TSRMLS_CC) < 0) {
-+ return -1;
-+ }
-+ }
-+
-+ t = apc_time();
-+
-+ for(i = 0; i < bd->num_entries; i++) {
-+ ctxt.pool = apc_pool_create(APC_SMALL_POOL, apc_sma_malloc, apc_sma_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ if (!ctxt.pool) { /* TODO need to cleanup previous pools */
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ goto failure;
-+ }
-+ ep = &bd->entries[i];
-+ switch (ep->type) {
-+ case APC_CACHE_KEY_FILE:
-+ /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load (or something else perhaps?) */
-+ break;
-+ case APC_CACHE_KEY_FPFILE:
-+ ctxt.copy = APC_COPY_IN_OPCODE;
-+
-+ HANDLE_BLOCK_INTERRUPTIONS();
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ if(APCG(write_lock)) {
-+ if(!apc_cache_write_lock(apc_cache TSRMLS_CC)) {
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+ return -1;
-+ }
-+ }
-+#endif
-+ if(! (alloc_op_array = apc_copy_op_array(NULL, ep->val.file.op_array, &ctxt TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ apc_bin_fixup_op_array(alloc_op_array);
-+
-+ if(! (alloc_functions = apc_sma_malloc(sizeof(apc_function_t) * (ep->num_functions + 1) TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ for(i2=0; i2 < ep->num_functions; i2++) {
-+ if(! (alloc_functions[i2].name = apc_xmemcpy(ep->val.file.functions[i2].name, ep->val.file.functions[i2].name_len + 1, apc_sma_malloc TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ alloc_functions[i2].name_len = ep->val.file.functions[i2].name_len;
-+ if(! (alloc_functions[i2].function = apc_sma_malloc(sizeof(zend_function) TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ switch(ep->val.file.functions[i2].function->type) {
-+ case ZEND_INTERNAL_FUNCTION:
-+ case ZEND_OVERLOADED_FUNCTION:
-+ alloc_functions[i2].function->op_array = ep->val.file.functions[i2].function->op_array;
-+ break;
-+ case ZEND_USER_FUNCTION:
-+ case ZEND_EVAL_CODE:
-+ if (!apc_copy_op_array(&alloc_functions[i2].function->op_array, &ep->val.file.functions[i2].function->op_array, &ctxt TSRMLS_CC)) {
-+ goto failure;
-+ }
-+ apc_bin_fixup_op_array(&alloc_functions[i2].function->op_array);
-+ break;
-+ default:
-+ assert(0);
-+ }
-+#ifdef ZEND_ENGINE_2
-+ alloc_functions[i2].function->common.prototype=NULL;
-+ alloc_functions[i2].function->common.fn_flags=ep->val.file.functions[i2].function->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
-+#endif
-+ }
-+ alloc_functions[i2].name = NULL;
-+ alloc_functions[i2].function = NULL;
-+
-+ if(! (alloc_classes = apc_sma_malloc(sizeof(apc_class_t) * (ep->num_classes + 1) TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ for(i2=0; i2 < ep->num_classes; i2++) {
-+ if(! (alloc_classes[i2].name = apc_xmemcpy(ep->val.file.classes[i2].name, ep->val.file.classes[i2].name_len+1, apc_sma_malloc TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ alloc_classes[i2].name_len = ep->val.file.classes[i2].name_len;
-+ if(! (alloc_classes[i2].class_entry = apc_copy_class_entry(NULL, ep->val.file.classes[i2].class_entry, &ctxt TSRMLS_CC))) {
-+ goto failure;
-+ }
-+ apc_bin_fixup_class_entry(alloc_classes[i2].class_entry);
-+ if(! (alloc_classes[i2].parent_name = apc_xstrdup(ep->val.file.classes[i2].parent_name, apc_sma_malloc TSRMLS_CC))) {
-+ if(ep->val.file.classes[i2].parent_name != NULL) {
-+ goto failure;
-+ }
-+ }
-+ }
-+ alloc_classes[i2].name = NULL;
-+ alloc_classes[i2].class_entry = NULL;
-+
-+ if(!(cache_entry = apc_cache_make_file_entry(ep->val.file.filename, alloc_op_array, alloc_functions, alloc_classes, &ctxt TSRMLS_CC))) {
-+ goto failure;
-+ }
-+
-+ if (!apc_cache_make_file_key(&cache_key, ep->val.file.filename, PG(include_path), t TSRMLS_CC)) {
-+ goto failure;
-+ }
-+
-+ if ((ret = apc_cache_insert(apc_cache, cache_key, cache_entry, &ctxt, t TSRMLS_CC)) != 1) {
-+ if(ret==-1) {
-+ goto failure;
-+ }
-+ }
-+
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ if(APCG(write_lock)) {
-+ apc_cache_write_unlock(apc_cache TSRMLS_CC);
-+ }
-+#endif
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+
-+ break;
-+ case APC_CACHE_KEY_USER:
-+ ctxt.copy = APC_COPY_IN_USER;
-+ _apc_store(ep->val.user.info, ep->val.user.info_len, ep->val.user.val, ep->val.user.ttl, 0 TSRMLS_CC);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ return 0;
-+
-+failure:
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ apc_warning("Unable to allocate memory for apc binary load/dump functionality." TSRMLS_CC);
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ if(APCG(write_lock)) {
-+ apc_cache_write_unlock(apc_cache TSRMLS_CC);
-+ }
-+#endif
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+ return -1;
-+} /* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_bin.h b/ext/apc/apc_bin.h
---- a/ext/apc/apc_bin.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_bin.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,63 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_bin.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_BINDUMP_H
-+#define APC_BINDUMP_H
-+
-+#include "apc.h"
-+#include "apc_php.h"
-+#include "ext/standard/basic_functions.h"
-+
-+/* APC binload flags */
-+#define APC_BIN_VERIFY_MD5 1 << 0
-+#define APC_BIN_VERIFY_CRC32 1 << 1
-+
-+typedef struct _apc_bd_entry_t {
-+ unsigned char type;
-+ uint num_functions;
-+ uint num_classes;
-+ apc_cache_entry_value_t val;
-+} apc_bd_entry_t;
-+
-+typedef struct _apc_bd_t {
-+ unsigned int size;
-+ int swizzled;
-+ unsigned char md5[16];
-+ php_uint32 crc;
-+ unsigned int num_entries;
-+ apc_bd_entry_t *entries;
-+ int num_swizzled_ptrs;
-+ void ***swizzled_ptrs;
-+} apc_bd_t;
-+
-+apc_bd_t* apc_bin_dump(HashTable *files, HashTable *user_vars TSRMLS_DC);
-+int apc_bin_load(apc_bd_t *bd, int flags TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc.c b/ext/apc/apc.c
---- a/ext/apc/apc.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,670 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc.c 326710 2012-07-19 20:51:04Z rasmus $ */
-+
-+#include "apc.h"
-+#include "apc_zend.h"
-+#include "apc_cache.h"
-+#include "apc_globals.h"
-+#include "php.h"
-+
-+#if HAVE_PCRE || HAVE_BUNDLED_PCRE
-+/* Deal with problem present until php-5.2.2 where php_pcre.h was not installed correctly */
-+# if !HAVE_BUNDLED_PCRE && PHP_MAJOR_VERSION == 5 && (PHP_MINOR_VERSION < 2 || (PHP_MINOR_VERSION == 2 && PHP_RELEASE_VERSION < 2))
-+# include "apc_php_pcre.h"
-+# else
-+# include "ext/pcre/php_pcre.h"
-+# endif
-+# include "ext/standard/php_smart_str.h"
-+#endif
-+
-+#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))
-+
-+/* {{{ memory allocation wrappers */
-+
-+void* apc_emalloc(size_t n TSRMLS_DC)
-+{
-+ void* p = malloc(n);
-+ if (p == NULL) {
-+ apc_error("apc_emalloc: malloc failed to allocate %u bytes:" TSRMLS_CC, n);
-+ return NULL;
-+ }
-+ return p;
-+}
-+
-+void* apc_erealloc(void* p, size_t n TSRMLS_DC)
-+{
-+ void *new;
-+ new = realloc(p, n);
-+ if (new == NULL) {
-+ apc_error("apc_erealloc: realloc failed to allocate %u bytes:" TSRMLS_CC, n);
-+ return NULL;
-+ }
-+ return new;
-+}
-+
-+void apc_efree(void* p TSRMLS_DC)
-+{
-+ if (p == NULL) {
-+ apc_error("apc_efree: attempt to free null pointer" TSRMLS_CC);
-+ return;
-+ }
-+ free(p);
-+}
-+
-+char* APC_ALLOC apc_estrdup(const char* s TSRMLS_DC)
-+{
-+ int len;
-+ char* dup;
-+
-+ if (s == NULL) {
-+ return NULL;
-+ }
-+ len = strlen(s);
-+ dup = (char*) malloc(len+1);
-+ if (dup == NULL) {
-+ apc_error("apc_estrdup: malloc failed to allocate %u bytes:" TSRMLS_CC, len+1);
-+ return NULL;
-+ }
-+ memcpy(dup, s, len);
-+ dup[len] = '\0';
-+ return dup;
-+}
-+
-+void* APC_ALLOC apc_xstrdup(const char* s, apc_malloc_t f TSRMLS_DC)
-+{
-+ return s != NULL ? apc_xmemcpy(s, strlen(s)+1, f TSRMLS_CC) : NULL;
-+}
-+
-+void* APC_ALLOC apc_xmemcpy(const void* p, size_t n, apc_malloc_t f TSRMLS_DC)
-+{
-+ void* q;
-+
-+ if (p != NULL && (q = f(n TSRMLS_CC)) != NULL) {
-+ memcpy(q, p, n);
-+ return q;
-+ }
-+ return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ console display functions */
-+#ifdef ZTS
-+# define APC_PRINT_FUNCTION_PARAMETER TSRMLS_C
-+#else
-+# define APC_PRINT_FUNCTION_PARAMETER format
-+#endif
-+
-+#define APC_PRINT_FUNCTION(name, verbosity) \
-+ void apc_##name(const char *format TSRMLS_DC, ...) \
-+ { \
-+ va_list args; \
-+ \
-+ va_start(args, APC_PRINT_FUNCTION_PARAMETER); \
-+ php_verror(NULL, "", verbosity, format, args TSRMLS_CC); \
-+ va_end(args); \
-+ }
-+
-+APC_PRINT_FUNCTION(error, E_ERROR)
-+APC_PRINT_FUNCTION(warning, E_WARNING)
-+APC_PRINT_FUNCTION(notice, E_NOTICE)
-+
-+#ifdef __DEBUG_APC__
-+APC_PRINT_FUNCTION(debug, E_NOTICE)
-+#else
-+void apc_debug(const char *format TSRMLS_DC, ...) {}
-+#endif
-+/* }}} */
-+
-+/* {{{ string and text manipulation */
-+
-+char* apc_append(const char* s, const char* t TSRMLS_DC)
-+{
-+ int slen;
-+ int tlen;
-+ char* p;
-+
-+ slen = strlen(s);
-+ tlen = strlen(t);
-+
-+ p = (char*) apc_emalloc((slen + tlen + 1) * sizeof(char) TSRMLS_CC);
-+ memcpy(p, s, slen);
-+ memcpy(p + slen, t, tlen + 1);
-+
-+ return p;
-+}
-+
-+char* apc_substr(const char* s, int start, int length TSRMLS_DC)
-+{
-+ char* substr;
-+ int src_len = strlen(s);
-+
-+ /* bring start into range */
-+ if (start < 0) {
-+ start = 0;
-+ }
-+ else if (start >= src_len) {
-+ start = src_len - 1;
-+ }
-+
-+ /* bring length into range */
-+ if (length < 0 || src_len - start < length) {
-+ length = src_len - start;
-+ }
-+
-+ /* create the substring */
-+ substr = apc_xmemcpy(s + start, length + 1, apc_emalloc TSRMLS_CC);
-+ substr[length] = '\0';
-+ return substr;
-+}
-+
-+char** apc_tokenize(const char* s, char delim TSRMLS_DC)
-+{
-+ char** tokens; /* array of tokens, NULL terminated */
-+ int size; /* size of tokens array */
-+ int n; /* index of next token in tokens array */
-+ int cur; /* current position in input string */
-+ int end; /* final legal position in input string */
-+ int next; /* position of next delimiter in input */
-+
-+ if (!s) {
-+ return NULL;
-+ }
-+
-+ size = 2;
-+ n = 0;
-+ cur = 0;
-+ end = strlen(s) - 1;
-+
-+ tokens = (char**) apc_emalloc(size * sizeof(char*) TSRMLS_CC);
-+ tokens[n] = NULL;
-+
-+ while (cur <= end) {
-+ /* search for the next delimiter */
-+ char* p = strchr(s + cur, delim);
-+ next = p ? p-s : end+1;
-+
-+ /* resize token array if necessary */
-+ if (n == size-1) {
-+ size *= 2;
-+ tokens = (char**) apc_erealloc(tokens, size * sizeof(char*) TSRMLS_CC);
-+ }
-+
-+ /* save the current token */
-+ tokens[n] = apc_substr(s, cur, next-cur TSRMLS_CC);
-+
-+ tokens[++n] = NULL;
-+ cur = next + 1;
-+ }
-+
-+ return tokens;
-+}
-+
-+/* }}} */
-+
-+
-+/* {{{ apc_win32_restat */
-+#ifdef PHP_WIN32
-+static int apc_restat(apc_fileinfo_t *fileinfo TSRMLS_DC)
-+{
-+ HANDLE hFile;
-+ BY_HANDLE_FILE_INFORMATION hInfo;
-+
-+ hFile = CreateFile(fileinfo->fullpath, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-+
-+ if (!hFile) {
-+ apc_debug("Cannot create a file HANDLE for %s\n" TSRMLS_CC, fileinfo->fullpath);
-+ return -1;
-+ }
-+
-+ if (!GetFileInformationByHandle(hFile, &hInfo)) {
-+ apc_debug("Cannot get file information from handle\n" TSRMLS_CC);
-+ CloseHandle(hFile);
-+ return -1;
-+ }
-+
-+ CloseHandle(hFile);
-+
-+ fileinfo->st_buf.sb.st_dev = hInfo.dwVolumeSerialNumber;
-+ fileinfo->st_buf.sb.st_ino = (((apc_ino_t)(hInfo.nFileIndexHigh) << 32) | (apc_ino_t) hInfo.nFileIndexLow);
-+
-+ return 0;
-+}
-+#else
-+static int apc_restat(apc_fileinfo_t *fileinfo TSRMLS_DC)
-+{
-+ return 0;
-+}
-+#endif
-+/* }}} */
-+
-+/* {{{ apc_search_paths */
-+/* similar to php_stream_stat_path */
-+#define APC_URL_STAT(wrapper, filename, pstatbuf) \
-+ ((wrapper)->wops->url_stat((wrapper), (filename), PHP_STREAM_URL_STAT_QUIET, (pstatbuf), NULL TSRMLS_CC))
-+
-+/* copy out to path_buf if path_for_open isn't the same as filename */
-+#define COPY_IF_CHANGED(p) \
-+ (char*) (((p) == filename) ? filename : \
-+ (strlcpy((char*)fileinfo->path_buf, (p), sizeof(fileinfo->path_buf))) \
-+ ? (fileinfo->path_buf) : NULL)
-+
-+/* len checks can be skipped here because filename is NUL terminated */
-+#define IS_RELATIVE_PATH(filename, len) \
-+ ((filename) && (filename[0] == '.' && \
-+ (IS_SLASH(filename[1]) || \
-+ (filename[1] == '.' && \
-+ IS_SLASH(filename[2])))))
-+
-+/* {{{ stupid stringifcation */
-+#if DEFAULT_SLASH == '/'
-+ #define DEFAULT_SLASH_STRING "/"
-+#elif DEFAULT_SLASH == '\\'
-+ #define DEFAULT_SLASH_STRING "\\"
-+#else
-+ #error "Unknown value for DEFAULT_SLASH"
-+#endif
-+/* }}} */
-+
-+int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo TSRMLS_DC)
-+{
-+ char** paths = NULL;
-+ char *exec_fname;
-+ int exec_fname_length;
-+ int found = 0;
-+ int i;
-+ php_stream_wrapper *wrapper = NULL;
-+ char *path_for_open = NULL;
-+
-+ assert(filename && fileinfo);
-+
-+
-+ wrapper = php_stream_locate_url_wrapper(filename, &path_for_open, 0 TSRMLS_CC);
-+
-+ if(!wrapper || !wrapper->wops || !wrapper->wops->url_stat) {
-+ return -1;
-+ }
-+
-+ if(wrapper != &php_plain_files_wrapper) {
-+ if(APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = COPY_IF_CHANGED(path_for_open);
-+ return apc_restat(fileinfo TSRMLS_CC);
-+ }
-+ return -1; /* cannot stat */
-+ }
-+
-+ if (IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) &&
-+ APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = COPY_IF_CHANGED(path_for_open);
-+ return apc_restat(fileinfo TSRMLS_CC);
-+ }
-+
-+ if (!IS_RELATIVE_PATH(path_for_open, strlen(path_for_open))) {
-+ paths = apc_tokenize(path, DEFAULT_DIR_SEPARATOR TSRMLS_CC);
-+ if (!paths)
-+ return -1;
-+
-+ /* for each directory in paths, look for filename inside */
-+ for (i = 0; paths[i]; i++) {
-+ snprintf(fileinfo->path_buf, sizeof(fileinfo->path_buf), "%s%c%s", paths[i], DEFAULT_SLASH, path_for_open);
-+ if (APC_URL_STAT(wrapper, fileinfo->path_buf, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = (char*) fileinfo->path_buf;
-+ found = 1;
-+ break;
-+ }
-+ }
-+ /* in cli mode PHP explicitly checks the cwd, so we should as well */
-+ if(APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) {
-+ snprintf(fileinfo->path_buf, sizeof(fileinfo->path_buf), ".%c%s", DEFAULT_SLASH, path_for_open);
-+ if (APC_URL_STAT(wrapper, fileinfo->path_buf, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = (char*) fileinfo->path_buf;
-+ found = 1;
-+ }
-+ }
-+ } else {
-+ /* read cwd and try to fake up fullpath */
-+ fileinfo->path_buf[0] = '\0';
-+ if(VCWD_GETCWD(fileinfo->path_buf, sizeof(fileinfo->path_buf))) {
-+ strlcat(fileinfo->path_buf, DEFAULT_SLASH_STRING, sizeof(fileinfo->path_buf));
-+ strlcat(fileinfo->path_buf, path_for_open, sizeof(fileinfo->path_buf));
-+ if (APC_URL_STAT(wrapper, fileinfo->path_buf, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = (char*) fileinfo->path_buf;
-+ return apc_restat(fileinfo TSRMLS_CC);
-+ }
-+ }
-+ }
-+
-+ /* check in path of the calling scripts' current working directory */
-+ /* modified from main/streams/plain_wrapper.c */
-+ if(!found && zend_is_executing(TSRMLS_C)) {
-+ exec_fname = zend_get_executed_filename(TSRMLS_C);
-+ exec_fname_length = strlen(exec_fname);
-+ while((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
-+ if((exec_fname && exec_fname[0] != '[') && exec_fname_length > 0) {
-+ /* not: [no active file] or no path */
-+ memcpy(fileinfo->path_buf, exec_fname, exec_fname_length);
-+ fileinfo->path_buf[exec_fname_length] = DEFAULT_SLASH;
-+ strlcpy(fileinfo->path_buf +exec_fname_length +1, path_for_open,sizeof(fileinfo->path_buf)-exec_fname_length-1);
-+ /* apc_warning("filename: %s, exec_fname: %s, fileinfo->path_buf: %s" TSRMLS_CC, path_for_open, exec_fname, fileinfo->path_buf); */
-+ if (APC_URL_STAT(wrapper, fileinfo->path_buf, &fileinfo->st_buf) == 0) {
-+ fileinfo->fullpath = (char*) fileinfo->path_buf;
-+ found = 1;
-+ }
-+ }
-+ }
-+
-+ if(paths) {
-+ /* free the value returned by apc_tokenize */
-+ for (i = 0; paths[i]; i++) {
-+ apc_efree(paths[i] TSRMLS_CC);
-+ }
-+ apc_efree(paths TSRMLS_CC);
-+ }
-+
-+ return found ? apc_restat(fileinfo TSRMLS_CC) : -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ regular expression wrapper functions */
-+
-+#if (HAVE_PCRE || HAVE_BUNDLED_PCRE)
-+typedef struct {
-+ pcre *preg;
-+ pcre *nreg;
-+} apc_regex;
-+
-+#define APC_ADD_PATTERN(match, pat) do {\
-+ if(match.len > 1) {\
-+ smart_str_appendc(&match, '|');\
-+ }\
-+ smart_str_appendc(&match, '(');\
-+ while(*pat) {\
-+ if(*pat == '/') smart_str_appendc(&match, '\\');\
-+ \
-+ smart_str_appendc(&match, *(pat++));\
-+ }\
-+ smart_str_appendc(&match, ')');\
-+} while(0)
-+
-+#define APC_COMPILE_PATTERN(re, match) do {\
-+ if(match.len > 2) { /* more than just "//" */\
-+ if (((re) = pcre_get_compiled_regex(match.c, NULL, NULL TSRMLS_CC)) == NULL) {\
-+ apc_warning("apc_regex_compile_array: invalid expression '%s'" TSRMLS_CC, match.c); \
-+ smart_str_free(&match);\
-+ return NULL;\
-+ }\
-+ } else { \
-+ (re) = NULL;\
-+ }\
-+} while(0)
-+
-+void* apc_regex_compile_array(char* patterns[] TSRMLS_DC)
-+{
-+ apc_regex* regs;
-+ int npat;
-+ smart_str pmatch = {0,};
-+ smart_str nmatch = {0,};
-+ char* pattern;
-+
-+ if (!patterns)
-+ return NULL;
-+
-+ regs = (apc_regex*) apc_emalloc(sizeof(apc_regex) TSRMLS_CC);
-+
-+ smart_str_appendc(&pmatch, '/');
-+ smart_str_appendc(&nmatch, '/');
-+
-+ for (npat = 0; patterns[npat] != NULL; npat++) {
-+ pattern = patterns[npat];
-+ if(pattern[0] == '+') {
-+ pattern += sizeof(char);
-+ APC_ADD_PATTERN(pmatch, pattern);
-+ } else {
-+ if(pattern[0] == '-') pattern += sizeof(char);
-+ APC_ADD_PATTERN(nmatch, pattern);
-+ }
-+ }
-+ smart_str_appendc(&pmatch, '/');
-+ smart_str_appendc(&nmatch, '/');
-+
-+ smart_str_0(&nmatch);
-+ smart_str_0(&pmatch);
-+
-+ APC_COMPILE_PATTERN(regs->preg, pmatch);
-+ APC_COMPILE_PATTERN(regs->nreg, nmatch);
-+
-+ smart_str_free(&pmatch);
-+ smart_str_free(&nmatch);
-+
-+ return (void*) regs;
-+}
-+
-+void apc_regex_destroy_array(void* p TSRMLS_DC)
-+{
-+ if (p != NULL) {
-+ apc_regex* regs = (apc_regex*) p;
-+ apc_efree(regs TSRMLS_CC);
-+ }
-+}
-+
-+#define APC_MATCH_PATTERN(re, input, output) do {\
-+ if (re && pcre_exec(re, NULL, (input), strlen(input), 0, 0, NULL, 0) >= 0) {\
-+ return (output);\
-+ }\
-+} while(0)
-+
-+
-+int apc_regex_match_array(void* p, const char* input)
-+{
-+ apc_regex* regs;
-+
-+ if (!p)
-+ return 0;
-+
-+ regs = (apc_regex*) p;
-+
-+ APC_MATCH_PATTERN(regs->preg, input, APC_POSITIVE_MATCH);
-+ APC_MATCH_PATTERN(regs->nreg, input, APC_NEGATIVE_MATCH);
-+
-+ return 0;
-+}
-+#else /* no pcre */
-+void* apc_regex_compile_array(char* patterns[] TSRMLS_DC)
-+{
-+ if(patterns && patterns[0] != NULL) {
-+ apc_warning("pcre missing, disabling filters" TSRMLS_CC);
-+ }
-+ return NULL;
-+}
-+void apc_regex_destroy_array(void* p)
-+{
-+ /* nothing */
-+}
-+int apc_regex_match_array(void* p, const char* input)
-+{
-+ return 0;
-+}
-+#endif
-+/* }}} */
-+
-+/* {{{ crc32 implementation */
-+
-+/* this table was generated by crc32gen() */
-+static unsigned int crc32tab[] = {
-+ /* 0 */ 0x00000000, 0x3b83984b, 0x77073096, 0x4c84a8dd,
-+ /* 4 */ 0xee0e612c, 0xd58df967, 0x990951ba, 0xa28ac9f1,
-+ /* 8 */ 0x076dc419, 0x3cee5c52, 0x706af48f, 0x4be96cc4,
-+ /* 12 */ 0xe963a535, 0xd2e03d7e, 0x9e6495a3, 0xa5e70de8,
-+ /* 16 */ 0x0edb8832, 0x35581079, 0x79dcb8a4, 0x425f20ef,
-+ /* 20 */ 0xe0d5e91e, 0xdb567155, 0x97d2d988, 0xac5141c3,
-+ /* 24 */ 0x09b64c2b, 0x3235d460, 0x7eb17cbd, 0x4532e4f6,
-+ /* 28 */ 0xe7b82d07, 0xdc3bb54c, 0x90bf1d91, 0xab3c85da,
-+ /* 32 */ 0x1db71064, 0x2634882f, 0x6ab020f2, 0x5133b8b9,
-+ /* 36 */ 0xf3b97148, 0xc83ae903, 0x84be41de, 0xbf3dd995,
-+ /* 40 */ 0x1adad47d, 0x21594c36, 0x6ddde4eb, 0x565e7ca0,
-+ /* 44 */ 0xf4d4b551, 0xcf572d1a, 0x83d385c7, 0xb8501d8c,
-+ /* 48 */ 0x136c9856, 0x28ef001d, 0x646ba8c0, 0x5fe8308b,
-+ /* 52 */ 0xfd62f97a, 0xc6e16131, 0x8a65c9ec, 0xb1e651a7,
-+ /* 56 */ 0x14015c4f, 0x2f82c404, 0x63066cd9, 0x5885f492,
-+ /* 60 */ 0xfa0f3d63, 0xc18ca528, 0x8d080df5, 0xb68b95be,
-+ /* 64 */ 0x3b6e20c8, 0x00edb883, 0x4c69105e, 0x77ea8815,
-+ /* 68 */ 0xd56041e4, 0xeee3d9af, 0xa2677172, 0x99e4e939,
-+ /* 72 */ 0x3c03e4d1, 0x07807c9a, 0x4b04d447, 0x70874c0c,
-+ /* 76 */ 0xd20d85fd, 0xe98e1db6, 0xa50ab56b, 0x9e892d20,
-+ /* 80 */ 0x35b5a8fa, 0x0e3630b1, 0x42b2986c, 0x79310027,
-+ /* 84 */ 0xdbbbc9d6, 0xe038519d, 0xacbcf940, 0x973f610b,
-+ /* 88 */ 0x32d86ce3, 0x095bf4a8, 0x45df5c75, 0x7e5cc43e,
-+ /* 92 */ 0xdcd60dcf, 0xe7559584, 0xabd13d59, 0x9052a512,
-+ /* 96 */ 0x26d930ac, 0x1d5aa8e7, 0x51de003a, 0x6a5d9871,
-+ /* 100 */ 0xc8d75180, 0xf354c9cb, 0xbfd06116, 0x8453f95d,
-+ /* 104 */ 0x21b4f4b5, 0x1a376cfe, 0x56b3c423, 0x6d305c68,
-+ /* 108 */ 0xcfba9599, 0xf4390dd2, 0xb8bda50f, 0x833e3d44,
-+ /* 112 */ 0x2802b89e, 0x138120d5, 0x5f058808, 0x64861043,
-+ /* 116 */ 0xc60cd9b2, 0xfd8f41f9, 0xb10be924, 0x8a88716f,
-+ /* 120 */ 0x2f6f7c87, 0x14ece4cc, 0x58684c11, 0x63ebd45a,
-+ /* 124 */ 0xc1611dab, 0xfae285e0, 0xb6662d3d, 0x8de5b576,
-+ /* 128 */ 0x76dc4190, 0x4d5fd9db, 0x01db7106, 0x3a58e94d,
-+ /* 132 */ 0x98d220bc, 0xa351b8f7, 0xefd5102a, 0xd4568861,
-+ /* 136 */ 0x71b18589, 0x4a321dc2, 0x06b6b51f, 0x3d352d54,
-+ /* 140 */ 0x9fbfe4a5, 0xa43c7cee, 0xe8b8d433, 0xd33b4c78,
-+ /* 144 */ 0x7807c9a2, 0x438451e9, 0x0f00f934, 0x3483617f,
-+ /* 148 */ 0x9609a88e, 0xad8a30c5, 0xe10e9818, 0xda8d0053,
-+ /* 152 */ 0x7f6a0dbb, 0x44e995f0, 0x086d3d2d, 0x33eea566,
-+ /* 156 */ 0x91646c97, 0xaae7f4dc, 0xe6635c01, 0xdde0c44a,
-+ /* 160 */ 0x6b6b51f4, 0x50e8c9bf, 0x1c6c6162, 0x27eff929,
-+ /* 164 */ 0x856530d8, 0xbee6a893, 0xf262004e, 0xc9e19805,
-+ /* 168 */ 0x6c0695ed, 0x57850da6, 0x1b01a57b, 0x20823d30,
-+ /* 172 */ 0x8208f4c1, 0xb98b6c8a, 0xf50fc457, 0xce8c5c1c,
-+ /* 176 */ 0x65b0d9c6, 0x5e33418d, 0x12b7e950, 0x2934711b,
-+ /* 180 */ 0x8bbeb8ea, 0xb03d20a1, 0xfcb9887c, 0xc73a1037,
-+ /* 184 */ 0x62dd1ddf, 0x595e8594, 0x15da2d49, 0x2e59b502,
-+ /* 188 */ 0x8cd37cf3, 0xb750e4b8, 0xfbd44c65, 0xc057d42e,
-+ /* 192 */ 0x4db26158, 0x7631f913, 0x3ab551ce, 0x0136c985,
-+ /* 196 */ 0xa3bc0074, 0x983f983f, 0xd4bb30e2, 0xef38a8a9,
-+ /* 200 */ 0x4adfa541, 0x715c3d0a, 0x3dd895d7, 0x065b0d9c,
-+ /* 204 */ 0xa4d1c46d, 0x9f525c26, 0xd3d6f4fb, 0xe8556cb0,
-+ /* 208 */ 0x4369e96a, 0x78ea7121, 0x346ed9fc, 0x0fed41b7,
-+ /* 212 */ 0xad678846, 0x96e4100d, 0xda60b8d0, 0xe1e3209b,
-+ /* 216 */ 0x44042d73, 0x7f87b538, 0x33031de5, 0x088085ae,
-+ /* 220 */ 0xaa0a4c5f, 0x9189d414, 0xdd0d7cc9, 0xe68ee482,
-+ /* 224 */ 0x5005713c, 0x6b86e977, 0x270241aa, 0x1c81d9e1,
-+ /* 228 */ 0xbe0b1010, 0x8588885b, 0xc90c2086, 0xf28fb8cd,
-+ /* 232 */ 0x5768b525, 0x6ceb2d6e, 0x206f85b3, 0x1bec1df8,
-+ /* 236 */ 0xb966d409, 0x82e54c42, 0xce61e49f, 0xf5e27cd4,
-+ /* 240 */ 0x5edef90e, 0x655d6145, 0x29d9c998, 0x125a51d3,
-+ /* 244 */ 0xb0d09822, 0x8b530069, 0xc7d7a8b4, 0xfc5430ff,
-+ /* 248 */ 0x59b33d17, 0x6230a55c, 0x2eb40d81, 0x153795ca,
-+ /* 252 */ 0xb7bd5c3b, 0x8c3ec470, 0xc0ba6cad, 0xfb39f4e6,
-+};
-+
-+unsigned int apc_crc32(const char* buf, int len)
-+{
-+ int i;
-+ int k;
-+ unsigned int crc;
-+
-+ /* preconditioning */
-+ crc = 0xFFFFFFFF;
-+
-+ for (i = 0; i < len; i++) {
-+ k = (crc ^ buf[i]) & 0x000000FF;
-+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[k];
-+ }
-+
-+ /* postconditioning */
-+ return ~crc;
-+}
-+
-+/* crc32gen: generate the nth (0..255) crc32 table value */
-+#if 0
-+static unsigned long crc32gen(int n)
-+{
-+ int i;
-+ unsigned long crc;
-+
-+ crc = n;
-+ for (i = 8; i >= 0; i--) {
-+ if (crc & 1) {
-+ crc = (crc >> 1) ^ 0xEDB88320;
-+ }
-+ else {
-+ crc >>= 1;
-+ }
-+ }
-+ return crc;
-+}
-+#endif
-+
-+/* }}} */
-+
-+
-+/* {{{ apc_flip_hash() */
-+HashTable* apc_flip_hash(HashTable *hash) {
-+ zval **entry, *data;
-+ HashTable *new_hash;
-+ HashPosition pos;
-+
-+ if(hash == NULL) return hash;
-+
-+ MAKE_STD_ZVAL(data);
-+ ZVAL_LONG(data, 1);
-+
-+ new_hash = emalloc(sizeof(HashTable));
-+ zend_hash_init(new_hash, hash->nTableSize, NULL, ZVAL_PTR_DTOR, 0);
-+
-+ zend_hash_internal_pointer_reset_ex(hash, &pos);
-+ while (zend_hash_get_current_data_ex(hash, (void **)&entry, &pos) == SUCCESS) {
-+ if(Z_TYPE_PP(entry) == IS_STRING) {
-+ zend_hash_update(new_hash, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) +1, &data, sizeof(data), NULL);
-+ } else {
-+ zend_hash_index_update(new_hash, Z_LVAL_PP(entry), &data, sizeof(data), NULL);
-+ }
-+ Z_ADDREF_P(data);
-+ zend_hash_move_forward_ex(hash, &pos);
-+ }
-+ zval_ptr_dtor(&data);
-+
-+ return new_hash;
-+}
-+/* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_cache.c b/ext/apc/apc_cache.c
---- a/ext/apc/apc_cache.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_cache.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,1383 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_cache.c 325482 2012-05-01 00:09:36Z rasmus $ */
-+
-+#include "apc_cache.h"
-+#include "apc_zend.h"
-+#include "apc_sma.h"
-+#include "apc_globals.h"
-+#include "SAPI.h"
-+#include "TSRM.h"
-+#include "ext/standard/md5.h"
-+
-+/* TODO: rehash when load factor exceeds threshold */
-+
-+#define CHECK(p) { if ((p) == NULL) return NULL; }
-+
-+/* {{{ key_equals */
-+#define key_equals(a, b) (a.inode==b.inode && a.device==b.device)
-+/* }}} */
-+
-+static void apc_cache_expunge(apc_cache_t* cache, size_t size TSRMLS_DC);
-+
-+/* {{{ hash */
-+static unsigned long hash(apc_cache_key_t key)
-+{
-+ return (unsigned long)(key.data.file.device + key.data.file.inode);
-+}
-+/* }}} */
-+
-+/* {{{ string_nhash_8 */
-+#define string_nhash_8(s,len) (unsigned long)(zend_inline_hash_func((s), len))
-+/* }}} */
-+
-+/* {{{ murmurhash */
-+#if 0
-+static inline unsigned long murmurhash(const char *skey, size_t keylen)
-+{
-+ const long m = 0x7fd652ad;
-+ const long r = 16;
-+ unsigned int h = 0xdeadbeef;
-+
-+ while(keylen >= 4)
-+ {
-+ h += *(unsigned int*)skey;
-+ h *= m;
-+ h ^= h >> r;
-+
-+ skey += 4;
-+ keylen -= 4;
-+ }
-+
-+ switch(keylen)
-+ {
-+ case 3:
-+ h += skey[2] << 16;
-+ case 2:
-+ h += skey[1] << 8;
-+ case 1:
-+ h += skey[0];
-+ h *= m;
-+ h ^= h >> r;
-+ };
-+
-+ h *= m;
-+ h ^= h >> 10;
-+ h *= m;
-+ h ^= h >> 17;
-+
-+ return h;
-+}
-+#endif
-+/* }}} */
-+
-+
-+/* {{{ make_prime */
-+static int const primes[] = {
-+ 257, /* 256 */
-+ 521, /* 512 */
-+ 1031, /* 1024 */
-+ 2053, /* 2048 */
-+ 3079, /* 3072 */
-+ 4099, /* 4096 */
-+ 5147, /* 5120 */
-+ 6151, /* 6144 */
-+ 7177, /* 7168 */
-+ 8209, /* 8192 */
-+ 9221, /* 9216 */
-+10243, /* 10240 */
-+11273, /* 11264 */
-+12289, /* 12288 */
-+13313, /* 13312 */
-+14341, /* 14336 */
-+15361, /* 15360 */
-+16411, /* 16384 */
-+17417, /* 17408 */
-+18433, /* 18432 */
-+19457, /* 19456 */
-+0 /* sentinel */
-+};
-+
-+static int make_prime(int n)
-+{
-+ int *k = (int*)primes;
-+ while(*k) {
-+ if((*k) > n) return *k;
-+ k++;
-+ }
-+ return *(k-1);
-+}
-+/* }}} */
-+
-+/* {{{ make_slot */
-+slot_t* make_slot(apc_cache_key_t *key, apc_cache_entry_t* value, slot_t* next, time_t t TSRMLS_DC)
-+{
-+ slot_t* p = apc_pool_alloc(value->pool, sizeof(slot_t));
-+
-+ if (!p) return NULL;
-+
-+ if(key->type == APC_CACHE_KEY_USER) {
-+ char *identifier = (char*) apc_pmemcpy(key->data.user.identifier, key->data.user.identifier_len, value->pool TSRMLS_CC);
-+ if (!identifier) {
-+ return NULL;
-+ }
-+ key->data.user.identifier = identifier;
-+ } else if(key->type == APC_CACHE_KEY_FPFILE) {
-+ char *fullpath = (char*) apc_pstrdup(key->data.fpfile.fullpath, value->pool TSRMLS_CC);
-+ if (!fullpath) {
-+ return NULL;
-+ }
-+ key->data.fpfile.fullpath = fullpath;
-+ }
-+ p->key = key[0];
-+ p->value = value;
-+ p->next = next;
-+ p->num_hits = 0;
-+ p->creation_time = t;
-+ p->access_time = t;
-+ p->deletion_time = 0;
-+ return p;
-+}
-+/* }}} */
-+
-+/* {{{ free_slot */
-+static void free_slot(slot_t* slot TSRMLS_DC)
-+{
-+ apc_pool_destroy(slot->value->pool TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ remove_slot */
-+static void remove_slot(apc_cache_t* cache, slot_t** slot TSRMLS_DC)
-+{
-+ slot_t* dead = *slot;
-+ *slot = (*slot)->next;
-+
-+ cache->header->mem_size -= dead->value->mem_size;
-+ CACHE_FAST_DEC(cache, cache->header->num_entries);
-+ if (dead->value->ref_count <= 0) {
-+ free_slot(dead TSRMLS_CC);
-+ }
-+ else {
-+ dead->next = cache->header->deleted_list;
-+ dead->deletion_time = time(0);
-+ cache->header->deleted_list = dead;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ process_pending_removals */
-+static void process_pending_removals(apc_cache_t* cache TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ time_t now;
-+
-+ /* This function scans the list of removed cache entries and deletes any
-+ * entry whose reference count is zero (indicating that it is no longer
-+ * being executed) or that has been on the pending list for more than
-+ * cache->gc_ttl seconds (we issue a warning in the latter case).
-+ */
-+
-+ if (!cache->header->deleted_list)
-+ return;
-+
-+ slot = &cache->header->deleted_list;
-+ now = time(0);
-+
-+ while (*slot != NULL) {
-+ int gc_sec = cache->gc_ttl ? (now - (*slot)->deletion_time) : 0;
-+
-+ if ((*slot)->value->ref_count <= 0 || gc_sec > cache->gc_ttl) {
-+ slot_t* dead = *slot;
-+
-+ if (dead->value->ref_count > 0) {
-+ switch(dead->value->type) {
-+ case APC_CACHE_ENTRY_FILE:
-+ apc_debug("GC cache entry '%s' (dev=%d ino=%d) was on gc-list for %d seconds" TSRMLS_CC,
-+ dead->value->data.file.filename, dead->key.data.file.device, dead->key.data.file.inode, gc_sec);
-+ break;
-+ case APC_CACHE_ENTRY_USER:
-+ apc_debug("GC cache entry '%s' was on gc-list for %d seconds" TSRMLS_CC, dead->value->data.user.info, gc_sec);
-+ break;
-+ }
-+ }
-+ *slot = dead->next;
-+ free_slot(dead TSRMLS_CC);
-+ }
-+ else {
-+ slot = &(*slot)->next;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ prevent_garbage_collection */
-+static void prevent_garbage_collection(apc_cache_entry_t* entry)
-+{
-+ /* set reference counts on zend objects to an arbitrarily high value to
-+ * prevent garbage collection after execution */
-+
-+ enum { BIG_VALUE = 1000 };
-+
-+ if(entry->data.file.op_array) {
-+ entry->data.file.op_array->refcount[0] = BIG_VALUE;
-+ }
-+ if (entry->data.file.functions) {
-+ int i;
-+ apc_function_t* fns = entry->data.file.functions;
-+ for (i=0; fns[i].function != NULL; i++) {
-+ *(fns[i].function->op_array.refcount) = BIG_VALUE;
-+ }
-+ }
-+ if (entry->data.file.classes) {
-+ int i;
-+ apc_class_t* classes = entry->data.file.classes;
-+ for (i=0; classes[i].class_entry != NULL; i++) {
-+ classes[i].class_entry->refcount = BIG_VALUE;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_create */
-+apc_cache_t* apc_cache_create(int size_hint, int gc_ttl, int ttl TSRMLS_DC)
-+{
-+ apc_cache_t* cache;
-+ int cache_size;
-+ int num_slots;
-+
-+ num_slots = make_prime(size_hint > 0 ? size_hint : 2000);
-+
-+ cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t) TSRMLS_CC);
-+ cache_size = sizeof(cache_header_t) + num_slots*sizeof(slot_t*);
-+
-+ cache->shmaddr = apc_sma_malloc(cache_size TSRMLS_CC);
-+ if(!cache->shmaddr) {
-+ apc_error("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). " TSRMLS_CC);
-+ return NULL;
-+ }
-+ memset(cache->shmaddr, 0, cache_size);
-+
-+ cache->header = (cache_header_t*) cache->shmaddr;
-+ cache->header->num_hits = 0;
-+ cache->header->num_misses = 0;
-+ cache->header->deleted_list = NULL;
-+ cache->header->start_time = time(NULL);
-+ cache->header->expunges = 0;
-+ cache->header->busy = 0;
-+
-+ cache->slots = (slot_t**) (((char*) cache->shmaddr) + sizeof(cache_header_t));
-+ cache->num_slots = num_slots;
-+ cache->gc_ttl = gc_ttl;
-+ cache->ttl = ttl;
-+ CREATE_LOCK(cache->header->lock);
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ CREATE_LOCK(cache->header->wrlock);
-+#endif
-+ memset(cache->slots, 0, sizeof(slot_t*)*num_slots);
-+ cache->expunge_cb = apc_cache_expunge;
-+ cache->has_lock = 0;
-+
-+ return cache;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_destroy */
-+void apc_cache_destroy(apc_cache_t* cache TSRMLS_DC)
-+{
-+ DESTROY_LOCK(cache->header->lock);
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ DESTROY_LOCK(cache->header->wrlock);
-+#endif
-+ apc_efree(cache TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_clear */
-+void apc_cache_clear(apc_cache_t* cache TSRMLS_DC)
-+{
-+ int i;
-+
-+ if(!cache) return;
-+
-+ CACHE_LOCK(cache);
-+ cache->header->busy = 1;
-+ cache->header->num_hits = 0;
-+ cache->header->num_misses = 0;
-+ cache->header->start_time = time(NULL);
-+ cache->header->expunges = 0;
-+
-+ for (i = 0; i < cache->num_slots; i++) {
-+ slot_t* p = cache->slots[i];
-+ while (p) {
-+ remove_slot(cache, &p TSRMLS_CC);
-+ }
-+ cache->slots[i] = NULL;
-+ }
-+
-+ memset(&cache->header->lastkey, 0, sizeof(apc_keyid_t));
-+
-+ cache->header->busy = 0;
-+ CACHE_UNLOCK(cache);
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_expunge */
-+static void apc_cache_expunge(apc_cache_t* cache, size_t size TSRMLS_DC)
-+{
-+ int i;
-+ time_t t;
-+
-+ t = apc_time();
-+
-+ if(!cache) return;
-+
-+ if(!cache->ttl) {
-+ /*
-+ * If cache->ttl is not set, we wipe out the entire cache when
-+ * we run out of space.
-+ */
-+ CACHE_SAFE_LOCK(cache);
-+ process_pending_removals(cache TSRMLS_CC);
-+ if (apc_sma_get_avail_mem() > (size_t)(APCG(shm_size)/2)) {
-+ /* probably a queued up expunge, we don't need to do this */
-+ CACHE_SAFE_UNLOCK(cache);
-+ return;
-+ }
-+ cache->header->busy = 1;
-+ CACHE_FAST_INC(cache, cache->header->expunges);
-+clear_all:
-+ for (i = 0; i < cache->num_slots; i++) {
-+ slot_t* p = cache->slots[i];
-+ while (p) {
-+ remove_slot(cache, &p TSRMLS_CC);
-+ }
-+ cache->slots[i] = NULL;
-+ }
-+ memset(&cache->header->lastkey, 0, sizeof(apc_keyid_t));
-+ cache->header->busy = 0;
-+ CACHE_SAFE_UNLOCK(cache);
-+ } else {
-+ slot_t **p;
-+ /*
-+ * If the ttl for the cache is set we walk through and delete stale
-+ * entries. For the user cache that is slightly confusing since
-+ * we have the individual entry ttl's we can look at, but that would be
-+ * too much work. So if you want the user cache expunged, set a high
-+ * default apc.user_ttl and still provide a specific ttl for each entry
-+ * on insert
-+ */
-+
-+ CACHE_SAFE_LOCK(cache);
-+ process_pending_removals(cache TSRMLS_CC);
-+ if (apc_sma_get_avail_mem() > (size_t)(APCG(shm_size)/2)) {
-+ /* probably a queued up expunge, we don't need to do this */
-+ CACHE_SAFE_UNLOCK(cache);
-+ return;
-+ }
-+ cache->header->busy = 1;
-+ CACHE_FAST_INC(cache, cache->header->expunges);
-+ for (i = 0; i < cache->num_slots; i++) {
-+ p = &cache->slots[i];
-+ while(*p) {
-+ /*
-+ * For the user cache we look at the individual entry ttl values
-+ * and if not set fall back to the default ttl for the user cache
-+ */
-+ if((*p)->value->type == APC_CACHE_ENTRY_USER) {
-+ if((*p)->value->data.user.ttl) {
-+ if((time_t) ((*p)->creation_time + (*p)->value->data.user.ttl) < t) {
-+ remove_slot(cache, p TSRMLS_CC);
-+ continue;
-+ }
-+ } else if(cache->ttl) {
-+ if((*p)->creation_time + cache->ttl < t) {
-+ remove_slot(cache, p TSRMLS_CC);
-+ continue;
-+ }
-+ }
-+ } else if((*p)->access_time < (t - cache->ttl)) {
-+ remove_slot(cache, p TSRMLS_CC);
-+ continue;
-+ }
-+ p = &(*p)->next;
-+ }
-+ }
-+
-+ if (!apc_sma_get_avail_size(size)) {
-+ /* TODO: re-do this to remove goto across locked sections */
-+ goto clear_all;
-+ }
-+ memset(&cache->header->lastkey, 0, sizeof(apc_keyid_t));
-+ cache->header->busy = 0;
-+ CACHE_SAFE_UNLOCK(cache);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_insert */
-+static inline int _apc_cache_insert(apc_cache_t* cache,
-+ apc_cache_key_t key,
-+ apc_cache_entry_t* value,
-+ apc_context_t* ctxt,
-+ time_t t
-+ TSRMLS_DC)
-+{
-+ slot_t** slot;
-+
-+ if (!value) {
-+ return 0;
-+ }
-+
-+ apc_debug("Inserting [%s]\n" TSRMLS_CC, value->data.file.filename);
-+
-+ process_pending_removals(cache TSRMLS_CC);
-+
-+ slot = &cache->slots[key.h % cache->num_slots];
-+
-+ while(*slot) {
-+ if(key.type == (*slot)->key.type) {
-+ if(key.type == APC_CACHE_KEY_FILE) {
-+ if(key_equals((*slot)->key.data.file, key.data.file)) {
-+ /* If existing slot for the same device+inode is different, remove it and insert the new version */
-+ if (ctxt->force_update || (*slot)->key.mtime != key.mtime) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ break;
-+ }
-+ return 0;
-+ } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ continue;
-+ }
-+ } else { /* APC_CACHE_KEY_FPFILE */
-+ if((key.h == (*slot)->key.h) &&
-+ !memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) {
-+ /* Hrm.. it's already here, remove it and insert new one */
-+ remove_slot(cache, slot TSRMLS_CC);
-+ break;
-+ } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ continue;
-+ }
-+ }
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ if ((*slot = make_slot(&key, value, *slot, t TSRMLS_CC)) == NULL) {
-+ return -1;
-+ }
-+
-+ value->mem_size = ctxt->pool->size;
-+ cache->header->mem_size += ctxt->pool->size;
-+ CACHE_FAST_INC(cache, cache->header->num_entries);
-+ CACHE_FAST_INC(cache, cache->header->num_inserts);
-+
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_insert */
-+int apc_cache_insert(apc_cache_t* cache, apc_cache_key_t key, apc_cache_entry_t* value, apc_context_t *ctxt, time_t t TSRMLS_DC)
-+{
-+ int rval;
-+ CACHE_LOCK(cache);
-+ rval = _apc_cache_insert(cache, key, value, ctxt, t TSRMLS_CC);
-+ CACHE_UNLOCK(cache);
-+ return rval;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_insert */
-+int *apc_cache_insert_mult(apc_cache_t* cache, apc_cache_key_t* keys, apc_cache_entry_t** values, apc_context_t *ctxt, time_t t, int num_entries TSRMLS_DC)
-+{
-+ int *rval;
-+ int i;
-+
-+ rval = emalloc(sizeof(int) * num_entries);
-+ CACHE_LOCK(cache);
-+ for (i=0; i < num_entries; i++) {
-+ if (values[i]) {
-+ ctxt->pool = values[i]->pool;
-+ rval[i] = _apc_cache_insert(cache, keys[i], values[i], ctxt, t TSRMLS_CC);
-+ }
-+ }
-+ CACHE_UNLOCK(cache);
-+ return rval;
-+}
-+/* }}} */
-+
-+
-+/* {{{ apc_cache_user_insert */
-+int apc_cache_user_insert(apc_cache_t* cache, apc_cache_key_t key, apc_cache_entry_t* value, apc_context_t* ctxt, time_t t, int exclusive TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ unsigned int keylen = key.data.user.identifier_len;
-+ apc_keyid_t *lastkey = &cache->header->lastkey;
-+
-+ if (!value) {
-+ return 0;
-+ }
-+
-+ if(apc_cache_busy(cache)) {
-+ /* cache cleanup in progress, do not wait */
-+ return 0;
-+ }
-+
-+ if(apc_cache_is_last_key(cache, &key, t TSRMLS_CC)) {
-+ /* potential cache slam */
-+ return 0;
-+ }
-+
-+ CACHE_LOCK(cache);
-+
-+ memset(lastkey, 0, sizeof(apc_keyid_t));
-+
-+ lastkey->h = key.h;
-+ lastkey->keylen = keylen;
-+ lastkey->mtime = t;
-+#ifdef ZTS
-+ lastkey->tid = tsrm_thread_id();
-+#else
-+ lastkey->pid = getpid();
-+#endif
-+
-+ /* we do not reset lastkey after the insert. Whether it is inserted
-+ * or not, another insert in the same second is always a bad idea.
-+ */
-+
-+ process_pending_removals(cache TSRMLS_CC);
-+
-+ slot = &cache->slots[key.h % cache->num_slots];
-+
-+ while (*slot) {
-+ if (((*slot)->key.h == key.h) &&
-+ (!memcmp((*slot)->key.data.user.identifier, key.data.user.identifier, keylen))) {
-+ /*
-+ * At this point we have found the user cache entry. If we are doing
-+ * an exclusive insert (apc_add) we are going to bail right away if
-+ * the user entry already exists and it has no ttl, or
-+ * there is a ttl and the entry has not timed out yet.
-+ */
-+ if(exclusive && ( !(*slot)->value->data.user.ttl ||
-+ ( (*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) >= t )
-+ ) ) {
-+ goto fail;
-+ }
-+ remove_slot(cache, slot TSRMLS_CC);
-+ break;
-+ } else
-+ /*
-+ * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of
-+ * slot entries so we don't always have to skip past a bunch of stale entries. We check
-+ * for staleness here and get rid of them by first checking to see if the cache has a global
-+ * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly
-+ * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl
-+ */
-+ if((cache->ttl && (*slot)->access_time < (t - cache->ttl)) ||
-+ ((*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t)) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ continue;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ if ((*slot = make_slot(&key, value, *slot, t TSRMLS_CC)) == NULL) {
-+ goto fail;
-+ }
-+
-+ value->mem_size = ctxt->pool->size;
-+ cache->header->mem_size += ctxt->pool->size;
-+
-+ CACHE_FAST_INC(cache, cache->header->num_entries);
-+ CACHE_FAST_INC(cache, cache->header->num_inserts);
-+
-+ CACHE_UNLOCK(cache);
-+
-+ return 1;
-+
-+fail:
-+ CACHE_UNLOCK(cache);
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_find_slot */
-+slot_t* apc_cache_find_slot(apc_cache_t* cache, apc_cache_key_t key, time_t t TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ volatile slot_t* retval = NULL;
-+
-+ CACHE_RDLOCK(cache);
-+ if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots];
-+ else slot = &cache->slots[key.h % cache->num_slots];
-+
-+ while (*slot) {
-+ if(key.type == (*slot)->key.type) {
-+ if(key.type == APC_CACHE_KEY_FILE) {
-+ if(key_equals((*slot)->key.data.file, key.data.file)) {
-+ if((*slot)->key.mtime != key.mtime) {
-+ #if (USE_READ_LOCKS == 0)
-+ /* this is merely a memory-friendly optimization, if we do have a write-lock
-+ * might as well move this to the deleted_list right-away. Otherwise an insert
-+ * of the same key wil do it (or an expunge, *eventually*).
-+ */
-+ remove_slot(cache, slot TSRMLS_CC);
-+ #endif
-+ CACHE_SAFE_INC(cache, cache->header->num_misses);
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+ }
-+ CACHE_SAFE_INC(cache, (*slot)->num_hits);
-+ CACHE_SAFE_INC(cache, (*slot)->value->ref_count);
-+ (*slot)->access_time = t;
-+ prevent_garbage_collection((*slot)->value);
-+ CACHE_FAST_INC(cache, cache->header->num_hits);
-+ retval = *slot;
-+ CACHE_RDUNLOCK(cache);
-+ return (slot_t*)retval;
-+ }
-+ } else { /* APC_CACHE_KEY_FPFILE */
-+ if(((*slot)->key.h == key.h) &&
-+ !memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) {
-+ /* TTL Check ? */
-+ CACHE_SAFE_INC(cache, (*slot)->num_hits);
-+ CACHE_SAFE_INC(cache, (*slot)->value->ref_count);
-+ (*slot)->access_time = t;
-+ prevent_garbage_collection((*slot)->value);
-+ CACHE_FAST_INC(cache, cache->header->num_hits);
-+ retval = *slot;
-+ CACHE_RDUNLOCK(cache);
-+ return (slot_t*)retval;
-+ }
-+ }
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ CACHE_FAST_INC(cache, cache->header->num_misses);
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_find */
-+apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, apc_cache_key_t key, time_t t TSRMLS_DC)
-+{
-+ slot_t * slot = apc_cache_find_slot(cache, key, t TSRMLS_CC);
-+ apc_debug("apc_cache_find [%i]\n" TSRMLS_CC, key.h);
-+ return (slot) ? slot->value : NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_user_find */
-+apc_cache_entry_t* apc_cache_user_find(apc_cache_t* cache, char *strkey, int keylen, time_t t TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ volatile apc_cache_entry_t* value = NULL;
-+ unsigned long h;
-+
-+ if(apc_cache_busy(cache))
-+ {
-+ /* cache cleanup in progress */
-+ return NULL;
-+ }
-+
-+ CACHE_RDLOCK(cache);
-+
-+ h = string_nhash_8(strkey, keylen);
-+
-+ slot = &cache->slots[h % cache->num_slots];
-+
-+ while (*slot) {
-+ if ((h == (*slot)->key.h) &&
-+ !memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
-+ /* Check to make sure this entry isn't expired by a hard TTL */
-+ if((*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t) {
-+ #if (USE_READ_LOCKS == 0)
-+ /* this is merely a memory-friendly optimization, if we do have a write-lock
-+ * might as well move this to the deleted_list right-away. Otherwise an insert
-+ * of the same key wil do it (or an expunge, *eventually*).
-+ */
-+ remove_slot(cache, slot TSRMLS_CC);
-+ #endif
-+ CACHE_FAST_INC(cache, cache->header->num_misses);
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+ }
-+ /* Otherwise we are fine, increase counters and return the cache entry */
-+ CACHE_SAFE_INC(cache, (*slot)->num_hits);
-+ CACHE_SAFE_INC(cache, (*slot)->value->ref_count);
-+ (*slot)->access_time = t;
-+
-+ CACHE_FAST_INC(cache, cache->header->num_hits);
-+ value = (*slot)->value;
-+ CACHE_RDUNLOCK(cache);
-+ return (apc_cache_entry_t*)value;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ CACHE_FAST_INC(cache, cache->header->num_misses);
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_user_exists */
-+apc_cache_entry_t* apc_cache_user_exists(apc_cache_t* cache, char *strkey, int keylen, time_t t TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ volatile apc_cache_entry_t* value = NULL;
-+ unsigned long h;
-+
-+ if(apc_cache_busy(cache))
-+ {
-+ /* cache cleanup in progress */
-+ return NULL;
-+ }
-+
-+ CACHE_RDLOCK(cache);
-+
-+ h = string_nhash_8(strkey, keylen);
-+
-+ slot = &cache->slots[h % cache->num_slots];
-+
-+ while (*slot) {
-+ if ((h == (*slot)->key.h) &&
-+ !memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
-+ /* Check to make sure this entry isn't expired by a hard TTL */
-+ if((*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t) {
-+ CACHE_UNLOCK(cache);
-+ return NULL;
-+ }
-+ /* Return the cache entry ptr */
-+ value = (*slot)->value;
-+ CACHE_RDUNLOCK(cache);
-+ return (apc_cache_entry_t*)value;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_user_update */
-+int _apc_cache_user_update(apc_cache_t* cache, char *strkey, int keylen, apc_cache_updater_t updater, void* data TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ int retval;
-+ unsigned long h;
-+
-+ if(apc_cache_busy(cache))
-+ {
-+ /* cache cleanup in progress */
-+ return 0;
-+ }
-+
-+ CACHE_LOCK(cache);
-+
-+ h = string_nhash_8(strkey, keylen);
-+ slot = &cache->slots[h % cache->num_slots];
-+
-+ while (*slot) {
-+ if ((h == (*slot)->key.h) &&
-+ !memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
-+ switch(Z_TYPE_P((*slot)->value->data.user.val) & ~IS_CONSTANT_INDEX) {
-+ case IS_ARRAY:
-+ case IS_CONSTANT_ARRAY:
-+ case IS_OBJECT:
-+ {
-+ if(APCG(serializer)) {
-+ retval = 0;
-+ break;
-+ } else {
-+ /* fall through */
-+ }
-+ }
-+ /* fall through */
-+ default:
-+ {
-+ retval = updater(cache, (*slot)->value, data);
-+ (*slot)->key.mtime = apc_time();
-+ }
-+ break;
-+ }
-+ CACHE_UNLOCK(cache);
-+ return retval;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ CACHE_UNLOCK(cache);
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_user_delete */
-+int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ unsigned long h;
-+
-+ CACHE_LOCK(cache);
-+
-+ h = string_nhash_8(strkey, keylen);
-+
-+ slot = &cache->slots[h % cache->num_slots];
-+
-+ while (*slot) {
-+ if ((h == (*slot)->key.h) &&
-+ !memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ CACHE_UNLOCK(cache);
-+ return 1;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ CACHE_UNLOCK(cache);
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_delete */
-+int apc_cache_delete(apc_cache_t* cache, char *filename, int filename_len TSRMLS_DC)
-+{
-+ slot_t** slot;
-+ time_t t;
-+ apc_cache_key_t key;
-+
-+ t = apc_time();
-+
-+ /* try to create a cache key; if we fail, give up on caching */
-+ if (!apc_cache_make_file_key(&key, filename, PG(include_path), t TSRMLS_CC)) {
-+ apc_warning("Could not stat file %s, unable to delete from cache." TSRMLS_CC, filename);
-+ return -1;
-+ }
-+
-+ CACHE_LOCK(cache);
-+
-+ if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots];
-+ else slot = &cache->slots[key.h % cache->num_slots];
-+
-+ while(*slot) {
-+ if(key.type == (*slot)->key.type) {
-+ if(key.type == APC_CACHE_KEY_FILE) {
-+ if(key_equals((*slot)->key.data.file, key.data.file)) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ CACHE_UNLOCK(cache);
-+ return 1;
-+ }
-+ } else { /* APC_CACHE_KEY_FPFILE */
-+ if(((*slot)->key.h == key.h) &&
-+ (!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1))) {
-+ remove_slot(cache, slot TSRMLS_CC);
-+ CACHE_UNLOCK(cache);
-+ return 1;
-+ }
-+ }
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ memset(&cache->header->lastkey, 0, sizeof(apc_keyid_t));
-+
-+ CACHE_UNLOCK(cache);
-+ return 0;
-+
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_release */
-+void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry TSRMLS_DC)
-+{
-+ CACHE_SAFE_DEC(cache, entry->ref_count);
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_make_file_key */
-+int apc_cache_make_file_key(apc_cache_key_t* key,
-+ const char* filename,
-+ const char* include_path,
-+ time_t t
-+ TSRMLS_DC)
-+{
-+ struct stat *tmp_buf=NULL;
-+ struct apc_fileinfo_t *fileinfo = NULL;
-+ int len;
-+
-+ assert(key != NULL);
-+
-+ if (!filename || !SG(request_info).path_translated) {
-+ apc_debug("No filename and no path_translated - bailing\n" TSRMLS_CC);
-+ goto cleanup;
-+ }
-+
-+ len = strlen(filename);
-+ if(APCG(fpstat)==0) {
-+ if(IS_ABSOLUTE_PATH(filename,len) || strstr(filename, "://")) {
-+ key->data.fpfile.fullpath = filename;
-+ key->data.fpfile.fullpath_len = len;
-+ key->h = string_nhash_8(key->data.fpfile.fullpath, key->data.fpfile.fullpath_len);
-+ key->mtime = t;
-+ key->type = APC_CACHE_KEY_FPFILE;
-+ goto success;
-+ } else if(APCG(canonicalize)) {
-+
-+ fileinfo = apc_php_malloc(sizeof(apc_fileinfo_t) TSRMLS_CC);
-+
-+ if (apc_search_paths(filename, include_path, fileinfo TSRMLS_CC) != 0) {
-+ apc_warning("apc failed to locate %s - bailing" TSRMLS_CC, filename);
-+ goto cleanup;
-+ }
-+
-+ if(!VCWD_REALPATH(fileinfo->fullpath, APCG(canon_path))) {
-+ apc_warning("realpath failed to canonicalize %s - bailing" TSRMLS_CC, filename);
-+ goto cleanup;
-+ }
-+
-+ key->data.fpfile.fullpath = APCG(canon_path);
-+ key->data.fpfile.fullpath_len = strlen(APCG(canon_path));
-+ key->h = string_nhash_8(key->data.fpfile.fullpath, key->data.fpfile.fullpath_len);
-+ key->mtime = t;
-+ key->type = APC_CACHE_KEY_FPFILE;
-+ goto success;
-+ }
-+ /* fall through to stat mode */
-+ }
-+
-+ fileinfo = apc_php_malloc(sizeof(apc_fileinfo_t) TSRMLS_CC);
-+
-+ assert(fileinfo != NULL);
-+
-+ if(!strcmp(SG(request_info).path_translated, filename)) {
-+ tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */
-+ }
-+
-+ if(tmp_buf) {
-+ fileinfo->st_buf.sb = *tmp_buf;
-+ } else {
-+ if (apc_search_paths(filename, include_path, fileinfo TSRMLS_CC) != 0) {
-+ apc_debug("Stat failed %s - bailing (%s) (%d)\n" TSRMLS_CC, filename,SG(request_info).path_translated);
-+ goto cleanup;
-+ }
-+ }
-+
-+ if(APCG(max_file_size) < fileinfo->st_buf.sb.st_size) {
-+ apc_debug("File is too big %s (%d - %ld) - bailing\n" TSRMLS_CC, filename,t,fileinfo->st_buf.sb.st_size);
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * This is a bit of a hack.
-+ *
-+ * Here I am checking to see if the file is at least 2 seconds old.
-+ * The idea is that if the file is currently being written to then its
-+ * mtime is going to match or at most be 1 second off of the current
-+ * request time and we want to avoid caching files that have not been
-+ * completely written. Of course, people should be using atomic
-+ * mechanisms to push files onto live web servers, but adding this
-+ * tiny safety is easier than educating the world. This is now
-+ * configurable, but the default is still 2 seconds.
-+ */
-+ if(APCG(file_update_protection) && (t - fileinfo->st_buf.sb.st_mtime < APCG(file_update_protection)) && !APCG(force_file_update)) {
-+ apc_debug("File is too new %s (%d - %d) - bailing\n" TSRMLS_CC,filename,t,fileinfo->st_buf.sb.st_mtime);
-+ goto cleanup;
-+ }
-+
-+ key->data.file.device = fileinfo->st_buf.sb.st_dev;
-+ key->data.file.inode = fileinfo->st_buf.sb.st_ino;
-+ key->h = (unsigned long) key->data.file.device + (unsigned long) key->data.file.inode;
-+
-+ /*
-+ * If working with content management systems that like to munge the mtime,
-+ * it might be appropriate to key off of the ctime to be immune to systems
-+ * that try to backdate a template. If the mtime is set to something older
-+ * than the previous mtime of a template we will obviously never see this
-+ * "older" template. At some point the Smarty templating system did this.
-+ * I generally disagree with using the ctime here because you lose the
-+ * ability to warm up new content by saving it to a temporary file, hitting
-+ * it once to cache it and then renaming it into its permanent location so
-+ * set the apc.stat_ctime=true to enable this check.
-+ */
-+ if(APCG(stat_ctime)) {
-+ key->mtime = (fileinfo->st_buf.sb.st_ctime > fileinfo->st_buf.sb.st_mtime) ? fileinfo->st_buf.sb.st_ctime : fileinfo->st_buf.sb.st_mtime;
-+ } else {
-+ key->mtime = fileinfo->st_buf.sb.st_mtime;
-+ }
-+ key->type = APC_CACHE_KEY_FILE;
-+
-+success:
-+
-+ if(fileinfo != NULL) {
-+ apc_php_free(fileinfo TSRMLS_CC);
-+ }
-+
-+ return 1;
-+
-+cleanup:
-+
-+ if(fileinfo != NULL) {
-+ apc_php_free(fileinfo TSRMLS_CC);
-+ }
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_make_user_key */
-+int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t)
-+{
-+ assert(key != NULL);
-+
-+ if (!identifier)
-+ return 0;
-+
-+ key->data.user.identifier = identifier;
-+ key->data.user.identifier_len = identifier_len;
-+ key->h = string_nhash_8(key->data.user.identifier, key->data.user.identifier_len);
-+ key->mtime = t;
-+ key->type = APC_CACHE_KEY_USER;
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_make_file_entry */
-+apc_cache_entry_t* apc_cache_make_file_entry(const char* filename,
-+ zend_op_array* op_array,
-+ apc_function_t* functions,
-+ apc_class_t* classes,
-+ apc_context_t* ctxt
-+ TSRMLS_DC)
-+{
-+ apc_cache_entry_t* entry;
-+ apc_pool* pool = ctxt->pool;
-+
-+ entry = (apc_cache_entry_t*) apc_pool_alloc(pool, sizeof(apc_cache_entry_t));
-+ if (!entry) return NULL;
-+
-+ entry->data.file.filename = apc_pstrdup(filename, pool TSRMLS_CC);
-+ if(!entry->data.file.filename) {
-+ apc_debug("apc_cache_make_file_entry: entry->data.file.filename is NULL - bailing\n" TSRMLS_CC);
-+ return NULL;
-+ }
-+ apc_debug("apc_cache_make_file_entry: entry->data.file.filename is [%s]\n" TSRMLS_CC,entry->data.file.filename);
-+ entry->data.file.op_array = op_array;
-+ entry->data.file.functions = functions;
-+ entry->data.file.classes = classes;
-+
-+ entry->data.file.halt_offset = apc_file_halt_offset(filename TSRMLS_CC);
-+
-+ entry->type = APC_CACHE_ENTRY_FILE;
-+ entry->ref_count = 0;
-+ entry->mem_size = 0;
-+ entry->pool = pool;
-+ return entry;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_store_zval */
-+zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ if (Z_TYPE_P(src) == IS_ARRAY) {
-+ /* Maintain a list of zvals we've copied to properly handle recursive structures */
-+ zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
-+ dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC);
-+ zend_hash_destroy(&APCG(copied_zvals));
-+ APCG(copied_zvals).nTableSize=0;
-+ } else {
-+ dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC);
-+ }
-+
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_fetch_zval */
-+zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ if (Z_TYPE_P(src) == IS_ARRAY) {
-+ /* Maintain a list of zvals we've copied to properly handle recursive structures */
-+ zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
-+ dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC);
-+ zend_hash_destroy(&APCG(copied_zvals));
-+ APCG(copied_zvals).nTableSize=0;
-+ } else {
-+ dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC);
-+ }
-+
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_make_user_entry */
-+apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval* val, apc_context_t* ctxt, const unsigned int ttl TSRMLS_DC)
-+{
-+ apc_cache_entry_t* entry;
-+ apc_pool* pool = ctxt->pool;
-+
-+ entry = (apc_cache_entry_t*) apc_pool_alloc(pool, sizeof(apc_cache_entry_t));
-+ if (!entry) return NULL;
-+
-+ entry->data.user.info = apc_pmemcpy(info, info_len, pool TSRMLS_CC);
-+ entry->data.user.info_len = info_len;
-+ if(!entry->data.user.info) {
-+ return NULL;
-+ }
-+ entry->data.user.val = apc_cache_store_zval(NULL, val, ctxt TSRMLS_CC);
-+ if(!entry->data.user.val) {
-+ return NULL;
-+ }
-+ INIT_PZVAL(entry->data.user.val);
-+ entry->data.user.ttl = ttl;
-+ entry->type = APC_CACHE_ENTRY_USER;
-+ entry->ref_count = 0;
-+ entry->mem_size = 0;
-+ entry->pool = pool;
-+ return entry;
-+}
-+/* }}} */
-+
-+/* {{{ */
-+static zval* apc_cache_link_info(apc_cache_t *cache, slot_t* p TSRMLS_DC)
-+{
-+ zval *link = NULL;
-+ char md5str[33];
-+
-+ ALLOC_INIT_ZVAL(link);
-+
-+ if(!link) {
-+ return NULL;
-+ }
-+
-+ array_init(link);
-+
-+ if(p->value->type == APC_CACHE_ENTRY_FILE) {
-+ add_assoc_string(link, "type", "file", 1);
-+ if(p->key.type == APC_CACHE_KEY_FILE) {
-+
-+ #ifdef PHP_WIN32
-+ {
-+ char buf[20];
-+ sprintf(buf, "%I64d", p->key.data.file.device);
-+ add_assoc_string(link, "device", buf, 1);
-+
-+ sprintf(buf, "%I64d", p->key.data.file.inode);
-+ add_assoc_string(link, "inode", buf, 1);
-+ }
-+ #else
-+ add_assoc_long(link, "device", p->key.data.file.device);
-+ add_assoc_long(link, "inode", p->key.data.file.inode);
-+ #endif
-+
-+ add_assoc_string(link, "filename", p->value->data.file.filename, 1);
-+ } else { /* This is a no-stat fullpath file entry */
-+ add_assoc_long(link, "device", 0);
-+ add_assoc_long(link, "inode", 0);
-+ add_assoc_string(link, "filename", (char*)p->key.data.fpfile.fullpath, 1);
-+ }
-+ if (APCG(file_md5)) {
-+ make_digest(md5str, p->key.md5);
-+ add_assoc_string(link, "md5", md5str, 1);
-+ }
-+ } else if(p->value->type == APC_CACHE_ENTRY_USER) {
-+ add_assoc_stringl(link, "info", p->value->data.user.info, p->value->data.user.info_len-1, 1);
-+ add_assoc_long(link, "ttl", (long)p->value->data.user.ttl);
-+ add_assoc_string(link, "type", "user", 1);
-+ }
-+
-+ add_assoc_double(link, "num_hits", (double)p->num_hits);
-+ add_assoc_long(link, "mtime", p->key.mtime);
-+ add_assoc_long(link, "creation_time", p->creation_time);
-+ add_assoc_long(link, "deletion_time", p->deletion_time);
-+ add_assoc_long(link, "access_time", p->access_time);
-+ add_assoc_long(link, "ref_count", p->value->ref_count);
-+ add_assoc_long(link, "mem_size", p->value->mem_size);
-+
-+ return link;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_info */
-+zval* apc_cache_info(apc_cache_t* cache, zend_bool limited TSRMLS_DC)
-+{
-+ zval *info = NULL;
-+ zval *list = NULL;
-+ zval *deleted_list = NULL;
-+ zval *slots = NULL;
-+ slot_t* p;
-+ int i, j;
-+
-+ if(!cache) return NULL;
-+
-+ CACHE_RDLOCK(cache);
-+
-+ ALLOC_INIT_ZVAL(info);
-+
-+ if(!info) {
-+ CACHE_RDUNLOCK(cache);
-+ return NULL;
-+ }
-+
-+ array_init(info);
-+ add_assoc_long(info, "num_slots", cache->num_slots);
-+ add_assoc_long(info, "ttl", cache->ttl);
-+
-+ add_assoc_double(info, "num_hits", (double)cache->header->num_hits);
-+ add_assoc_double(info, "num_misses", (double)cache->header->num_misses);
-+ add_assoc_double(info, "num_inserts", (double)cache->header->num_inserts);
-+ add_assoc_double(info, "expunges", (double)cache->header->expunges);
-+
-+ add_assoc_long(info, "start_time", cache->header->start_time);
-+ add_assoc_double(info, "mem_size", (double)cache->header->mem_size);
-+ add_assoc_long(info, "num_entries", cache->header->num_entries);
-+#ifdef MULTIPART_EVENT_FORMDATA
-+ add_assoc_long(info, "file_upload_progress", 1);
-+#else
-+ add_assoc_long(info, "file_upload_progress", 0);
-+#endif
-+#if APC_MMAP
-+ add_assoc_stringl(info, "memory_type", "mmap", sizeof("mmap")-1, 1);
-+#else
-+ add_assoc_stringl(info, "memory_type", "IPC shared", sizeof("IPC shared")-1, 1);
-+#endif
-+ add_assoc_stringl(info, "locking_type", APC_LOCK_TYPE, sizeof(APC_LOCK_TYPE)-1, 1);
-+
-+ if(!limited) {
-+ /* For each hashtable slot */
-+ ALLOC_INIT_ZVAL(list);
-+ array_init(list);
-+
-+ ALLOC_INIT_ZVAL(slots);
-+ array_init(slots);
-+
-+ for (i = 0; i < cache->num_slots; i++) {
-+ p = cache->slots[i];
-+ j = 0;
-+ for (; p != NULL; p = p->next) {
-+ zval *link = apc_cache_link_info(cache, p TSRMLS_CC);
-+ add_next_index_zval(list, link);
-+ j++;
-+ }
-+ if(j != 0) {
-+ add_index_long(slots, (ulong)i, j);
-+ }
-+ }
-+
-+ /* For each slot pending deletion */
-+ ALLOC_INIT_ZVAL(deleted_list);
-+ array_init(deleted_list);
-+
-+ for (p = cache->header->deleted_list; p != NULL; p = p->next) {
-+ zval *link = apc_cache_link_info(cache, p TSRMLS_CC);
-+ add_next_index_zval(deleted_list, link);
-+ }
-+
-+ add_assoc_zval(info, "cache_list", list);
-+ add_assoc_zval(info, "deleted_list", deleted_list);
-+ add_assoc_zval(info, "slot_distribution", slots);
-+ }
-+
-+ CACHE_RDUNLOCK(cache);
-+ return info;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_unlock */
-+void apc_cache_unlock(apc_cache_t* cache TSRMLS_DC)
-+{
-+ CACHE_UNLOCK(cache);
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_busy */
-+zend_bool apc_cache_busy(apc_cache_t* cache)
-+{
-+ return cache->header->busy;
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_is_last_key */
-+zend_bool apc_cache_is_last_key(apc_cache_t* cache, apc_cache_key_t* key, time_t t TSRMLS_DC)
-+{
-+ apc_keyid_t *lastkey = &cache->header->lastkey;
-+ unsigned int keylen = key->data.user.identifier_len;
-+#ifdef ZTS
-+ THREAD_T tid = tsrm_thread_id();
-+ #define FROM_DIFFERENT_THREAD(k) (memcmp(&((k)->tid), &tid, sizeof(THREAD_T))!=0)
-+#else
-+ pid_t pid = getpid();
-+ #define FROM_DIFFERENT_THREAD(k) (pid != (k)->pid)
-+#endif
-+
-+
-+ /* unlocked reads, but we're not shooting for 100% success with this */
-+ if(lastkey->h == key->h && keylen == lastkey->keylen) {
-+ if(lastkey->mtime == t && FROM_DIFFERENT_THREAD(lastkey)) {
-+ /* potential cache slam */
-+ if(APCG(slam_defense)) {
-+ apc_debug("Potential cache slam averted for key '%s'" TSRMLS_CC, key->data.user.identifier);
-+ return 1;
-+ }
-+ }
-+ }
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+#if NONBLOCKING_LOCK_AVAILABLE
-+/* {{{ apc_cache_write_lock */
-+zend_bool apc_cache_write_lock(apc_cache_t* cache TSRMLS_DC)
-+{
-+ return apc_lck_nb_lock(cache->header->wrlock);
-+}
-+/* }}} */
-+
-+/* {{{ apc_cache_write_unlock */
-+void apc_cache_write_unlock(apc_cache_t* cache TSRMLS_DC)
-+{
-+ apc_lck_unlock(cache->header->wrlock);
-+}
-+/* }}} */
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_cache.h b/ext/apc/apc_cache.h
---- a/ext/apc/apc_cache.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_cache.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,371 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_cache.h 324329 2012-03-18 15:29:37Z mike $ */
-+
-+#ifndef APC_CACHE_H
-+#define APC_CACHE_H
-+
-+/*
-+ * This module defines the shared memory file cache. Basically all of the
-+ * logic for storing and retrieving cache entries lives here.
-+ */
-+
-+#include "apc.h"
-+#include "apc_compile.h"
-+#include "apc_lock.h"
-+#include "apc_pool.h"
-+#include "apc_main.h"
-+#include "TSRM.h"
-+
-+#define APC_CACHE_ENTRY_FILE 1
-+#define APC_CACHE_ENTRY_USER 2
-+
-+#define APC_CACHE_KEY_FILE 1
-+#define APC_CACHE_KEY_USER 2
-+#define APC_CACHE_KEY_FPFILE 3
-+
-+#ifdef PHP_WIN32
-+typedef unsigned __int64 apc_ino_t;
-+typedef unsigned __int64 apc_dev_t;
-+#else
-+typedef ino_t apc_ino_t;
-+typedef dev_t apc_dev_t;
-+#endif
-+
-+/* {{{ cache locking macros */
-+#define CACHE_LOCK(cache) { LOCK(cache->header->lock); cache->has_lock = 1; }
-+#define CACHE_UNLOCK(cache) { UNLOCK(cache->header->lock); cache->has_lock = 0; }
-+#define CACHE_SAFE_LOCK(cache) { if ((++cache->has_lock) == 1) LOCK(cache->header->lock); }
-+#define CACHE_SAFE_UNLOCK(cache) { if ((--cache->has_lock) == 0) UNLOCK(cache->header->lock); }
-+
-+#if (RDLOCK_AVAILABLE == 1) && defined(HAVE_ATOMIC_OPERATIONS)
-+#define USE_READ_LOCKS 1
-+#define CACHE_RDLOCK(cache) { RDLOCK(cache->header->lock); cache->has_lock = 0; }
-+#define CACHE_RDUNLOCK(cache) { RDUNLOCK(cache->header->lock); cache->has_lock = 0; }
-+#define CACHE_SAFE_INC(cache, obj) { ATOMIC_INC(obj); }
-+#define CACHE_SAFE_DEC(cache, obj) { ATOMIC_DEC(obj); }
-+#else
-+#define USE_READ_LOCKS 0
-+#define CACHE_RDLOCK(cache) { LOCK(cache->header->lock); cache->has_lock = 1; }
-+#define CACHE_RDUNLOCK(cache) { UNLOCK(cache->header->lock); cache->has_lock = 0; }
-+#define CACHE_SAFE_INC(cache, obj) { CACHE_SAFE_LOCK(cache); obj++; CACHE_SAFE_UNLOCK(cache);}
-+#define CACHE_SAFE_DEC(cache, obj) { CACHE_SAFE_LOCK(cache); obj--; CACHE_SAFE_UNLOCK(cache);}
-+#endif
-+
-+#define CACHE_FAST_INC(cache, obj) { obj++; }
-+#define CACHE_FAST_DEC(cache, obj) { obj--; }
-+/* }}} */
-+
-+/* {{{ struct definition: apc_cache_key_t */
-+#define T apc_cache_t*
-+typedef struct apc_cache_t apc_cache_t; /* opaque cache type */
-+
-+typedef union _apc_cache_key_data_t {
-+ struct {
-+ apc_dev_t device; /* the filesystem device */
-+ apc_ino_t inode; /* the filesystem inode */
-+ } file;
-+ struct {
-+ const char *identifier;
-+ int identifier_len;
-+ } user;
-+ struct {
-+ const char *fullpath;
-+ int fullpath_len;
-+ } fpfile;
-+} apc_cache_key_data_t;
-+
-+typedef struct apc_cache_key_t apc_cache_key_t;
-+struct apc_cache_key_t {
-+ apc_cache_key_data_t data;
-+ unsigned long h; /* pre-computed hash value */
-+ time_t mtime; /* the mtime of this cached entry */
-+ unsigned char type;
-+ unsigned char md5[16]; /* md5 hash of the source file */
-+};
-+
-+
-+typedef struct apc_keyid_t apc_keyid_t;
-+
-+struct apc_keyid_t {
-+ unsigned int h;
-+ unsigned int keylen;
-+ time_t mtime;
-+#ifdef ZTS
-+ THREAD_T tid;
-+#else
-+ pid_t pid;
-+#endif
-+};
-+/* }}} */
-+
-+/* {{{ struct definition: apc_cache_entry_t */
-+typedef union _apc_cache_entry_value_t {
-+ struct {
-+ char *filename; /* absolute path to source file */
-+ zend_op_array* op_array; /* op_array allocated in shared memory */
-+ apc_function_t* functions; /* array of apc_function_t's */
-+ apc_class_t* classes; /* array of apc_class_t's */
-+ long halt_offset; /* value of __COMPILER_HALT_OFFSET__ for the file */
-+ } file;
-+ struct {
-+ char *info;
-+ int info_len;
-+ zval *val;
-+ unsigned int ttl;
-+ } user;
-+} apc_cache_entry_value_t;
-+
-+typedef struct apc_cache_entry_t apc_cache_entry_t;
-+struct apc_cache_entry_t {
-+ apc_cache_entry_value_t data;
-+ unsigned char type;
-+ int ref_count;
-+ size_t mem_size;
-+ apc_pool *pool;
-+};
-+/* }}} */
-+
-+/*
-+ * apc_cache_create creates the shared memory compiler cache. This function
-+ * should be called just once (ideally in the web server parent process, e.g.
-+ * in apache), otherwise you will end up with multiple caches (which won't
-+ * necessarily break anything). Returns a pointer to the cache object.
-+ *
-+ * size_hint is a "hint" at the total number of source files that will be
-+ * cached. It determines the physical size of the hash table. Passing 0 for
-+ * this argument will use a reasonable default value.
-+ *
-+ * gc_ttl is the maximum time a cache entry may speed on the garbage
-+ * collection list. This is basically a work around for the inherent
-+ * unreliability of our reference counting mechanism (see apc_cache_release).
-+ *
-+ * ttl is the maximum time a cache entry can idle in a slot in case the slot
-+ * is needed. This helps in cleaning up the cache and ensuring that entries
-+ * hit frequently stay cached and ones not hit very often eventually disappear.
-+ */
-+extern T apc_cache_create(int size_hint, int gc_ttl, int ttl TSRMLS_DC);
-+
-+/*
-+ * apc_cache_destroy releases any OS resources associated with a cache object.
-+ * Under apache, this function can be safely called by the child processes
-+ * when they exit.
-+ */
-+extern void apc_cache_destroy(T cache TSRMLS_DC);
-+
-+/*
-+ * apc_cache_clear empties a cache. This can safely be called at any time,
-+ * even while other server processes are executing cached source files.
-+ */
-+extern void apc_cache_clear(T cache TSRMLS_DC);
-+
-+/*
-+ * apc_cache_insert adds an entry to the cache, using a filename as a key.
-+ * Internally, the filename is translated to a canonical representation, so
-+ * that relative and absolute filenames will map to a single key. Returns
-+ * non-zero if the file was successfully inserted, 0 otherwise. If 0 is
-+ * returned, the caller must free the cache entry by calling
-+ * apc_cache_free_entry (see below).
-+ *
-+ * key is the value created by apc_cache_make_file_key for file keys.
-+ *
-+ * value is a cache entry returned by apc_cache_make_entry (see below).
-+ */
-+extern int apc_cache_insert(T cache, apc_cache_key_t key,
-+ apc_cache_entry_t* value, apc_context_t* ctxt, time_t t TSRMLS_DC);
-+
-+extern int apc_cache_user_insert(T cache, apc_cache_key_t key,
-+ apc_cache_entry_t* value, apc_context_t* ctxt, time_t t, int exclusive TSRMLS_DC);
-+
-+extern int *apc_cache_insert_mult(apc_cache_t* cache, apc_cache_key_t* keys,
-+ apc_cache_entry_t** values, apc_context_t *ctxt, time_t t, int num_entries TSRMLS_DC);
-+
-+/*
-+ * apc_cache_find searches for a cache entry by filename, and returns a
-+ * pointer to the entry if found, NULL otherwise.
-+ *
-+ * key is a value created by apc_cache_make_file_key for file keys.
-+ */
-+extern apc_cache_entry_t* apc_cache_find(T cache, apc_cache_key_t key, time_t t TSRMLS_DC);
-+
-+/*
-+ * apc_cache_user_find searches for a cache entry by its hashed identifier,
-+ * and returns a pointer to the entry if found, NULL otherwise.
-+ *
-+ */
-+extern apc_cache_entry_t* apc_cache_user_find(T cache, char* strkey, int keylen, time_t t TSRMLS_DC);
-+
-+/*
-+ * apc_cache_user_exists searches for a cache entry by its hashed identifier,
-+ * and returns a pointer to the entry if found, NULL otherwise. This is a
-+ * quick non-locking version of apc_cache_user_find that does not modify the
-+ * shared memory segment in any way.
-+ *
-+ */
-+extern apc_cache_entry_t* apc_cache_user_exists(T cache, char* strkey, int keylen, time_t t TSRMLS_DC);
-+
-+/*
-+ * apc_cache_delete and apc_cache_user_delete finds an entry in the cache and deletes it.
-+ */
-+extern int apc_cache_delete(apc_cache_t* cache, char *filename, int filename_len TSRMLS_DC);
-+extern int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen TSRMLS_DC);
-+
-+/* apc_cach_fetch_zval takes a zval in the cache and reconstructs a runtime
-+ * zval from it.
-+ *
-+ */
-+zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC);
-+
-+/*
-+ * apc_cache_release decrements the reference count associated with a cache
-+ * entry. Calling apc_cache_find automatically increments the reference count,
-+ * and this function must be called post-execution to return the count to its
-+ * original value. Failing to do so will prevent the entry from being
-+ * garbage-collected.
-+ *
-+ * entry is the cache entry whose ref count you want to decrement.
-+ */
-+extern void apc_cache_release(T cache, apc_cache_entry_t* entry TSRMLS_DC);
-+
-+/*
-+ * apc_cache_make_file_key creates a key object given a relative or absolute
-+ * filename and an optional list of auxillary paths to search. include_path is
-+ * searched if the filename cannot be found relative to the current working
-+ * directory.
-+ *
-+ * key points to caller-allocated storage (must not be null).
-+ *
-+ * filename is the path to the source file.
-+ *
-+ * include_path is a colon-separated list of directories to search.
-+ *
-+ * and finally we pass in the current request time so we can avoid
-+ * caching files with a current mtime which tends to indicate that
-+ * they are still being written to.
-+ */
-+extern int apc_cache_make_file_key(apc_cache_key_t* key,
-+ const char* filename,
-+ const char* include_path,
-+ time_t t
-+ TSRMLS_DC);
-+
-+/*
-+ * apc_cache_make_file_entry creates an apc_cache_entry_t object given a filename
-+ * and the compilation results returned by the PHP compiler.
-+ */
-+extern apc_cache_entry_t* apc_cache_make_file_entry(const char* filename,
-+ zend_op_array* op_array,
-+ apc_function_t* functions,
-+ apc_class_t* classes,
-+ apc_context_t* ctxt
-+ TSRMLS_DC);
-+
-+
-+zend_bool apc_compile_cache_entry(apc_cache_key_t *key, zend_file_handle* h, int type, time_t t, zend_op_array** op_array_pp, apc_cache_entry_t** cache_entry_pp TSRMLS_DC);
-+
-+/*
-+ * apc_cache_make_user_entry creates an apc_cache_entry_t object given an info string
-+ * and the zval to be stored.
-+ */
-+extern apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval *val, apc_context_t* ctxt, const unsigned int ttl TSRMLS_DC);
-+
-+extern int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t);
-+
-+/* {{{ struct definition: slot_t */
-+typedef struct slot_t slot_t;
-+struct slot_t {
-+ apc_cache_key_t key; /* slot key */
-+ apc_cache_entry_t* value; /* slot value */
-+ slot_t* next; /* next slot in linked list */
-+ unsigned long num_hits; /* number of hits to this bucket */
-+ time_t creation_time; /* time slot was initialized */
-+ time_t deletion_time; /* time slot was removed from cache */
-+ time_t access_time; /* time slot was last accessed */
-+};
-+/* }}} */
-+
-+/* {{{ struct definition: cache_header_t
-+ Any values that must be shared among processes should go in here. */
-+typedef struct cache_header_t cache_header_t;
-+struct cache_header_t {
-+ apc_lck_t lock; /* read/write lock (exclusive blocking cache lock) */
-+ apc_lck_t wrlock; /* write lock (non-blocking used to prevent cache slams) */
-+ unsigned long num_hits; /* total successful hits in cache */
-+ unsigned long num_misses; /* total unsuccessful hits in cache */
-+ unsigned long num_inserts; /* total successful inserts in cache */
-+ unsigned long expunges; /* total number of expunges */
-+ slot_t* deleted_list; /* linked list of to-be-deleted slots */
-+ time_t start_time; /* time the above counters were reset */
-+ zend_bool busy; /* Flag to tell clients when we are busy cleaning the cache */
-+ int num_entries; /* Statistic on the number of entries */
-+ size_t mem_size; /* Statistic on the memory size used by this cache */
-+ apc_keyid_t lastkey; /* the key that is being inserted (user cache) */
-+};
-+/* }}} */
-+
-+typedef void (*apc_expunge_cb_t)(T cache, size_t n TSRMLS_DC);
-+
-+/* {{{ struct definition: apc_cache_t */
-+struct apc_cache_t {
-+ void* shmaddr; /* process (local) address of shared cache */
-+ cache_header_t* header; /* cache header (stored in SHM) */
-+ slot_t** slots; /* array of cache slots (stored in SHM) */
-+ int num_slots; /* number of slots in cache */
-+ int gc_ttl; /* maximum time on GC list for a slot */
-+ int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */
-+ apc_expunge_cb_t expunge_cb; /* cache specific expunge callback to free up sma memory */
-+ uint has_lock; /* flag for possible recursive locks within the same process */
-+};
-+/* }}} */
-+
-+extern zval* apc_cache_info(T cache, zend_bool limited TSRMLS_DC);
-+extern void apc_cache_unlock(apc_cache_t* cache TSRMLS_DC);
-+extern zend_bool apc_cache_busy(apc_cache_t* cache);
-+extern zend_bool apc_cache_write_lock(apc_cache_t* cache TSRMLS_DC);
-+extern void apc_cache_write_unlock(apc_cache_t* cache TSRMLS_DC);
-+extern zend_bool apc_cache_is_last_key(apc_cache_t* cache, apc_cache_key_t* key, time_t t TSRMLS_DC);
-+
-+/* used by apc_rfc1867 to update data in-place - not to be used elsewhere */
-+
-+typedef int (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data);
-+extern int _apc_cache_user_update(apc_cache_t* cache, char *strkey, int keylen,
-+ apc_cache_updater_t updater, void* data TSRMLS_DC);
-+
-+
-+#undef T
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_compile.c b/ext/apc/apc_compile.c
---- a/ext/apc/apc_compile.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_compile.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,2164 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_compile.c 326703 2012-07-19 17:06:12Z rasmus $ */
-+
-+#include "apc_compile.h"
-+#include "apc_globals.h"
-+#include "apc_zend.h"
-+#include "apc_php.h"
-+#include "apc_string.h"
-+#include "ext/standard/php_var.h"
-+#include "ext/standard/php_smart_str.h"
-+
-+typedef void* (*ht_copy_fun_t)(void*, void*, apc_context_t* TSRMLS_DC);
-+//typedef void (*ht_free_fun_t)(void*, apc_context_t*);
-+typedef int (*ht_check_copy_fun_t)(Bucket*, va_list);
-+
-+typedef void (*ht_fixup_fun_t)(Bucket*, zend_class_entry*, zend_class_entry*);
-+
-+#define CHECK(p) { if ((p) == NULL) return NULL; }
-+
-+/* {{{ internal function declarations */
-+
-+static zend_function* my_bitwise_copy_function(zend_function*, zend_function*, apc_context_t* TSRMLS_DC);
-+
-+/*
-+ * The "copy" functions perform deep-copies on a particular data structure
-+ * (passed as the second argument). They also optionally allocate space for
-+ * the destination data structure if the first argument is null.
-+ */
-+static zval** my_copy_zval_ptr(zval**, const zval**, apc_context_t* TSRMLS_DC);
-+static zval* my_copy_zval(zval*, const zval*, apc_context_t* TSRMLS_DC);
-+#ifndef ZEND_ENGINE_2_4
-+static znode* my_copy_znode(znode*, znode*, apc_context_t* TSRMLS_DC);
-+#endif
-+static zend_op* my_copy_zend_op(zend_op*, zend_op*, apc_context_t* TSRMLS_DC);
-+static zend_function* my_copy_function(zend_function*, zend_function*, apc_context_t* TSRMLS_DC);
-+static zend_function_entry* my_copy_function_entry(zend_function_entry*, const zend_function_entry*, apc_context_t* TSRMLS_DC);
-+static zend_class_entry* my_copy_class_entry(zend_class_entry*, zend_class_entry*, apc_context_t* TSRMLS_DC);
-+static HashTable* my_copy_hashtable_ex(HashTable*, HashTable* TSRMLS_DC, ht_copy_fun_t, int, apc_context_t*, ht_check_copy_fun_t, ...);
-+#define my_copy_hashtable( dst, src, copy_fn, holds_ptr, ctxt) \
-+ my_copy_hashtable_ex(dst, src TSRMLS_CC, copy_fn, holds_ptr, ctxt, NULL)
-+static HashTable* my_copy_static_variables(zend_op_array* src, apc_context_t* TSRMLS_DC);
-+static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_context_t* TSRMLS_DC);
-+static zend_arg_info* my_copy_arg_info_array(zend_arg_info*, const zend_arg_info*, uint, apc_context_t* TSRMLS_DC);
-+static zend_arg_info* my_copy_arg_info(zend_arg_info*, const zend_arg_info*, apc_context_t* TSRMLS_DC);
-+
-+/*
-+ * The "fixup" functions need for ZEND_ENGINE_2
-+ */
-+static void my_fixup_function( Bucket *p, zend_class_entry *src, zend_class_entry *dst );
-+static void my_fixup_hashtable( HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst );
-+/* my_fixup_function_for_execution is the same as my_fixup_function
-+ * but named differently for clarity
-+ */
-+#define my_fixup_function_for_execution my_fixup_function
-+
-+#ifdef ZEND_ENGINE_2_2
-+static void my_fixup_property_info( Bucket *p, zend_class_entry *src, zend_class_entry *dst );
-+#define my_fixup_property_info_for_execution my_fixup_property_info
-+#endif
-+
-+/*
-+ * These functions return "1" if the member/function is
-+ * defined/overridden in the 'current' class and not inherited.
-+ */
-+static int my_check_copy_function(Bucket* src, va_list args);
-+static int my_check_copy_property_info(Bucket* src, va_list args);
-+#ifndef ZEND_ENGINE_2_4
-+static int my_check_copy_default_property(Bucket* p, va_list args);
-+static int my_check_copy_static_member(Bucket* src, va_list args);
-+#endif
-+static int my_check_copy_constant(Bucket* src, va_list args);
-+
-+/* }}} */
-+
-+/* {{{ apc php serializers */
-+int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS)
-+{
-+ smart_str strbuf = {0};
-+ php_serialize_data_t var_hash;
-+ PHP_VAR_SERIALIZE_INIT(var_hash);
-+ php_var_serialize(&strbuf, (zval**)&value, &var_hash TSRMLS_CC);
-+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
-+ if(strbuf.c) {
-+ *buf = (unsigned char*)strbuf.c;
-+ *buf_len = strbuf.len;
-+ smart_str_0(&strbuf);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS)
-+{
-+ const unsigned char *tmp = buf;
-+ php_unserialize_data_t var_hash;
-+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
-+ if(!php_var_unserialize(value, &tmp, buf + buf_len, &var_hash TSRMLS_CC)) {
-+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-+ zval_dtor(*value);
-+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %ld bytes", (long)(tmp - buf), (long)buf_len);
-+ (*value)->type = IS_NULL;
-+ return 0;
-+ }
-+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ check_op_array_integrity */
-+#if 0
-+static void check_op_array_integrity(zend_op_array* src)
-+{
-+ int i, j;
-+
-+ /* These sorts of checks really aren't particularly effective, but they
-+ * can provide a welcome sanity check when debugging. Just don't enable
-+ * for production use! */
-+
-+ assert(src->refcount != NULL);
-+ assert(src->opcodes != NULL);
-+ assert(src->last > 0);
-+
-+ for (i = 0; i < src->last; i++) {
-+ zend_op* op = &src->opcodes[i];
-+ znode* nodes[] = { &op->result, &op->op1, &op->op2 };
-+ for (j = 0; j < 3; j++) {
-+ assert(nodes[j]->op_type == IS_CONST ||
-+ nodes[j]->op_type == IS_VAR ||
-+ nodes[j]->op_type == IS_TMP_VAR ||
-+ nodes[j]->op_type == IS_UNUSED);
-+
-+ if (nodes[j]->op_type == IS_CONST) {
-+ int type = nodes[j]->u.constant.type;
-+ assert(type == IS_RESOURCE ||
-+ type == IS_BOOL ||
-+ type == IS_LONG ||
-+ type == IS_DOUBLE ||
-+ type == IS_NULL ||
-+ type == IS_CONSTANT ||
-+ type == IS_STRING ||
-+ type == FLAG_IS_BC ||
-+ type == IS_ARRAY ||
-+ type == IS_CONSTANT_ARRAY ||
-+ type == IS_OBJECT);
-+ }
-+ }
-+ }
-+}
-+#endif
-+/* }}} */
-+
-+/* {{{ my_bitwise_copy_function */
-+static zend_function* my_bitwise_copy_function(zend_function* dst, zend_function* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_function*) apc_pool_alloc(pool, sizeof(src[0])));
-+ }
-+
-+ /* We only need to do a bitwise copy */
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_zval_ptr */
-+static zval** my_copy_zval_ptr(zval** dst, const zval** src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ zval* dst_new;
-+ apc_pool* pool = ctxt->pool;
-+ int usegc = (ctxt->copy == APC_COPY_OUT_OPCODE) || (ctxt->copy == APC_COPY_OUT_USER);
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zval**) apc_pool_alloc(pool, sizeof(zval*)));
-+ }
-+
-+ if(usegc) {
-+ ALLOC_ZVAL(dst[0]);
-+ CHECK(dst[0]);
-+ } else {
-+ CHECK((dst[0] = (zval*) apc_pool_alloc(pool, sizeof(zval))));
-+ }
-+
-+ CHECK((dst_new = my_copy_zval(*dst, *src, ctxt TSRMLS_CC)));
-+
-+ if(dst_new != *dst) {
-+ if(usegc) {
-+ FREE_ZVAL(dst[0]);
-+ }
-+ *dst = dst_new;
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_serialize_object */
-+static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ smart_str buf = {0};
-+ apc_pool* pool = ctxt->pool;
-+ apc_serialize_t serialize = APC_SERIALIZER_NAME(php);
-+ void *config = NULL;
-+
-+ if(APCG(serializer)) { /* TODO: move to ctxt */
-+ serialize = APCG(serializer)->serialize;
-+ config = APCG(serializer)->config;
-+ }
-+
-+ if(serialize((unsigned char**)&buf.c, &buf.len, src, config TSRMLS_CC)) {
-+ dst->type = src->type & ~IS_CONSTANT_INDEX;
-+ dst->value.str.len = buf.len;
-+ CHECK(dst->value.str.val = apc_pmemcpy(buf.c, (buf.len + 1), pool TSRMLS_CC));
-+ }
-+
-+ if(buf.c) smart_str_free(&buf);
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_unserialize_object */
-+static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_unserialize_t unserialize = APC_UNSERIALIZER_NAME(php);
-+ unsigned char *p = (unsigned char*)Z_STRVAL_P(src);
-+ void *config = NULL;
-+
-+ if(APCG(serializer)) { /* TODO: move to ctxt */
-+ unserialize = APCG(serializer)->unserialize;
-+ config = APCG(serializer)->config;
-+ }
-+
-+ if(unserialize(&dst, p, Z_STRLEN_P(src), config TSRMLS_CC)) {
-+ return dst;
-+ } else {
-+ zval_dtor(dst);
-+ dst->type = IS_NULL;
-+ }
-+ return dst;
-+}
-+/* }}} */
-+
-+static char *apc_string_pmemcpy(char *str, size_t len, apc_pool* pool TSRMLS_DC)
-+{
-+#ifdef ZEND_ENGINE_2_4
-+#ifndef ZTS
-+ if (pool->type != APC_UNPOOL) {
-+ char * ret = (char*)apc_new_interned_string((const char*)str, len TSRMLS_CC);
-+ if (ret) {
-+ return ret;
-+ }
-+ }
-+#endif
-+#endif
-+ return apc_pmemcpy(str, len, pool TSRMLS_CC);
-+}
-+
-+/* {{{ my_copy_zval */
-+static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ zval **tmp;
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(dst != NULL);
-+ assert(src != NULL);
-+
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ if(APCG(copied_zvals).nTableSize) {
-+ if(zend_hash_index_find(&APCG(copied_zvals), (ulong)src, (void**)&tmp) == SUCCESS) {
-+ if(Z_ISREF_P((zval*)src)) {
-+ Z_SET_ISREF_PP(tmp);
-+ }
-+ Z_ADDREF_PP(tmp);
-+ return *tmp;
-+ }
-+
-+ zend_hash_index_update(&APCG(copied_zvals), (ulong)src, (void**)&dst, sizeof(zval*), NULL);
-+ }
-+
-+
-+ if(ctxt->copy == APC_COPY_OUT_USER || ctxt->copy == APC_COPY_IN_USER) {
-+ /* deep copies are refcount(1), but moved up for recursive
-+ * arrays, which end up being add_ref'd during its copy. */
-+ Z_SET_REFCOUNT_P(dst, 1);
-+ Z_UNSET_ISREF_P(dst);
-+ } else {
-+ /* code uses refcount=2 for consts */
-+ Z_SET_REFCOUNT_P(dst, Z_REFCOUNT_P((zval*)src));
-+ Z_SET_ISREF_TO_P(dst, Z_ISREF_P((zval*)src));
-+ }
-+
-+ switch (src->type & IS_CONSTANT_TYPE_MASK) {
-+ case IS_RESOURCE:
-+ case IS_BOOL:
-+ case IS_LONG:
-+ case IS_DOUBLE:
-+ case IS_NULL:
-+ break;
-+
-+ case IS_CONSTANT:
-+ case IS_STRING:
-+ if (src->value.str.val) {
-+ CHECK(dst->value.str.val = apc_string_pmemcpy(src->value.str.val,
-+ src->value.str.len+1,
-+ pool TSRMLS_CC));
-+ }
-+ break;
-+
-+ case IS_ARRAY:
-+ case IS_CONSTANT_ARRAY:
-+ if(APCG(serializer) == NULL ||
-+ ctxt->copy == APC_COPY_IN_OPCODE || ctxt->copy == APC_COPY_OUT_OPCODE) {
-+
-+ CHECK(dst->value.ht =
-+ my_copy_hashtable(NULL,
-+ src->value.ht,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt));
-+ break;
-+ } else {
-+ /* fall through to object case */
-+ }
-+
-+ case IS_OBJECT:
-+
-+ dst->type = IS_NULL;
-+ if(ctxt->copy == APC_COPY_IN_USER) {
-+ dst = my_serialize_object(dst, src, ctxt TSRMLS_CC);
-+ } else if(ctxt->copy == APC_COPY_OUT_USER) {
-+ dst = my_unserialize_object(dst, src, ctxt TSRMLS_CC);
-+ }
-+ break;
-+
-+ default:
-+ assert(0);
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+#ifdef ZEND_ENGINE_2_4
-+/* {{{ my_copy_znode */
-+static void my_check_znode(zend_uchar op_type, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(op_type == IS_CONST ||
-+ op_type == IS_VAR ||
-+ op_type == IS_CV ||
-+ op_type == IS_TMP_VAR ||
-+ op_type == IS_UNUSED);
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_zend_op */
-+static zend_op* my_copy_zend_op(zend_op* dst, zend_op* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(dst != NULL);
-+ assert(src != NULL);
-+
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ my_check_znode(dst->result_type & ~EXT_TYPE_UNUSED, ctxt TSRMLS_CC);
-+ my_check_znode(dst->op1_type, ctxt TSRMLS_CC);
-+ my_check_znode(dst->op2_type, ctxt TSRMLS_CC);
-+
-+ return dst;
-+}
-+/* }}} */
-+#else
-+/* {{{ my_copy_znode */
-+static znode* my_copy_znode(znode* dst, znode* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(dst != NULL);
-+ assert(src != NULL);
-+
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+#ifdef IS_CV
-+ assert(dst ->op_type == IS_CONST ||
-+ dst ->op_type == IS_VAR ||
-+ dst ->op_type == IS_CV ||
-+ dst ->op_type == IS_TMP_VAR ||
-+ dst ->op_type == IS_UNUSED);
-+#else
-+ assert(dst ->op_type == IS_CONST ||
-+ dst ->op_type == IS_VAR ||
-+ dst ->op_type == IS_TMP_VAR ||
-+ dst ->op_type == IS_UNUSED);
-+#endif
-+
-+ if (src->op_type == IS_CONST) {
-+ if(!my_copy_zval(&dst->u.constant, &src->u.constant, ctxt TSRMLS_CC)) {
-+ return NULL;
-+ }
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_zend_op */
-+static zend_op* my_copy_zend_op(zend_op* dst, zend_op* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(dst != NULL);
-+ assert(src != NULL);
-+
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ CHECK(my_copy_znode(&dst->result, &src->result, ctxt TSRMLS_CC));
-+ CHECK(my_copy_znode(&dst->op1, &src->op1, ctxt TSRMLS_CC));
-+ CHECK(my_copy_znode(&dst->op2, &src->op2, ctxt TSRMLS_CC));
-+
-+ return dst;
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ my_copy_function */
-+static zend_function* my_copy_function(zend_function* dst, zend_function* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(src != NULL);
-+
-+ CHECK(dst = my_bitwise_copy_function(dst, src, ctxt TSRMLS_CC));
-+
-+ switch (src->type) {
-+ case ZEND_INTERNAL_FUNCTION:
-+ case ZEND_OVERLOADED_FUNCTION:
-+ /* shallow copy because op_array is internal */
-+ dst->op_array = src->op_array;
-+ break;
-+
-+ case ZEND_USER_FUNCTION:
-+ case ZEND_EVAL_CODE:
-+ CHECK(apc_copy_op_array(&dst->op_array,
-+ &src->op_array,
-+ ctxt TSRMLS_CC));
-+ break;
-+
-+ default:
-+ assert(0);
-+ }
-+ /*
-+ * op_array bitwise copying overwrites what ever you modified
-+ * before apc_copy_op_array - which is why this code is outside
-+ * my_bitwise_copy_function.
-+ */
-+
-+ /* zend_do_inheritance will re-look this up, because the pointers
-+ * in prototype are from a function table of another class. It just
-+ * helps if that one is from EG(class_table).
-+ */
-+ dst->common.prototype = NULL;
-+
-+ /* once a method is marked as ZEND_ACC_IMPLEMENTED_ABSTRACT then you
-+ * have to carry around a prototype. Thankfully zend_do_inheritance
-+ * sets this properly as well
-+ */
-+ dst->common.fn_flags = src->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
-+
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_function_entry */
-+static zend_function_entry* my_copy_function_entry(zend_function_entry* dst, const zend_function_entry* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_function_entry*) apc_pool_alloc(ctxt->pool, sizeof(src[0])));
-+ }
-+
-+ /* Start with a bitwise copy */
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ dst->fname = NULL;
-+ dst->arg_info = NULL;
-+
-+ if (src->fname) {
-+ CHECK((dst->fname = apc_pstrdup(src->fname, ctxt->pool TSRMLS_CC)));
-+ }
-+
-+ if (src->arg_info) {
-+ CHECK((dst->arg_info = my_copy_arg_info_array(NULL,
-+ src->arg_info,
-+ src->num_args,
-+ ctxt TSRMLS_CC)));
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_property_info */
-+static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_property_info*) apc_pool_alloc(pool, sizeof(*src)));
-+ }
-+
-+ /* Start with a bitwise copy */
-+ memcpy(dst, src, sizeof(*src));
-+
-+ dst->name = NULL;
-+#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0
-+ dst->doc_comment = NULL;
-+#endif
-+
-+ if (src->name) {
-+ /* private members are stored inside property_info as a mangled
-+ * string of the form:
-+ * \0<classname>\0<membername>\0
-+ */
-+ CHECK((dst->name = apc_string_pmemcpy(src->name, src->name_length+1, pool TSRMLS_CC)));
-+ }
-+
-+#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0
-+ if (src->doc_comment) {
-+ CHECK((dst->doc_comment = apc_pmemcpy(src->doc_comment, (src->doc_comment_len + 1), pool TSRMLS_CC)));
-+ }
-+#endif
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_property_info_for_execution */
-+static zend_property_info* my_copy_property_info_for_execution(zend_property_info* dst, zend_property_info* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_property_info*) apc_pool_alloc(ctxt->pool, sizeof(*src)));
-+ }
-+
-+ /* We need only a shallow copy */
-+ memcpy(dst, src, sizeof(*src));
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_arg_info_array */
-+static zend_arg_info* my_copy_arg_info_array(zend_arg_info* dst, const zend_arg_info* src, uint num_args, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ uint i = 0;
-+
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_arg_info*) apc_pool_alloc(ctxt->pool, (sizeof(*src) * num_args)));
-+ }
-+
-+ /* Start with a bitwise copy */
-+ memcpy(dst, src, sizeof(*src)*num_args);
-+
-+ for(i=0; i < num_args; i++) {
-+ CHECK((my_copy_arg_info( &dst[i], &src[i], ctxt TSRMLS_CC)));
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_arg_info */
-+static zend_arg_info* my_copy_arg_info(zend_arg_info* dst, const zend_arg_info* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_arg_info*) apc_pool_alloc(pool, sizeof(*src)));
-+ }
-+
-+ /* Start with a bitwise copy */
-+ memcpy(dst, src, sizeof(*src));
-+
-+ dst->name = NULL;
-+ dst->class_name = NULL;
-+
-+ if (src->name) {
-+ CHECK((dst->name = apc_string_pmemcpy((char *) src->name, src->name_len+1, pool TSRMLS_CC)));
-+ }
-+
-+ if (src->class_name) {
-+ CHECK((dst->class_name = apc_string_pmemcpy((char *) src->class_name, src->class_name_len+1, pool TSRMLS_CC)));
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_class_entry */
-+zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ return my_copy_class_entry(dst, src, ctxt TSRMLS_CC);
-+}
-+
-+/* {{{ my_copy_class_entry */
-+static zend_class_entry* my_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ int i = 0;
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_class_entry*) apc_pool_alloc(pool, sizeof(*src)));
-+ }
-+
-+ /* Start with a bitwise copy */
-+ memcpy(dst, src, sizeof(*src));
-+
-+ dst->name = NULL;
-+ memset(&dst->function_table, 0, sizeof(dst->function_table));
-+ ZEND_CE_DOC_COMMENT(dst) = NULL;
-+ ZEND_CE_FILENAME(dst) = NULL;
-+ memset(&dst->properties_info, 0, sizeof(dst->properties_info));
-+ memset(&dst->constants_table, 0, sizeof(dst->constants_table));
-+
-+ if (src->name) {
-+ CHECK((dst->name = apc_pstrdup(src->name, pool TSRMLS_CC)));
-+ }
-+
-+ if(!(my_copy_hashtable_ex(&dst->function_table,
-+ &src->function_table TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_function,
-+ 0,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_function,
-+ src))) {
-+ return NULL;
-+ }
-+
-+ /* the interfaces are populated at runtime using ADD_INTERFACE */
-+ dst->interfaces = NULL;
-+
-+ /* the current count includes inherited interfaces as well,
-+ the real dynamic ones are the first <n> which are zero'd
-+ out in zend_do_end_class_declaration */
-+ for(i = 0 ; (uint)i < src->num_interfaces ; i++) {
-+ if(src->interfaces[i])
-+ {
-+ dst->num_interfaces = i;
-+ break;
-+ }
-+ }
-+
-+ /* these will either be set inside my_fixup_hashtable or
-+ * they will be copied out from parent inside zend_do_inheritance
-+ */
-+ dst->parent = NULL;
-+ dst->constructor = NULL;
-+ dst->destructor = NULL;
-+ dst->clone = NULL;
-+ dst->__get = NULL;
-+ dst->__set = NULL;
-+ dst->__unset = NULL;
-+ dst->__isset = NULL;
-+ dst->__call = NULL;
-+#ifdef ZEND_ENGINE_2_2
-+ dst->__tostring = NULL;
-+#endif
-+#ifdef ZEND_ENGINE_2_3
-+ dst->__callstatic = NULL;
-+#endif
-+
-+ /* unset function proxies */
-+ dst->serialize_func = NULL;
-+ dst->unserialize_func = NULL;
-+
-+ my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function, src, dst);
-+
-+#ifdef ZEND_ENGINE_2_4
-+ dst->default_properties_count = src->default_properties_count;
-+ if (src->default_properties_count) {
-+ CHECK(dst->default_properties_table = (zval**) apc_pool_alloc(pool, (sizeof(zval*) * src->default_properties_count)));
-+ for (i = 0; i < src->default_properties_count; i++) {
-+ if (src->default_properties_table[i]) {
-+ my_copy_zval_ptr(&dst->default_properties_table[i], (const zval**)&src->default_properties_table[i], ctxt TSRMLS_CC);
-+ } else {
-+ dst->default_properties_table[i] = NULL;
-+ }
-+ }
-+ } else {
-+ dst->default_properties_table = NULL;
-+ }
-+#else
-+ memset(&dst->default_properties, 0, sizeof(dst->default_properties));
-+ CHECK((my_copy_hashtable_ex(&dst->default_properties,
-+ &src->default_properties TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_default_property,
-+ src)));
-+#endif
-+
-+ CHECK((my_copy_hashtable_ex(&dst->properties_info,
-+ &src->properties_info TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_property_info,
-+ 0,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_property_info,
-+ src)));
-+
-+#ifdef ZEND_ENGINE_2_2
-+ /* php5.2 introduced a scope attribute for property info */
-+ my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst);
-+#endif
-+
-+#ifdef ZEND_ENGINE_2_4
-+ dst->default_static_members_count = src->default_static_members_count;
-+
-+ if (src->default_static_members_count) {
-+ CHECK(dst->default_static_members_table = (zval**) apc_pool_alloc(pool, (sizeof(zval*) * src->default_static_members_count)));
-+ for (i = 0; i < src->default_static_members_count; i++) {
-+ if (src->default_static_members_table[i]) {
-+ my_copy_zval_ptr(&dst->default_static_members_table[i], (const zval**)&src->default_static_members_table[i], ctxt TSRMLS_CC);
-+ } else {
-+ dst->default_static_members_table[i] = NULL;
-+ }
-+ }
-+ } else {
-+ dst->default_static_members_table = NULL;
-+ }
-+ dst->static_members_table = dst->default_static_members_table;
-+#else
-+ memset(&dst->default_static_members, 0, sizeof(dst->default_static_members));
-+ dst->static_members = NULL;
-+ CHECK(my_copy_hashtable_ex(&dst->default_static_members,
-+ &src->default_static_members TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_static_member,
-+ src,
-+ &src->default_static_members));
-+
-+ if(src->static_members != &src->default_static_members)
-+ {
-+ CHECK((dst->static_members = my_copy_hashtable_ex(NULL,
-+ src->static_members TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_static_member,
-+ src,
-+ src->static_members)));
-+ }
-+ else
-+ {
-+ dst->static_members = &dst->default_static_members;
-+ }
-+#endif
-+
-+ CHECK((my_copy_hashtable_ex(&dst->constants_table,
-+ &src->constants_table TSRMLS_CC,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt,
-+ (ht_check_copy_fun_t) my_check_copy_constant,
-+ src)));
-+
-+ if (src->type == ZEND_USER_CLASS && ZEND_CE_DOC_COMMENT(src)) {
-+ CHECK(ZEND_CE_DOC_COMMENT(dst) =
-+ apc_pmemcpy(ZEND_CE_DOC_COMMENT(src), (ZEND_CE_DOC_COMMENT_LEN(src) + 1), pool TSRMLS_CC));
-+ }
-+
-+ if (src->type == ZEND_INTERNAL_CLASS && ZEND_CE_BUILTIN_FUNCTIONS(src)) {
-+ int n;
-+
-+ for (n = 0; src->type == ZEND_INTERNAL_CLASS && ZEND_CE_BUILTIN_FUNCTIONS(src)[n].fname != NULL; n++) {}
-+
-+ CHECK((ZEND_CE_BUILTIN_FUNCTIONS(dst) =
-+ (zend_function_entry*) apc_pool_alloc(pool, ((n + 1) * sizeof(zend_function_entry)))));
-+
-+ for (i = 0; i < n; i++) {
-+ CHECK(my_copy_function_entry((zend_function_entry*)(&ZEND_CE_BUILTIN_FUNCTIONS(dst)[i]),
-+ &ZEND_CE_BUILTIN_FUNCTIONS(src)[i],
-+ ctxt TSRMLS_CC));
-+ }
-+ *(char**)&(ZEND_CE_BUILTIN_FUNCTIONS(dst)[n].fname) = NULL;
-+ }
-+
-+ if (src->type == ZEND_USER_CLASS && ZEND_CE_FILENAME(src)) {
-+ CHECK((ZEND_CE_FILENAME(dst) = apc_pstrdup(ZEND_CE_FILENAME(src), pool TSRMLS_CC)));
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_hashtable_ex */
-+static APC_HOTSPOT HashTable* my_copy_hashtable_ex(HashTable* dst,
-+ HashTable* src TSRMLS_DC,
-+ ht_copy_fun_t copy_fn,
-+ int holds_ptrs,
-+ apc_context_t* ctxt,
-+ ht_check_copy_fun_t check_fn,
-+ ...)
-+{
-+ Bucket* curr = NULL;
-+ Bucket* prev = NULL;
-+ Bucket* newp = NULL;
-+ int first = 1;
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (HashTable*) apc_pool_alloc(pool, sizeof(src[0])));
-+ }
-+
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ /* allocate buckets for the new hashtable */
-+ CHECK((dst->arBuckets = apc_pool_alloc(pool, (dst->nTableSize * sizeof(Bucket*)))));
-+
-+ memset(dst->arBuckets, 0, dst->nTableSize * sizeof(Bucket*));
-+ dst->pInternalPointer = NULL;
-+ dst->pListHead = NULL;
-+
-+ for (curr = src->pListHead; curr != NULL; curr = curr->pListNext) {
-+ int n = curr->h % dst->nTableSize;
-+
-+ if(check_fn) {
-+ va_list args;
-+ va_start(args, check_fn);
-+
-+ /* Call the check_fn to see if the current bucket
-+ * needs to be copied out
-+ */
-+ if(!check_fn(curr, args)) {
-+ dst->nNumOfElements--;
-+ va_end(args);
-+ continue;
-+ }
-+
-+ va_end(args);
-+ }
-+
-+ /* create a copy of the bucket 'curr' */
-+#ifdef ZEND_ENGINE_2_4
-+ if (!curr->nKeyLength) {
-+ CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC)));
-+ } else if (IS_INTERNED(curr->arKey)) {
-+ CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC)));
-+#ifndef ZTS
-+ } else if (pool->type != APC_UNPOOL) {
-+ char *arKey;
-+
-+ CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC)));
-+ arKey = apc_new_interned_string(curr->arKey, curr->nKeyLength TSRMLS_CC);
-+ if (!arKey) {
-+ CHECK((newp->arKey = (char*) apc_pmemcpy(curr->arKey, curr->nKeyLength, pool TSRMLS_CC)));
-+ } else {
-+ newp->arKey = arKey;
-+ }
-+#endif
-+ } else {
-+ CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC)));
-+ CHECK((newp->arKey = (char*) apc_pmemcpy(curr->arKey, curr->nKeyLength, pool TSRMLS_CC)));
-+ }
-+#else
-+ CHECK((newp = (Bucket*) apc_pmemcpy(curr,
-+ (sizeof(Bucket) + curr->nKeyLength - 1),
-+ pool TSRMLS_CC)));
-+#endif
-+
-+ /* insert 'newp' into the linked list at its hashed index */
-+ if (dst->arBuckets[n]) {
-+ newp->pNext = dst->arBuckets[n];
-+ newp->pLast = NULL;
-+ newp->pNext->pLast = newp;
-+ }
-+ else {
-+ newp->pNext = newp->pLast = NULL;
-+ }
-+
-+ dst->arBuckets[n] = newp;
-+
-+ /* copy the bucket data using our 'copy_fn' callback function */
-+ CHECK((newp->pData = copy_fn(NULL, curr->pData, ctxt TSRMLS_CC)));
-+
-+ if (holds_ptrs) {
-+ memcpy(&newp->pDataPtr, newp->pData, sizeof(void*));
-+ }
-+ else {
-+ newp->pDataPtr = NULL;
-+ }
-+
-+ /* insert 'newp' into the table-thread linked list */
-+ newp->pListLast = prev;
-+ newp->pListNext = NULL;
-+
-+ if (prev) {
-+ prev->pListNext = newp;
-+ }
-+
-+ if (first) {
-+ dst->pListHead = newp;
-+ first = 0;
-+ }
-+
-+ prev = newp;
-+ }
-+
-+ dst->pListTail = newp;
-+
-+ zend_hash_internal_pointer_reset(dst);
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ my_copy_static_variables */
-+static HashTable* my_copy_static_variables(zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ if (src->static_variables == NULL) {
-+ return NULL;
-+ }
-+
-+ return my_copy_hashtable(NULL,
-+ src->static_variables,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt);
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_zval */
-+zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_pool* pool = ctxt->pool;
-+ int usegc = (ctxt->copy == APC_COPY_OUT_OPCODE) || (ctxt->copy == APC_COPY_OUT_USER);
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ if(usegc) {
-+ ALLOC_ZVAL(dst);
-+ CHECK(dst);
-+ } else {
-+ CHECK(dst = (zval*) apc_pool_alloc(pool, sizeof(zval)));
-+ }
-+ }
-+
-+ CHECK(dst = my_copy_zval(dst, src, ctxt TSRMLS_CC));
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_fixup_op_array_jumps */
-+static void apc_fixup_op_array_jumps(zend_op_array *dst, zend_op_array *src )
-+{
-+ uint i;
-+
-+ for (i=0; i < dst->last; ++i) {
-+ zend_op *zo = &(dst->opcodes[i]);
-+ /*convert opline number to jump address*/
-+ switch (zo->opcode) {
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_GOTO:
-+#endif
-+ case ZEND_JMP:
-+ /*Note: if src->opcodes != dst->opcodes then we need to the opline according to src*/
-+#ifdef ZEND_ENGINE_2_4
-+ zo->op1.jmp_addr = dst->opcodes + (zo->op1.jmp_addr - src->opcodes);
-+#else
-+ zo->op1.u.jmp_addr = dst->opcodes + (zo->op1.u.jmp_addr - src->opcodes);
-+#endif
-+ break;
-+ case ZEND_JMPZ:
-+ case ZEND_JMPNZ:
-+ case ZEND_JMPZ_EX:
-+ case ZEND_JMPNZ_EX:
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_JMP_SET:
-+#endif
-+#ifdef ZEND_ENGINE_2_4
-+ case ZEND_JMP_SET_VAR:
-+#endif
-+#ifdef ZEND_ENGINE_2_4
-+ zo->op2.jmp_addr = dst->opcodes + (zo->op2.jmp_addr - src->opcodes);
-+#else
-+ zo->op2.u.jmp_addr = dst->opcodes + (zo->op2.u.jmp_addr - src->opcodes);
-+#endif
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_op_array */
-+zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ int i;
-+ apc_fileinfo_t *fileinfo = NULL;
-+ char canon_path[MAXPATHLEN];
-+ char *fullpath = NULL;
-+ apc_opflags_t * flags = NULL;
-+ apc_pool* pool = ctxt->pool;
-+
-+ assert(src != NULL);
-+
-+ if (!dst) {
-+ CHECK(dst = (zend_op_array*) apc_pool_alloc(pool, sizeof(src[0])));
-+ }
-+
-+ if(APCG(apc_optimize_function)) {
-+ APCG(apc_optimize_function)(src TSRMLS_CC);
-+ }
-+
-+ /* start with a bitwise copy of the array */
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ dst->function_name = NULL;
-+ dst->filename = NULL;
-+ dst->refcount = NULL;
-+ dst->opcodes = NULL;
-+ dst->brk_cont_array = NULL;
-+ dst->static_variables = NULL;
-+ dst->try_catch_array = NULL;
-+ dst->arg_info = NULL;
-+ dst->doc_comment = NULL;
-+#ifdef ZEND_ENGINE_2_1
-+ dst->vars = NULL;
-+#endif
-+
-+ /* copy the arg types array (if set) */
-+ if (src->arg_info) {
-+ CHECK(dst->arg_info = my_copy_arg_info_array(NULL,
-+ src->arg_info,
-+ src->num_args,
-+ ctxt TSRMLS_CC));
-+ }
-+
-+ if (src->function_name) {
-+ CHECK(dst->function_name = apc_pstrdup(src->function_name, pool TSRMLS_CC));
-+ }
-+ if (src->filename) {
-+ CHECK(dst->filename = apc_pstrdup(src->filename, pool TSRMLS_CC));
-+ }
-+
-+ CHECK(dst->refcount = apc_pmemcpy(src->refcount,
-+ sizeof(src->refcount[0]),
-+ pool TSRMLS_CC));
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (src->literals) {
-+ zend_literal *p, *q, *end;
-+
-+ q = src->literals;
-+ p = dst->literals = (zend_literal*) apc_pool_alloc(pool, (sizeof(zend_literal) * src->last_literal));
-+ end = p + src->last_literal;
-+ while (p < end) {
-+ *p = *q;
-+ my_copy_zval(&p->constant, &q->constant, ctxt TSRMLS_CC);
-+ p++;
-+ q++;
-+ }
-+ }
-+#endif
-+
-+ /* deep-copy the opcodes */
-+ CHECK(dst->opcodes = (zend_op*) apc_pool_alloc(pool, (sizeof(zend_op) * src->last)));
-+
-+ if(apc_reserved_offset != -1) {
-+ /* Insanity alert: the void* pointer is cast into an apc_opflags_t
-+ * struct. apc_zend_init() checks to ensure that it fits in a void* */
-+ flags = (apc_opflags_t*) & (dst->reserved[apc_reserved_offset]);
-+ memset(flags, 0, sizeof(apc_opflags_t));
-+ /* assert(sizeof(apc_opflags_t) <= sizeof(dst->reserved)); */
-+ }
-+
-+ for (i = 0; (uint) i < src->last; i++) {
-+ zend_op *zo = &(src->opcodes[i]);
-+ /* a lot of files are merely constant arrays with no jumps */
-+ switch (zo->opcode) {
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_GOTO:
-+#endif
-+ case ZEND_JMP:
-+ case ZEND_JMPZ:
-+ case ZEND_JMPNZ:
-+ case ZEND_JMPZ_EX:
-+ case ZEND_JMPNZ_EX:
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_JMP_SET:
-+#endif
-+#ifdef ZEND_ENGINE_2_4
-+ case ZEND_JMP_SET_VAR:
-+#endif
-+ if(flags != NULL) {
-+ flags->has_jumps = 1;
-+ }
-+ break;
-+ /* auto_globals_jit was not in php-4.3.* */
-+ case ZEND_FETCH_R:
-+ case ZEND_FETCH_W:
-+ case ZEND_FETCH_IS:
-+ case ZEND_FETCH_FUNC_ARG:
-+ case ZEND_FETCH_RW:
-+ case ZEND_FETCH_UNSET:
-+ if(PG(auto_globals_jit) && flags != NULL)
-+ {
-+ /* The fetch is only required if auto_globals_jit=1 */
-+#ifdef ZEND_ENGINE_2_4
-+ if((zo->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL &&
-+ zo->op1_type == IS_CONST &&
-+ Z_TYPE_P(zo->op1.zv) == IS_STRING) {
-+ if (Z_STRVAL_P(zo->op1.zv)[0] == '_') {
-+# define SET_IF_AUTOGLOBAL(member) \
-+ if(!strcmp(Z_STRVAL_P(zo->op1.zv), #member)) \
-+ flags->member = 1 /* no ';' here */
-+#else
-+ if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL &&
-+ zo->op1.op_type == IS_CONST &&
-+ zo->op1.u.constant.type == IS_STRING) {
-+ znode * varname = &zo->op1;
-+ if (varname->u.constant.value.str.val[0] == '_') {
-+# define SET_IF_AUTOGLOBAL(member) \
-+ if(!strcmp(varname->u.constant.value.str.val, #member)) \
-+ flags->member = 1 /* no ';' here */
-+#endif
-+ SET_IF_AUTOGLOBAL(_GET);
-+ else SET_IF_AUTOGLOBAL(_POST);
-+ else SET_IF_AUTOGLOBAL(_COOKIE);
-+ else SET_IF_AUTOGLOBAL(_SERVER);
-+ else SET_IF_AUTOGLOBAL(_ENV);
-+ else SET_IF_AUTOGLOBAL(_FILES);
-+ else SET_IF_AUTOGLOBAL(_REQUEST);
-+ else SET_IF_AUTOGLOBAL(_SESSION);
-+#ifdef ZEND_ENGINE_2_4
-+ else if(zend_is_auto_global(
-+ Z_STRVAL_P(zo->op1.zv),
-+ Z_STRLEN_P(zo->op1.zv)
-+ TSRMLS_CC))
-+#else
-+ else if(zend_is_auto_global(
-+ varname->u.constant.value.str.val,
-+ varname->u.constant.value.str.len
-+ TSRMLS_CC))
-+#endif
-+ {
-+ flags->unknown_global = 1;
-+ }
-+#ifdef ZEND_ENGINE_2_4
-+ } else SET_IF_AUTOGLOBAL(GLOBALS);
-+#else
-+ }
-+#endif
-+ }
-+ }
-+ break;
-+ case ZEND_RECV_INIT:
-+#ifdef ZEND_ENGINE_2_4
-+ if(zo->op2_type == IS_CONST &&
-+ Z_TYPE_P(zo->op2.zv) == IS_CONSTANT_ARRAY) {
-+#else
-+ if(zo->op2.op_type == IS_CONST &&
-+ zo->op2.u.constant.type == IS_CONSTANT_ARRAY) {
-+#endif
-+ if(flags != NULL) {
-+ flags->deep_copy = 1;
-+ }
-+ }
-+ break;
-+ default:
-+#ifdef ZEND_ENGINE_2_4
-+ if((zo->op1_type == IS_CONST &&
-+ Z_TYPE_P(zo->op1.zv) == IS_CONSTANT_ARRAY) ||
-+ (zo->op2_type == IS_CONST &&
-+ Z_TYPE_P(zo->op2.zv) == IS_CONSTANT_ARRAY)) {
-+#else
-+ if((zo->op1.op_type == IS_CONST &&
-+ zo->op1.u.constant.type == IS_CONSTANT_ARRAY) ||
-+ (zo->op2.op_type == IS_CONST &&
-+ zo->op2.u.constant.type == IS_CONSTANT_ARRAY)) {
-+#endif
-+ if(flags != NULL) {
-+ flags->deep_copy = 1;
-+ }
-+ }
-+ break;
-+ }
-+
-+ if(!(my_copy_zend_op(dst->opcodes+i, src->opcodes+i, ctxt TSRMLS_CC))) {
-+ return NULL;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (zo->op1_type == IS_CONST) {
-+ dst->opcodes[i].op1.literal = src->opcodes[i].op1.literal - src->literals + dst->literals;
-+ }
-+ if (zo->op2_type == IS_CONST) {
-+ dst->opcodes[i].op2.literal = src->opcodes[i].op2.literal - src->literals + dst->literals;
-+ }
-+ if (zo->result_type == IS_CONST) {
-+ dst->opcodes[i].result.literal = src->opcodes[i].result.literal - src->literals + dst->literals;
-+ }
-+#endif
-+
-+ /* This code breaks apc's rule#1 - cache what you compile */
-+ if((APCG(fpstat)==0) && APCG(canonicalize)) {
-+ /* not pool allocated, because the pool allocations eat up shm space */
-+ fileinfo = (apc_fileinfo_t*) apc_php_malloc(sizeof(apc_fileinfo_t) TSRMLS_CC);
-+#ifdef ZEND_ENGINE_2_4
-+ if((zo->opcode == ZEND_INCLUDE_OR_EVAL) &&
-+ (zo->op1_type == IS_CONST && Z_TYPE_P(zo->op1.zv) == IS_STRING)) {
-+ /* constant includes */
-+ if(!IS_ABSOLUTE_PATH(Z_STRVAL_P(zo->op1.zv),Z_STRLEN_P(zo->op1.zv))) {
-+ if (apc_search_paths(Z_STRVAL_P(zo->op1.zv), PG(include_path), fileinfo TSRMLS_CC) == 0) {
-+#else
-+ if((zo->opcode == ZEND_INCLUDE_OR_EVAL) &&
-+ (zo->op1.op_type == IS_CONST && zo->op1.u.constant.type == IS_STRING)) {
-+ /* constant includes */
-+ if(!IS_ABSOLUTE_PATH(Z_STRVAL_P(&zo->op1.u.constant),Z_STRLEN_P(&zo->op1.u.constant))) {
-+ if (apc_search_paths(Z_STRVAL_P(&zo->op1.u.constant), PG(include_path), fileinfo TSRMLS_CC) == 0) {
-+#endif
-+ if((fullpath = realpath(fileinfo->fullpath, canon_path))) {
-+ /* everything has to go through a realpath() */
-+ zend_op *dzo = &(dst->opcodes[i]);
-+#ifdef ZEND_ENGINE_2_4
-+ dzo->op1.literal = (zend_literal*) apc_pool_alloc(pool, sizeof(zend_literal));
-+ Z_STRLEN_P(dzo->op1.zv) = strlen(fullpath);
-+ Z_STRVAL_P(dzo->op1.zv) = apc_pstrdup(fullpath, pool TSRMLS_CC);
-+ Z_TYPE_P(dzo->op1.zv) = IS_STRING;
-+ Z_SET_REFCOUNT_P(dzo->op1.zv, 2);
-+ Z_SET_ISREF_P(dzo->op1.zv);
-+ dzo->op1.literal->hash_value = zend_hash_func(Z_STRVAL_P(dzo->op1.zv), Z_STRLEN_P(dzo->op1.zv)+1);
-+#else
-+ dzo->op1.u.constant.value.str.len = strlen(fullpath);
-+ dzo->op1.u.constant.value.str.val = apc_pstrdup(fullpath, pool TSRMLS_CC);
-+#endif
-+ }
-+ }
-+ }
-+ }
-+ apc_php_free(fileinfo TSRMLS_CC);
-+ }
-+ }
-+
-+ if(flags == NULL || flags->has_jumps) {
-+ apc_fixup_op_array_jumps(dst,src);
-+ }
-+
-+ /* copy the break-continue array */
-+ if (src->brk_cont_array) {
-+ CHECK(dst->brk_cont_array = apc_pmemcpy(src->brk_cont_array,
-+ sizeof(src->brk_cont_array[0]) * src->last_brk_cont,
-+ pool TSRMLS_CC));
-+ }
-+
-+ /* copy the table of static variables */
-+ if (src->static_variables) {
-+ CHECK(dst->static_variables = my_copy_static_variables(src, ctxt TSRMLS_CC));
-+ }
-+
-+ if (src->try_catch_array) {
-+ CHECK(dst->try_catch_array = apc_pmemcpy(src->try_catch_array,
-+ sizeof(src->try_catch_array[0]) * src->last_try_catch,
-+ pool TSRMLS_CC));
-+ }
-+
-+#ifdef ZEND_ENGINE_2_1 /* PHP 5.1 */
-+ if (src->vars) {
-+ CHECK(dst->vars = apc_pmemcpy(src->vars,
-+ sizeof(src->vars[0]) * src->last_var,
-+ pool TSRMLS_CC));
-+
-+ for(i = 0; i < src->last_var; i++) dst->vars[i].name = NULL;
-+
-+ for(i = 0; i < src->last_var; i++) {
-+ CHECK(dst->vars[i].name = apc_string_pmemcpy(src->vars[i].name,
-+ src->vars[i].name_len + 1,
-+ pool TSRMLS_CC));
-+ }
-+ }
-+#endif
-+
-+ if (src->doc_comment) {
-+ CHECK(dst->doc_comment
-+ = apc_pmemcpy(src->doc_comment, (src->doc_comment_len + 1), pool TSRMLS_CC));
-+ }
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+
-+/* {{{ apc_copy_new_functions */
-+apc_function_t* apc_copy_new_functions(int old_count, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_function_t* array;
-+ int new_count; /* number of new functions in table */
-+ int i;
-+ apc_pool* pool = ctxt->pool;
-+
-+ new_count = zend_hash_num_elements(CG(function_table)) - old_count;
-+ assert(new_count >= 0);
-+
-+ CHECK(array =
-+ (apc_function_t*)
-+ apc_pool_alloc(pool, (sizeof(apc_function_t) * (new_count + 1))));
-+
-+ if (new_count == 0) {
-+ array[0].function = NULL;
-+ return array;
-+ }
-+
-+ /* Skip the first `old_count` functions in the table */
-+ zend_hash_internal_pointer_reset(CG(function_table));
-+ for (i = 0; i < old_count; i++) {
-+ zend_hash_move_forward(CG(function_table));
-+ }
-+
-+ /* Add the next `new_count` functions to our array */
-+ for (i = 0; i < new_count; i++) {
-+ char* key;
-+ uint key_size;
-+ zend_function* fun;
-+
-+ zend_hash_get_current_key_ex(CG(function_table),
-+ &key,
-+ &key_size,
-+ NULL,
-+ 0,
-+ NULL);
-+
-+ zend_hash_get_current_data(CG(function_table), (void**) &fun);
-+
-+ CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool TSRMLS_CC));
-+ array[i].name_len = (int) key_size-1;
-+ CHECK(array[i].function = my_copy_function(NULL, fun, ctxt TSRMLS_CC));
-+ zend_hash_move_forward(CG(function_table));
-+ }
-+
-+ array[i].function = NULL;
-+ return array;
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_new_classes */
-+apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t *ctxt TSRMLS_DC)
-+{
-+ apc_class_t* array;
-+ int new_count; /* number of new classes in table */
-+ int i;
-+ apc_pool* pool = ctxt->pool;
-+
-+ new_count = zend_hash_num_elements(CG(class_table)) - old_count;
-+ assert(new_count >= 0);
-+
-+ CHECK(array =
-+ (apc_class_t*)
-+ apc_pool_alloc(pool, (sizeof(apc_class_t) * (new_count + 1))));
-+
-+ if (new_count == 0) {
-+ array[0].class_entry = NULL;
-+ return array;
-+ }
-+
-+ /* Skip the first `old_count` classes in the table */
-+ zend_hash_internal_pointer_reset(CG(class_table));
-+ for (i = 0; i < old_count; i++) {
-+ zend_hash_move_forward(CG(class_table));
-+ }
-+
-+ /* Add the next `new_count` classes to our array */
-+ for (i = 0; i < new_count; i++) {
-+ char* key;
-+ uint key_size;
-+ zend_class_entry* elem = NULL;
-+
-+ array[i].class_entry = NULL;
-+
-+ zend_hash_get_current_key_ex(CG(class_table),
-+ &key,
-+ &key_size,
-+ NULL,
-+ 0,
-+ NULL);
-+
-+ zend_hash_get_current_data(CG(class_table), (void**) &elem);
-+
-+
-+ elem = *((zend_class_entry**)elem);
-+
-+ CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool TSRMLS_CC));
-+ array[i].name_len = (int) key_size-1;
-+ CHECK(array[i].class_entry = my_copy_class_entry(NULL, elem, ctxt TSRMLS_CC));
-+
-+ /*
-+ * If the class has a pointer to its parent class, save the parent
-+ * name so that we can enable compile-time inheritance when we reload
-+ * the child class; otherwise, set the parent name to null and scan
-+ * the op_array to determine if this class inherits from some base
-+ * class at execution-time.
-+ */
-+
-+ if (elem->parent) {
-+ CHECK(array[i].parent_name = apc_pstrdup(elem->parent->name, pool TSRMLS_CC));
-+ }
-+ else {
-+ array[i].parent_name = NULL;
-+ }
-+
-+ zend_hash_move_forward(CG(class_table));
-+ }
-+
-+ array[i].class_entry = NULL;
-+ return array;
-+}
-+/* }}} */
-+
-+/* Used only by my_prepare_op_array_for_execution */
-+#ifdef ZEND_ENGINE_2_4
-+# define APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION() \
-+ /* The fetch is only required if auto_globals_jit=1 */ \
-+ if((zo->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL && \
-+ zo->op1_type == IS_CONST && \
-+ Z_TYPE_P(zo->op1.zv) == IS_STRING && \
-+ Z_STRVAL_P(zo->op1.zv)[0] == '_') { \
-+ (void)zend_is_auto_global(Z_STRVAL_P(zo->op1.zv), \
-+ Z_STRLEN_P(zo->op1.zv) \
-+ TSRMLS_CC); \
-+ }
-+#else
-+# define APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION() \
-+ /* The fetch is only required if auto_globals_jit=1 */ \
-+ if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL && \
-+ zo->op1.op_type == IS_CONST && \
-+ zo->op1.u.constant.type == IS_STRING && \
-+ zo->op1.u.constant.value.str.val[0] == '_') { \
-+ \
-+ znode* varname = &zo->op1; \
-+ (void)zend_is_auto_global(varname->u.constant.value.str.val, \
-+ varname->u.constant.value.str.len \
-+ TSRMLS_CC); \
-+ }
-+#endif
-+
-+/* {{{ my_prepare_op_array_for_execution */
-+static int my_prepare_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ /* combine my_fetch_global_vars and my_copy_data_exceptions.
-+ * - Pre-fetch superglobals which would've been pre-fetched in parse phase.
-+ * - If the opcode stream contain mutable data, ensure a copy.
-+ * - Fixup array jumps in the same loop.
-+ */
-+ int i=src->last;
-+ zend_op *zo;
-+ zend_op *dzo;
-+ apc_opflags_t * flags = apc_reserved_offset != -1 ?
-+ (apc_opflags_t*) & (src->reserved[apc_reserved_offset]) : NULL;
-+ int needcopy = flags ? flags->deep_copy : 1;
-+ /* auto_globals_jit was not in php4 */
-+ int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global);
-+
-+#define FETCH_AUTOGLOBAL(member) do { \
-+ if(flags && flags->member == 1) { \
-+ zend_is_auto_global(#member,\
-+ (sizeof(#member) - 1)\
-+ TSRMLS_CC);\
-+ } \
-+} while(0);
-+
-+ FETCH_AUTOGLOBAL(_GET);
-+ FETCH_AUTOGLOBAL(_POST);
-+ FETCH_AUTOGLOBAL(_COOKIE);
-+ FETCH_AUTOGLOBAL(_SERVER);
-+ FETCH_AUTOGLOBAL(_ENV);
-+ FETCH_AUTOGLOBAL(_FILES);
-+ FETCH_AUTOGLOBAL(_REQUEST);
-+ FETCH_AUTOGLOBAL(_SESSION);
-+#ifdef ZEND_ENGINE_2_4
-+ FETCH_AUTOGLOBAL(GLOBALS);
-+#endif
-+
-+ if(needcopy) {
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (src->literals) {
-+ zend_literal *p, *q, *end;
-+
-+ q = src->literals;
-+ p = dst->literals = (zend_literal*) apc_xmemcpy(src->literals,
-+ sizeof(zend_literal) * src->last_literal,
-+ apc_php_malloc TSRMLS_CC);
-+ end = p + src->last_literal;
-+ while (p < end) {
-+ if (Z_TYPE(q->constant) == IS_CONSTANT_ARRAY) {
-+ my_copy_zval(&p->constant, &q->constant, ctxt TSRMLS_CC);
-+ }
-+ p++;
-+ q++;
-+ }
-+ }
-+#endif
-+
-+ dst->opcodes = (zend_op*) apc_xmemcpy(src->opcodes,
-+ sizeof(zend_op) * src->last,
-+ apc_php_malloc TSRMLS_CC);
-+ zo = src->opcodes;
-+ dzo = dst->opcodes;
-+ while(i > 0) {
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if(zo->op1_type == IS_CONST) {
-+ dzo->op1.literal = zo->op1.literal - src->literals + dst->literals;
-+ }
-+ if(zo->op2_type == IS_CONST) {
-+ dzo->op2.literal = zo->op2.literal - src->literals + dst->literals;
-+ }
-+ if(zo->result_type == IS_CONST) {
-+ dzo->result.literal = zo->result.literal - src->literals + dst->literals;
-+ }
-+#else
-+ if( ((zo->op1.op_type == IS_CONST &&
-+ zo->op1.u.constant.type == IS_CONSTANT_ARRAY)) ||
-+ ((zo->op2.op_type == IS_CONST &&
-+ zo->op2.u.constant.type == IS_CONSTANT_ARRAY))) {
-+
-+ if(!(my_copy_zend_op(dzo, zo, ctxt TSRMLS_CC))) {
-+ assert(0); /* emalloc failed or a bad constant array */
-+ }
-+ }
-+#endif
-+
-+ switch(zo->opcode) {
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_GOTO:
-+#endif
-+ case ZEND_JMP:
-+#ifdef ZEND_ENGINE_2_4
-+ dzo->op1.jmp_addr = dst->opcodes +
-+ (zo->op1.jmp_addr - src->opcodes);
-+#else
-+ dzo->op1.u.jmp_addr = dst->opcodes +
-+ (zo->op1.u.jmp_addr - src->opcodes);
-+#endif
-+ break;
-+ case ZEND_JMPZ:
-+ case ZEND_JMPNZ:
-+ case ZEND_JMPZ_EX:
-+ case ZEND_JMPNZ_EX:
-+#ifdef ZEND_ENGINE_2_3
-+ case ZEND_JMP_SET:
-+#endif
-+#ifdef ZEND_ENGINE_2_4
-+ case ZEND_JMP_SET_VAR:
-+#endif
-+#ifdef ZEND_ENGINE_2_4
-+ dzo->op2.jmp_addr = dst->opcodes +
-+ (zo->op2.jmp_addr - src->opcodes);
-+#else
-+ dzo->op2.u.jmp_addr = dst->opcodes +
-+ (zo->op2.u.jmp_addr - src->opcodes);
-+#endif
-+ break;
-+ case ZEND_FETCH_R:
-+ case ZEND_FETCH_W:
-+ case ZEND_FETCH_IS:
-+ case ZEND_FETCH_FUNC_ARG:
-+ if(do_prepare_fetch_global)
-+ {
-+ APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ i--;
-+ zo++;
-+ dzo++;
-+ }
-+ } else { /* !needcopy */
-+ /* The fetch is only required if auto_globals_jit=1 */
-+ if(do_prepare_fetch_global)
-+ {
-+ zo = src->opcodes;
-+ while(i > 0) {
-+
-+ if(zo->opcode == ZEND_FETCH_R ||
-+ zo->opcode == ZEND_FETCH_W ||
-+ zo->opcode == ZEND_FETCH_IS ||
-+ zo->opcode == ZEND_FETCH_FUNC_ARG
-+ ) {
-+ APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
-+ }
-+
-+ i--;
-+ zo++;
-+ }
-+ }
-+ }
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_op_array_for_execution */
-+zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ if(dst == NULL) {
-+ dst = (zend_op_array*) emalloc(sizeof(src[0]));
-+ }
-+ memcpy(dst, src, sizeof(src[0]));
-+ dst->static_variables = my_copy_static_variables(src, ctxt TSRMLS_CC);
-+
-+ /* memory leak */
-+ dst->refcount = apc_pmemcpy(src->refcount,
-+ sizeof(src->refcount[0]),
-+ ctxt->pool TSRMLS_CC);
-+
-+ my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC);
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_function_for_execution */
-+zend_function* apc_copy_function_for_execution(zend_function* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ zend_function* dst;
-+
-+ dst = (zend_function*) emalloc(sizeof(src[0]));
-+ memcpy(dst, src, sizeof(src[0]));
-+ apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC);
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_function_for_execution_ex */
-+zend_function* apc_copy_function_for_execution_ex(void *dummy, zend_function* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+ if(src->type==ZEND_INTERNAL_FUNCTION || src->type==ZEND_OVERLOADED_FUNCTION) return src;
-+ return apc_copy_function_for_execution(src, ctxt TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_copy_class_entry_for_execution */
-+zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC)
-+{
-+#ifdef ZEND_ENGINE_2_4
-+ int i;
-+#endif
-+ zend_class_entry* dst = (zend_class_entry*) apc_pool_alloc(ctxt->pool, sizeof(src[0]));
-+ memcpy(dst, src, sizeof(src[0]));
-+
-+ if(src->num_interfaces)
-+ {
-+ /* These are slots to be populated later by ADD_INTERFACE insns */
-+ dst->interfaces = apc_php_malloc(
-+ (sizeof(zend_class_entry*) * src->num_interfaces) TSRMLS_CC);
-+ memset(dst->interfaces, 0,
-+ sizeof(zend_class_entry*) * src->num_interfaces);
-+ }
-+ else
-+ {
-+ /* assert(dst->interfaces == NULL); */
-+ }
-+
-+ /* Deep-copy the class properties, because they will be modified */
-+
-+#ifdef ZEND_ENGINE_2_4
-+ dst->name = apc_string_pmemcpy((char*)src->name, src->name_length+1, ctxt->pool TSRMLS_CC);
-+ dst->default_properties_count = src->default_properties_count;
-+ if (src->default_properties_count) {
-+ dst->default_properties_table = (zval**) apc_php_malloc((sizeof(zval*) * src->default_properties_count) TSRMLS_CC);
-+ for (i = 0; i < src->default_properties_count; i++) {
-+ if (src->default_properties_table[i]) {
-+ my_copy_zval_ptr(&dst->default_properties_table[i], (const zval**)&src->default_properties_table[i], ctxt TSRMLS_CC);
-+ } else {
-+ dst->default_properties_table[i] = NULL;
-+ }
-+ }
-+ } else {
-+ dst->default_properties_table = NULL;
-+ }
-+#else
-+ my_copy_hashtable(&dst->default_properties,
-+ &src->default_properties,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt);
-+#endif
-+
-+ /* For derived classes, we must also copy the function hashtable (although
-+ * we can merely bitwise copy the functions it contains) */
-+
-+ my_copy_hashtable(&dst->function_table,
-+ &src->function_table,
-+ (ht_copy_fun_t) apc_copy_function_for_execution_ex,
-+ 0,
-+ ctxt);
-+
-+ my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function_for_execution, src, dst);
-+
-+ /* zend_do_inheritance merges properties_info.
-+ * Need only shallow copying as it doesn't hold the pointers.
-+ */
-+ my_copy_hashtable(&dst->properties_info,
-+ &src->properties_info,
-+ (ht_copy_fun_t) my_copy_property_info_for_execution,
-+ 0,
-+ ctxt);
-+
-+#ifdef ZEND_ENGINE_2_2
-+ /* php5.2 introduced a scope attribute for property info */
-+ my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst);
-+#endif
-+
-+ /* if inheritance results in a hash_del, it might result in
-+ * a pefree() of the pointers here. Deep copying required.
-+ */
-+
-+ my_copy_hashtable(&dst->constants_table,
-+ &src->constants_table,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt);
-+
-+#ifdef ZEND_ENGINE_2_4
-+ dst->default_static_members_count = src->default_static_members_count;
-+ if (src->default_static_members_count) {
-+ dst->default_static_members_table = (zval**) apc_php_malloc((sizeof(zval*) * src->default_static_members_count) TSRMLS_CC);
-+ for (i = 0; i < src->default_static_members_count; i++) {
-+ if (src->default_static_members_table[i]) {
-+ my_copy_zval_ptr(&dst->default_static_members_table[i], (const zval**)&src->default_static_members_table[i], ctxt TSRMLS_CC);
-+ } else {
-+ dst->default_static_members_table[i] = NULL;
-+ }
-+ }
-+ } else {
-+ dst->default_static_members_table = NULL;
-+ }
-+ dst->static_members_table = dst->default_static_members_table;
-+#else
-+ my_copy_hashtable(&dst->default_static_members,
-+ &src->default_static_members,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt);
-+
-+ if(src->static_members != &(src->default_static_members))
-+ {
-+ dst->static_members = my_copy_hashtable(NULL,
-+ src->static_members,
-+ (ht_copy_fun_t) my_copy_zval_ptr,
-+ 1,
-+ ctxt);
-+ }
-+ else
-+ {
-+ dst->static_members = &(dst->default_static_members);
-+ }
-+#endif
-+
-+ return dst;
-+}
-+/* }}} */
-+
-+/* {{{ apc_free_class_entry_after_execution */
-+void apc_free_class_entry_after_execution(zend_class_entry* src TSRMLS_DC)
-+{
-+ if(src->num_interfaces > 0 && src->interfaces) {
-+ apc_php_free(src->interfaces TSRMLS_CC);
-+ src->interfaces = NULL;
-+ src->num_interfaces = 0;
-+ }
-+ /* my_destroy_hashtable() does not play nice with refcounts */
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (src->default_static_members_table) {
-+ int i;
-+
-+ for (i = 0; i < src->default_static_members_count; i++) {
-+ zval_ptr_dtor(&src->default_static_members_table[i]);
-+ }
-+ efree(src->default_static_members_table);
-+ src->default_static_members_table = NULL;
-+ }
-+ src->static_members_table = NULL;
-+ if (src->default_properties_table) {
-+ int i;
-+
-+ for (i = 0; i < src->default_properties_count; i++) {
-+ if (src->default_properties_table[i]) {
-+ zval_ptr_dtor(&src->default_properties_table[i]);
-+ }
-+ }
-+ efree(src->default_properties_table);
-+ src->default_properties_table = NULL;
-+ }
-+#else
-+ zend_hash_clean(&src->default_static_members);
-+ if(src->static_members != &(src->default_static_members))
-+ {
-+ zend_hash_destroy(src->static_members);
-+ apc_php_free(src->static_members TSRMLS_CC);
-+ src->static_members = NULL;
-+ }
-+ else
-+ {
-+ src->static_members = NULL;
-+ }
-+
-+ zend_hash_clean(&src->default_properties);
-+#endif
-+ zend_hash_clean(&src->constants_table);
-+
-+ /* TODO: more cleanup */
-+}
-+/* }}} */
-+
-+/* {{{ apc_file_halt_offset */
-+long apc_file_halt_offset(const char *filename TSRMLS_DC)
-+{
-+ zend_constant *c;
-+ char *name;
-+ int len;
-+ char haltoff[] = "__COMPILER_HALT_OFFSET__";
-+ long value = -1;
-+
-+ zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, filename, strlen(filename), 0);
-+
-+ if (zend_hash_find(EG(zend_constants), name, len+1, (void **) &c) == SUCCESS) {
-+ value = Z_LVAL(c->value);
-+ }
-+
-+ pefree(name, 0);
-+
-+ return value;
-+}
-+/* }}} */
-+
-+/* {{{ apc_do_halt_compiler_register */
-+void apc_do_halt_compiler_register(const char *filename, long halt_offset TSRMLS_DC)
-+{
-+ char *name;
-+ char haltoff[] = "__COMPILER_HALT_OFFSET__";
-+ int len;
-+
-+ if(halt_offset > 0) {
-+
-+ zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1,
-+ filename, strlen(filename), 0);
-+
-+ zend_register_long_constant(name, len+1, halt_offset, CONST_CS, 0 TSRMLS_CC);
-+
-+ pefree(name, 0);
-+ }
-+}
-+/* }}} */
-+
-+
-+
-+/* {{{ my_fixup_function */
-+static void my_fixup_function(Bucket *p, zend_class_entry *src, zend_class_entry *dst)
-+{
-+ zend_function* zf = p->pData;
-+
-+ #define SET_IF_SAME_NAME(member) \
-+ do { \
-+ if(src->member && !strcmp(zf->common.function_name, src->member->common.function_name)) { \
-+ dst->member = zf; \
-+ } \
-+ } \
-+ while(0)
-+
-+ if(zf->common.scope == src)
-+ {
-+
-+ /* Fixing up the default functions for objects here since
-+ * we need to compare with the newly allocated functions
-+ *
-+ * caveat: a sub-class method can have the same name as the
-+ * parent's constructor and create problems.
-+ */
-+
-+ if(zf->common.fn_flags & ZEND_ACC_CTOR) dst->constructor = zf;
-+ else if(zf->common.fn_flags & ZEND_ACC_DTOR) dst->destructor = zf;
-+ else if(zf->common.fn_flags & ZEND_ACC_CLONE) dst->clone = zf;
-+ else
-+ {
-+ SET_IF_SAME_NAME(__get);
-+ SET_IF_SAME_NAME(__set);
-+ SET_IF_SAME_NAME(__unset);
-+ SET_IF_SAME_NAME(__isset);
-+ SET_IF_SAME_NAME(__call);
-+#ifdef ZEND_ENGINE_2_2
-+ SET_IF_SAME_NAME(__tostring);
-+#endif
-+#ifdef ZEND_ENGINE_2_3
-+ SET_IF_SAME_NAME(__callstatic);
-+#endif
-+ }
-+ zf->common.scope = dst;
-+ }
-+ else
-+ {
-+ /* no other function should reach here */
-+ assert(0);
-+ }
-+
-+ #undef SET_IF_SAME_NAME
-+}
-+/* }}} */
-+
-+#ifdef ZEND_ENGINE_2_2
-+/* {{{ my_fixup_property_info */
-+static void my_fixup_property_info(Bucket *p, zend_class_entry *src, zend_class_entry *dst)
-+{
-+ zend_property_info* property_info = (zend_property_info*)p->pData;
-+
-+ if(property_info->ce == src)
-+ {
-+ property_info->ce = dst;
-+ }
-+ else
-+ {
-+ assert(0); /* should never happen */
-+ }
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ my_fixup_hashtable */
-+static void my_fixup_hashtable(HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst)
-+{
-+ Bucket *p;
-+ uint i;
-+
-+ for (i = 0; i < ht->nTableSize; i++) {
-+ if(!ht->arBuckets) break;
-+ p = ht->arBuckets[i];
-+ while (p != NULL) {
-+ fixup(p, src, dst);
-+ p = p->pNext;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+
-+/* {{{ my_check_copy_function */
-+static int my_check_copy_function(Bucket* p, va_list args)
-+{
-+ zend_class_entry* src = va_arg(args, zend_class_entry*);
-+ zend_function* zf = (zend_function*)p->pData;
-+
-+ return (zf->common.scope == src);
-+}
-+/* }}} */
-+
-+#ifndef ZEND_ENGINE_2_4
-+/* {{{ my_check_copy_default_property */
-+static int my_check_copy_default_property(Bucket* p, va_list args)
-+{
-+ zend_class_entry* src = va_arg(args, zend_class_entry*);
-+ zend_class_entry* parent = src->parent;
-+ zval ** child_prop = (zval**)p->pData;
-+ zval ** parent_prop = NULL;
-+
-+ if (parent &&
-+ zend_hash_quick_find(&parent->default_properties, p->arKey,
-+ p->nKeyLength, p->h, (void **) &parent_prop)==SUCCESS) {
-+
-+ if((parent_prop && child_prop) && (*parent_prop) == (*child_prop))
-+ {
-+ return 0;
-+ }
-+ }
-+
-+ /* possibly not in the parent */
-+ return 1;
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ my_check_copy_property_info */
-+static int my_check_copy_property_info(Bucket* p, va_list args)
-+{
-+ zend_class_entry* src = va_arg(args, zend_class_entry*);
-+ zend_class_entry* parent = src->parent;
-+ zend_property_info* child_info = (zend_property_info*)p->pData;
-+ zend_property_info* parent_info = NULL;
-+
-+#ifdef ZEND_ENGINE_2_2
-+ /* so much easier */
-+ return (child_info->ce == src);
-+#endif
-+
-+ if (parent &&
-+ zend_hash_quick_find(&parent->properties_info, p->arKey, p->nKeyLength,
-+ p->h, (void **) &parent_info)==SUCCESS) {
-+ if(parent_info->flags & ZEND_ACC_PRIVATE)
-+ {
-+ return 1;
-+ }
-+ if((parent_info->flags & ZEND_ACC_PPP_MASK) !=
-+ (child_info->flags & ZEND_ACC_PPP_MASK))
-+ {
-+ /* TODO: figure out whether ACC_CHANGED is more appropriate
-+ * here */
-+ return 1;
-+ }
-+ return 0;
-+ }
-+
-+ /* property doesn't exist in parent, copy into cached child */
-+ return 1;
-+}
-+/* }}} */
-+
-+#ifndef ZEND_ENGINE_2_4
-+/* {{{ my_check_copy_static_member */
-+static int my_check_copy_static_member(Bucket* p, va_list args)
-+{
-+ zend_class_entry* src = va_arg(args, zend_class_entry*);
-+ HashTable * ht = va_arg(args, HashTable*);
-+ zend_class_entry* parent = src->parent;
-+ HashTable * parent_ht = NULL;
-+ char * member_name;
-+ char * class_name = NULL;
-+
-+ zend_property_info *parent_info = NULL;
-+ zend_property_info *child_info = NULL;
-+ zval ** parent_prop = NULL;
-+ zval ** child_prop = (zval**)(p->pData);
-+
-+ if(!parent) {
-+ return 1;
-+ }
-+
-+ /* these do not need free'ing */
-+#ifdef ZEND_ENGINE_2_2
-+ zend_unmangle_property_name(p->arKey, p->nKeyLength-1, &class_name, &member_name);
-+#else
-+ zend_unmangle_property_name(p->arKey, &class_name, &member_name);
-+#endif
-+
-+ /* please refer do_inherit_property_access_check in zend_compile.c
-+ * to understand why we lookup in properties_info.
-+ */
-+ if((zend_hash_find(&parent->properties_info, member_name,
-+ strlen(member_name)+1, (void**)&parent_info) == SUCCESS)
-+ &&
-+ (zend_hash_find(&src->properties_info, member_name,
-+ strlen(member_name)+1, (void**)&child_info) == SUCCESS))
-+ {
-+ if(ht == &(src->default_static_members))
-+ {
-+ parent_ht = &parent->default_static_members;
-+ }
-+ else
-+ {
-+ parent_ht = parent->static_members;
-+ }
-+
-+ if(zend_hash_quick_find(parent_ht, p->arKey,
-+ p->nKeyLength, p->h, (void**)&parent_prop) == SUCCESS)
-+ {
-+ /* they point to the same zval */
-+ if(*parent_prop == *child_prop)
-+ {
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ return 1;
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ my_check_copy_constant */
-+static int my_check_copy_constant(Bucket* p, va_list args)
-+{
-+ zend_class_entry* src = va_arg(args, zend_class_entry*);
-+ zend_class_entry* parent = src->parent;
-+ zval ** child_const = (zval**)p->pData;
-+ zval ** parent_const = NULL;
-+
-+ if (parent &&
-+ zend_hash_quick_find(&parent->constants_table, p->arKey,
-+ p->nKeyLength, p->h, (void **) &parent_const)==SUCCESS) {
-+
-+ if((parent_const && child_const) && (*parent_const) == (*child_const))
-+ {
-+ return 0;
-+ }
-+ }
-+
-+ /* possibly not in the parent */
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_register_optimizer(apc_optimize_function_t optimizer)
-+ * register a optimizer callback function, returns the previous callback
-+ */
-+apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC) {
-+ apc_optimize_function_t old_optimizer = APCG(apc_optimize_function);
-+ APCG(apc_optimize_function) = optimizer;
-+ return old_optimizer;
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_compile.h b/ext/apc/apc_compile.h
---- a/ext/apc/apc_compile.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_compile.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,152 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_compile.h 307185 2011-01-06 21:13:11Z gopalv $ */
-+
-+#ifndef APC_COMPILE_H
-+#define APC_COMPILE_H
-+
-+/*
-+ * This module encapsulates most of the complexity involved in deep-copying
-+ * the Zend compiler data structures. The routines are allocator-agnostic, so
-+ * the same function can be used for copying to and from shared memory.
-+ */
-+
-+#include "apc.h"
-+#include "apc_php.h"
-+#include "apc_main.h"
-+#include "apc_serializer.h"
-+
-+/* {{{ struct definition: apc_function_t */
-+typedef struct apc_function_t apc_function_t;
-+struct apc_function_t {
-+ char* name; /* the function name */
-+ int name_len; /* length of name */
-+ zend_function* function; /* the zend function data structure */
-+};
-+/* }}} */
-+
-+/* {{{ struct definition: apc_class_t */
-+typedef struct apc_class_t apc_class_t;
-+struct apc_class_t {
-+ char* name; /* the class name */
-+ int name_len; /* length of name */
-+ char* parent_name; /* the parent class name */
-+ zend_class_entry* class_entry; /* the zend class data structure */
-+};
-+/* }}} */
-+
-+/* {{{ struct definition: apc_opflags_t */
-+typedef struct apc_opflags_t apc_opflags_t;
-+struct apc_opflags_t {
-+ unsigned int has_jumps : 1; /* has jump offsets */
-+ unsigned int deep_copy : 1; /* needs deep copy */
-+
-+ /* autoglobal bits */
-+ unsigned int _POST : 1;
-+ unsigned int _GET : 1;
-+ unsigned int _COOKIE : 1;
-+ unsigned int _SERVER : 1;
-+ unsigned int _ENV : 1;
-+ unsigned int _FILES : 1;
-+ unsigned int _REQUEST : 1;
-+ unsigned int _SESSION : 1;
-+#ifdef ZEND_ENGINE_2_4
-+ unsigned int GLOBALS : 1;
-+#endif
-+ unsigned int unknown_global : 1;
-+};
-+/* }}} */
-+
-+/*
-+ * These are the top-level copy functions.
-+ */
-+
-+extern zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC);
-+extern zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC);
-+extern apc_function_t* apc_copy_new_functions(int old_count, apc_context_t* ctxt TSRMLS_DC);
-+extern apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t* ctxt TSRMLS_DC);
-+extern zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC);
-+
-+#if 0
-+/*
-+ * Deallocation functions corresponding to the copy functions above.
-+ */
-+
-+extern void apc_free_op_array(zend_op_array* src, apc_context_t* ctxt);
-+extern void apc_free_functions(apc_function_t* src, apc_context_t* ctxt);
-+extern void apc_free_classes(apc_class_t* src, apc_context_t* ctxt);
-+extern void apc_free_zval(zval* src, apc_context_t* ctxt);
-+#endif
-+
-+/*
-+ * These "copy-for-execution" functions must be called after retrieving an
-+ * object from the shared cache. They do the minimal amount of work necessary
-+ * to allow multiple processes to concurrently execute the same VM data
-+ * structures.
-+ */
-+
-+extern zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC);
-+extern zend_function* apc_copy_function_for_execution(zend_function* src, apc_context_t* ctxt TSRMLS_DC);
-+extern zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC);
-+
-+/*
-+ * The "free-after-execution" function performs a cursory clean up of the class data
-+ * This is required to minimize memory leak warnings and to ensure correct destructor
-+ * ordering of some variables.
-+ */
-+extern void apc_free_class_entry_after_execution(zend_class_entry* src TSRMLS_DC);
-+
-+/*
-+ * Optimization callback definition and registration function.
-+ */
-+typedef zend_op_array* (*apc_optimize_function_t) (zend_op_array* TSRMLS_DC);
-+extern apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC);
-+
-+/*
-+ * To handle __COMPILER_HALT_OFFSET__
-+ */
-+long apc_file_halt_offset(const char* filename TSRMLS_DC);
-+void apc_do_halt_compiler_register(const char *filename, long halt_offset TSRMLS_DC);
-+
-+/*
-+ * apc serialization functions
-+ */
-+int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS);
-+int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS);
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_debug.c b/ext/apc/apc_debug.c
---- a/ext/apc/apc_debug.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_debug.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+*/
-+
-+/* $Id: apc_debug.c 307048 2011-01-03 23:53:17Z kalle $ */
-+#include "apc.h"
-+#include <stdio.h>
-+#include "zend.h"
-+#include "zend_compile.h"
-+
-+#if defined(__DEBUG_APC__)
-+
-+/* keep track of vld_dump_oparray() signature */
-+typedef void (*vld_dump_f) (zend_op_array * TSRMLS_DC);
-+
-+#endif
-+
-+void dump(zend_op_array *op_array TSRMLS_DC)
-+{
-+#if defined(__DEBUG_APC__)
-+ vld_dump_f dump_op_array;
-+ DL_HANDLE handle = NULL;
-+
-+#ifdef PHP_WIN32
-+ handle = GetModuleHandle(NULL);
-+
-+ if (!handle) {
-+ apc_warning("unable to fetch current module handle." TSRMLS_CC);
-+ }
-+#endif
-+
-+ dump_op_array = (vld_dump_f) DL_FETCH_SYMBOL(handle, "vld_dump_oparray");
-+
-+#ifdef PHP_WIN32
-+ DL_UNLOAD(handle);
-+#endif
-+
-+ if(dump_op_array) {
-+ dump_op_array(op_array TSRMLS_CC);
-+
-+ return;
-+ }
-+
-+ apc_warning("vld is not installed or something even worse." TSRMLS_CC);
-+#endif
-+}
-diff -Naur a/ext/apc/apc_debug.h b/ext/apc/apc_debug.h
---- a/ext/apc/apc_debug.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_debug.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,29 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+*/
-+
-+void dump(zend_op_array * TSRMLS_DC);
-diff -Naur a/ext/apc/apc_fcntl.c b/ext/apc/apc_fcntl.c
---- a/ext/apc/apc_fcntl.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_fcntl.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,123 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_fcntl.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc.h"
-+
-+#ifdef APC_FCNTL_LOCKS
-+
-+#include "apc_fcntl.h"
-+#include <unistd.h>
-+#include <fcntl.h>
-+
-+int apc_fcntl_create(const char* pathname TSRMLS_DC)
-+{
-+ int fd;
-+ if(pathname == NULL) {
-+ char lock_path[] = "/tmp/.apc.XXXXXX";
-+ mktemp(lock_path);
-+ fd = open(lock_path, O_RDWR|O_CREAT, 0666);
-+ if(fd > 0 ) {
-+ unlink(lock_path);
-+ return fd;
-+ } else {
-+ apc_error("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:" TSRMLS_CC, lock_path);
-+ return -1;
-+ }
-+ }
-+ fd = open(pathname, O_RDWR|O_CREAT, 0666);
-+ if(fd > 0 ) {
-+ unlink(pathname);
-+ return fd;
-+ }
-+ apc_error("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:" TSRMLS_CC, pathname);
-+ return -1;
-+}
-+
-+void apc_fcntl_destroy(int fd)
-+{
-+ close(fd);
-+}
-+
-+static int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
-+{
-+ int ret;
-+ struct flock lock;
-+
-+ lock.l_type = type;
-+ lock.l_start = offset;
-+ lock.l_whence = whence;
-+ lock.l_len = len;
-+ lock.l_pid = 0;
-+
-+ do { ret = fcntl(fd, cmd, &lock) ; }
-+ while(ret < 0 && errno == EINTR);
-+ return(ret);
-+}
-+
-+void apc_fcntl_lock(int fd TSRMLS_DC)
-+{
-+ if(lock_reg(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
-+ apc_error("apc_fcntl_lock failed:" TSRMLS_CC);
-+ }
-+}
-+
-+void apc_fcntl_rdlock(int fd TSRMLS_DC)
-+{
-+ if(lock_reg(fd, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) {
-+ apc_error("apc_fcntl_rdlock failed:" TSRMLS_CC);
-+ }
-+}
-+
-+zend_bool apc_fcntl_nonblocking_lock(int fd TSRMLS_DC)
-+{
-+ if(lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0) < 0) {
-+ if(errno==EACCES||errno==EAGAIN) return 0;
-+ else apc_error("apc_fcntl_lock failed:" TSRMLS_CC);
-+ }
-+ return 1;
-+}
-+
-+void apc_fcntl_unlock(int fd TSRMLS_DC)
-+{
-+ if(lock_reg(fd, F_SETLKW, F_UNLCK, 0, SEEK_SET, 0) < 0) {
-+ apc_error("apc_fcntl_unlock failed:" TSRMLS_CC);
-+ }
-+}
-+
-+#endif /* APC_FCNTL_LOCKS */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_fcntl.h b/ext/apc/apc_fcntl.h
---- a/ext/apc/apc_fcntl.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_fcntl.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_fcntl.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_FCNTL_H
-+#define APC_FCNTL_H
-+
-+
-+extern int apc_fcntl_create(const char* pathname TSRMLS_DC);
-+extern void apc_fcntl_destroy(int fd);
-+extern void apc_fcntl_lock(int fd TSRMLS_DC);
-+extern void apc_fcntl_rdlock(int fd TSRMLS_DC);
-+extern void apc_fcntl_unlock(int fd TSRMLS_DC);
-+extern unsigned char apc_fcntl_nonblocking_lock(int fd TSRMLS_DC);
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_fcntl_win32.c b/ext/apc/apc_fcntl_win32.c
---- a/ext/apc/apc_fcntl_win32.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_fcntl_win32.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,120 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: George Schlossnagle <george@omniti.com> |
-+ | Edin Kadribasic <edink@php.net> |
-+ | Pierre Joye <pierre@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_fcntl_win32.c 309203 2011-03-14 06:47:16Z pajoye $ */
-+
-+#include "apc.h"
-+#include "apc_fcntl.h"
-+#include <php.h>
-+#include <win32/flock.h>
-+#include <io.h>
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+
-+int apc_fcntl_create(const char* pathname TSRMLS_DC)
-+{
-+ char lock_file[MAXPATHLEN];
-+ HANDLE fd;
-+ DWORD tmp_dirname_len;
-+ char lock_filename_tpl[] = ".apc.XXXXXX";
-+ char *lock_filename;
-+
-+ tmp_dirname_len = GetTempPath(MAXPATHLEN, lock_file);
-+ if (!tmp_dirname_len) {
-+ return -1;
-+ }
-+
-+ lock_filename = _mktemp(lock_filename_tpl);
-+ if (lock_filename == NULL) {
-+ return -1;
-+ }
-+
-+ snprintf(lock_file + tmp_dirname_len, MAXPATHLEN - tmp_dirname_len - 1, "%s", lock_filename);
-+
-+ fd = CreateFile(lock_file,
-+ GENERIC_READ | GENERIC_WRITE,
-+ FILE_SHARE_READ | FILE_SHARE_WRITE,
-+ NULL,
-+ OPEN_ALWAYS,
-+ FILE_ATTRIBUTE_NORMAL,
-+ NULL);
-+
-+ if (fd == INVALID_HANDLE_VALUE) {
-+ apc_error("apc_fcntl_create: could not open %s" TSRMLS_CC, lock_file);
-+ return -1;
-+ }
-+
-+ return (int)fd;
-+}
-+
-+void apc_fcntl_destroy(int fd)
-+{
-+ CloseHandle((HANDLE)fd);
-+}
-+
-+void apc_fcntl_lock(int fd TSRMLS_DC)
-+{
-+ OVERLAPPED offset = {0, 0, 0, 0, NULL};
-+
-+ if (!LockFileEx((HANDLE)fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &offset)) {
-+ apc_error("apc_fcntl_lock failed errno:%d" TSRMLS_CC, GetLastError());
-+ }
-+}
-+
-+void apc_fcntl_rdlock(int fd TSRMLS_DC)
-+{
-+ OVERLAPPED offset = {0, 0, 0, 0, NULL};
-+
-+ if (!LockFileEx((HANDLE)fd, 0, 0, 1, 0, &offset)) {
-+ apc_error("apc_fcntl_rdlock failed errno:%d" TSRMLS_CC, GetLastError());
-+ }
-+}
-+
-+void apc_fcntl_unlock(int fd TSRMLS_DC)
-+{
-+ OVERLAPPED offset = {0, 0, 0, 0, NULL};
-+
-+ if (!UnlockFileEx((HANDLE)fd, 0, 1, 0, &offset)) {
-+ DWORD error_code = GetLastError();
-+ /* Ignore already unlocked error */
-+ if (error_code != ERROR_NOT_LOCKED) {
-+ apc_error("apc_fcntl_unlock failed errno:%d" TSRMLS_CC, error_code);
-+ }
-+ }
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_globals.h b/ext/apc/apc_globals.h
---- a/ext/apc/apc_globals.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_globals.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,152 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_globals.h 307215 2011-01-07 09:54:00Z gopalv $ */
-+
-+#ifndef APC_GLOBALS_H
-+#define APC_GLOBALS_H
-+
-+#include "apc_cache.h"
-+#include "apc_stack.h"
-+#include "apc_php.h"
-+#include "apc_main.h"
-+
-+/* {{{ struct apc_rfc1867_data */
-+
-+typedef struct _apc_rfc1867_data apc_rfc1867_data;
-+
-+struct _apc_rfc1867_data {
-+ char tracking_key[64];
-+ int key_length;
-+ size_t content_length;
-+ char filename[128];
-+ char name[64];
-+ char *temp_filename;
-+ int cancel_upload;
-+ double start_time;
-+ size_t bytes_processed;
-+ size_t prev_bytes_processed;
-+ int update_freq;
-+ double rate;
-+ int started;
-+};
-+/* }}} */
-+
-+
-+ZEND_BEGIN_MODULE_GLOBALS(apc)
-+ /* configuration parameters */
-+ zend_bool enabled; /* if true, apc is enabled (defaults to true) */
-+ long shm_segments; /* number of shared memory segments to use */
-+ long shm_size; /* size of each shared memory segment (in MB) */
-+ long num_files_hint; /* parameter to apc_cache_create */
-+ long user_entries_hint;
-+ long gc_ttl; /* parameter to apc_cache_create */
-+ long ttl; /* parameter to apc_cache_create */
-+ long user_ttl;
-+#if APC_MMAP
-+ char *mmap_file_mask; /* mktemp-style file-mask to pass to mmap */
-+#endif
-+ char** filters; /* array of regex filters that prevent caching */
-+ void* compiled_filters; /* compiled regex filters */
-+
-+ /* module variables */
-+ zend_bool initialized; /* true if module was initialized */
-+ apc_stack_t* cache_stack; /* the stack of cached executable code */
-+ zend_bool cache_by_default; /* true if files should be cached unless filtered out */
-+ /* false if files should only be cached if filtered in */
-+ long file_update_protection; /* Age in seconds before a file is eligible to be cached - 0 to disable */
-+ zend_bool enable_cli; /* Flag to override turning APC off for CLI */
-+ long max_file_size; /* Maximum size of file, in bytes that APC will be allowed to cache */
-+ zend_bool fpstat; /* true if fullpath includes should be stat'ed */
-+ zend_bool canonicalize; /* true if relative paths should be canonicalized in no-stat mode */
-+ zend_bool stat_ctime; /* true if ctime in addition to mtime should be checked */
-+ zend_bool write_lock; /* true for a global write lock */
-+ zend_bool slam_defense; /* true for user cache slam defense */
-+ zend_bool report_autofilter; /* true for auto-filter warnings */
-+ zend_bool include_once; /* Override the ZEND_INCLUDE_OR_EVAL opcode handler to avoid pointless fopen()s [still experimental] */
-+ apc_optimize_function_t apc_optimize_function; /* optimizer function callback */
-+#ifdef MULTIPART_EVENT_FORMDATA
-+ zend_bool rfc1867; /* Flag to enable rfc1867 handler */
-+ char* rfc1867_prefix; /* Key prefix */
-+ char* rfc1867_name; /* Name of hidden field to activate upload progress/key suffix */
-+ double rfc1867_freq; /* Update frequency as percentage or bytes */
-+ long rfc1867_ttl; /* TTL for rfc1867 entries */
-+ apc_rfc1867_data rfc1867_data;/* Per-request data */
-+#endif
-+ HashTable copied_zvals; /* my_copy recursion detection list */
-+ zend_bool force_file_update; /* force files to be updated during apc_compile_file */
-+ char canon_path[MAXPATHLEN]; /* canonical path for key data */
-+#ifdef APC_FILEHITS
-+ zval *filehits; /* Files that came from the cache for this request */
-+#endif
-+ zend_bool coredump_unmap; /* Trap signals that coredump and unmap shared memory */
-+ apc_cache_t *current_cache; /* current cache being modified/read */
-+ char *preload_path;
-+ zend_bool file_md5; /* record md5 hash of files */
-+ void *apc_bd_alloc_ptr; /* bindump alloc() ptr */
-+ void *apc_bd_alloc_ubptr; /* bindump alloc() upper bound ptr */
-+ HashTable apc_bd_alloc_list; /* bindump alloc() ptr list */
-+ zend_bool use_request_time; /* use the SAPI request start time for TTL */
-+ zend_bool lazy_functions; /* enable/disable lazy function loading */
-+ HashTable *lazy_function_table; /* lazy function entry table */
-+ zend_bool lazy_classes; /* enable/disable lazy class loading */
-+ HashTable *lazy_class_table; /* lazy class entry table */
-+#ifdef ZEND_ENGINE_2_4
-+ long shm_strings_buffer;
-+#endif
-+ char *serializer_name; /* the serializer config option */
-+ apc_serializer_t *serializer;/* the actual serializer in use */
-+ZEND_END_MODULE_GLOBALS(apc)
-+
-+/* (the following declaration is defined in php_apc.c) */
-+ZEND_EXTERN_MODULE_GLOBALS(apc)
-+
-+#ifdef ZTS
-+# define APCG(v) TSRMG(apc_globals_id, zend_apc_globals *, v)
-+#else
-+# define APCG(v) (apc_globals.v)
-+#endif
-+
-+/* True globals */
-+extern apc_cache_t* apc_cache; /* the global compiler cache */
-+extern apc_cache_t* apc_user_cache; /* the global user content cache */
-+extern void* apc_compiled_filters; /* compiled filters */
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc.h b/ext/apc/apc.h
---- a/ext/apc/apc.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,136 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc.h 307264 2011-01-08 13:20:20Z gopalv $ */
-+
-+#ifndef APC_H
-+#define APC_H
-+
-+/*
-+ * This module defines utilities and helper functions used elsewhere in APC.
-+ */
-+
-+/* Commonly needed C library headers. */
-+#include <assert.h>
-+#include <errno.h>
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <time.h>
-+
-+/* UNIX headers (needed for struct stat) */
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#ifndef PHP_WIN32
-+#include <unistd.h>
-+#endif
-+
-+#ifdef HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+
-+#include "php.h"
-+#include "main/php_streams.h"
-+
-+/* typedefs for extensible memory allocators */
-+typedef void* (*apc_malloc_t)(size_t TSRMLS_DC);
-+typedef void (*apc_free_t) (void * TSRMLS_DC);
-+
-+/* wrappers for memory allocation routines */
-+extern void* apc_emalloc(size_t n TSRMLS_DC);
-+extern void* apc_erealloc(void* p, size_t n TSRMLS_DC);
-+extern void apc_efree(void* p TSRMLS_DC);
-+extern char* apc_estrdup(const char* s TSRMLS_DC);
-+extern void* apc_xstrdup(const char* s, apc_malloc_t f TSRMLS_DC);
-+extern void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f TSRMLS_DC);
-+
-+/* console display functions */
-+extern void apc_error(const char *format TSRMLS_DC, ...);
-+extern void apc_warning(const char *format TSRMLS_DC, ...);
-+extern void apc_notice(const char *format TSRMLS_DC, ...);
-+extern void apc_debug(const char *format TSRMLS_DC, ...);
-+
-+/* string and text manipulation */
-+extern char* apc_append(const char* s, const char* t TSRMLS_DC);
-+extern char* apc_substr(const char* s, int start, int length TSRMLS_DC);
-+extern char** apc_tokenize(const char* s, char delim TSRMLS_DC);
-+
-+/* filesystem functions */
-+
-+typedef struct apc_fileinfo_t
-+{
-+ char *fullpath;
-+ char path_buf[MAXPATHLEN];
-+ php_stream_statbuf st_buf;
-+} apc_fileinfo_t;
-+
-+extern int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo TSRMLS_DC);
-+
-+/* regular expression wrapper functions */
-+extern void* apc_regex_compile_array(char* patterns[] TSRMLS_DC);
-+extern void apc_regex_destroy_array(void* p TSRMLS_DC);
-+extern int apc_regex_match_array(void* p, const char* input);
-+
-+/* apc_crc32: returns the CRC-32 checksum of the first len bytes in buf */
-+extern unsigned int apc_crc32(const char* buf, int len);
-+
-+/* apc_flip_hash flips keys and values for faster searching */
-+extern HashTable* apc_flip_hash(HashTable *hash);
-+
-+#define APC_NEGATIVE_MATCH 1
-+#define APC_POSITIVE_MATCH 2
-+
-+#define apc_time() \
-+ (APCG(use_request_time) ? (time_t) sapi_get_request_time(TSRMLS_C) : time(0));
-+
-+#if defined(__GNUC__)
-+# define APC_UNUSED __attribute__((unused))
-+# define APC_USED __attribute__((used))
-+# define APC_ALLOC __attribute__((malloc))
-+# define APC_HOTSPOT __attribute__((hot))
-+#else
-+# define APC_UNUSED
-+# define APC_USED
-+# define APC_ALLOC
-+# define APC_HOTSPOT
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_iterator.c b/ext/apc/apc_iterator.c
---- a/ext/apc/apc_iterator.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_iterator.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,741 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_iterator.c 324326 2012-03-18 13:19:50Z pajoye $ */
-+
-+#include "php_apc.h"
-+#include "apc_iterator.h"
-+#include "apc_cache.h"
-+#include "apc_zend.h"
-+
-+#include "ext/standard/md5.h"
-+
-+#include "zend_interfaces.h"
-+
-+zend_class_entry *apc_iterator_ce;
-+zend_object_handlers apc_iterator_object_handlers;
-+
-+
-+/* {{{ apc_iterator_item */
-+static apc_iterator_item_t* apc_iterator_item_ctor(apc_iterator_t *iterator, slot_t **slot_pp TSRMLS_DC) {
-+ zval *zvalue;
-+ char md5str[33];
-+ slot_t *slot = *slot_pp;
-+ apc_context_t ctxt = {0, };
-+ apc_iterator_item_t *item = ecalloc(1, sizeof(apc_iterator_item_t));
-+
-+ if (slot->key.type == APC_CACHE_KEY_FILE) {
-+ /* keys should be unique and with stat=1 we could have multiple files with the same name, so use '<device> <inode>' instead */
-+#ifdef PHP_WIN32
-+ item->key_len = spprintf(&item->key, 0, "%I64d %I64d", slot->key.data.file.device, slot->key.data.file.inode);
-+#else
-+ item->key_len = spprintf(&item->key, 0, "%ld %ld", (ulong)slot->key.data.file.device, (ulong)slot->key.data.file.inode);
-+#endif
-+ item->filename_key = estrdup(slot->value->data.file.filename);
-+ } else if (slot->key.type == APC_CACHE_KEY_USER) {
-+ item->key = estrndup((char*)slot->key.data.user.identifier, slot->key.data.user.identifier_len);
-+ item->key_len = slot->key.data.user.identifier_len;
-+ item->filename_key = item->key;
-+ } else if (slot->key.type == APC_CACHE_KEY_FPFILE) {
-+ item->key = estrndup((char*)slot->key.data.fpfile.fullpath, slot->key.data.fpfile.fullpath_len);
-+ item->key_len = slot->key.data.fpfile.fullpath_len;
-+ item->filename_key = item->key;
-+ } else {
-+ apc_error("Internal error, invalid entry type." TSRMLS_CC);
-+ }
-+
-+ ALLOC_INIT_ZVAL(item->value);
-+ array_init(item->value);
-+
-+ if (APC_ITER_TYPE & iterator->format) {
-+ if(slot->value->type == APC_CACHE_ENTRY_FILE) {
-+ add_assoc_string(item->value, "type", "file", 1);
-+ } else if(slot->value->type == APC_CACHE_ENTRY_USER) {
-+ add_assoc_string(item->value, "type", "user", 1);
-+ }
-+ }
-+ if (APC_ITER_FILENAME & iterator->format) {
-+ if(slot->value->type == APC_CACHE_ENTRY_FILE) {
-+ if (slot->key.type == APC_CACHE_KEY_FILE) {
-+ add_assoc_string(item->value, "filename", slot->value->data.file.filename, 1);
-+ } else { /* APC_CACHE_FPFILE */
-+ add_assoc_string(item->value, "filename", (char*)slot->key.data.fpfile.fullpath, 1);
-+ }
-+ }
-+ }
-+ if (APC_ITER_DEVICE & iterator->format) {
-+ if(slot->key.type == APC_CACHE_KEY_FILE) {
-+#ifdef PHP_WIN32
-+ char buf[20];
-+ sprintf(buf, "%I64d", slot->key.data.file.device);
-+ add_assoc_string(item->value, "device", buf, 1);
-+#else
-+ add_assoc_long(item->value, "device", slot->key.data.file.device);
-+#endif
-+ }
-+ }
-+ if (APC_ITER_INODE & iterator->format) {
-+ if(slot->key.type == APC_CACHE_KEY_FILE) {
-+#ifdef PHP_WIN32
-+ char buf[20];
-+ sprintf(buf, "%I64d", slot->key.data.file.device);
-+ add_assoc_string(item->value, "device", buf, 1);
-+#else
-+ add_assoc_long(item->value, "inode", slot->key.data.file.inode);
-+#endif
-+ }
-+ }
-+ if (APC_ITER_KEY & iterator->format) {
-+ add_assoc_stringl(item->value, "key", item->key, (item->key_len - 1), 1);
-+ }
-+ if (APC_ITER_VALUE & iterator->format) {
-+ if(slot->value->type == APC_CACHE_ENTRY_USER) {
-+
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, NULL, NULL TSRMLS_CC);
-+ ctxt.copy = APC_COPY_OUT_USER;
-+
-+ MAKE_STD_ZVAL(zvalue);
-+ apc_cache_fetch_zval(zvalue, slot->value->data.user.val, &ctxt TSRMLS_CC);
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ add_assoc_zval(item->value, "value", zvalue);
-+ }
-+ }
-+ if (APC_ITER_MD5 & iterator->format) {
-+ if(slot->value->type == APC_CACHE_ENTRY_FILE) {
-+ if(APCG(file_md5) && slot->key.md5) {
-+ make_digest(md5str, slot->key.md5);
-+ add_assoc_string(item->value, "md5", md5str, 1);
-+ }
-+ }
-+ }
-+ if (APC_ITER_NUM_HITS & iterator->format) {
-+ add_assoc_long(item->value, "num_hits", slot->num_hits);
-+ }
-+ if (APC_ITER_MTIME & iterator->format) {
-+ add_assoc_long(item->value, "mtime", slot->key.mtime);
-+ }
-+ if (APC_ITER_CTIME & iterator->format) {
-+ add_assoc_long(item->value, "creation_time", slot->creation_time);
-+ }
-+ if (APC_ITER_DTIME & iterator->format) {
-+ add_assoc_long(item->value, "deletion_time", slot->deletion_time);
-+ }
-+ if (APC_ITER_ATIME & iterator->format) {
-+ add_assoc_long(item->value, "access_time", slot->access_time);
-+ }
-+ if (APC_ITER_REFCOUNT & iterator->format) {
-+ add_assoc_long(item->value, "ref_count", slot->value->ref_count);
-+ }
-+ if (APC_ITER_MEM_SIZE & iterator->format) {
-+ add_assoc_long(item->value, "mem_size", slot->value->mem_size);
-+ }
-+ if (APC_ITER_TTL & iterator->format) {
-+ if(slot->value->type == APC_CACHE_ENTRY_USER) {
-+ add_assoc_long(item->value, "ttl", slot->value->data.user.ttl);
-+ }
-+ }
-+
-+ return item;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_clone */
-+static zend_object_value apc_iterator_clone(zval *zobject TSRMLS_DC) {
-+ zend_object_value value = {0};
-+ apc_error("APCIterator object cannot be cloned." TSRMLS_CC);
-+ return value;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_item_dtor */
-+static void apc_iterator_item_dtor(apc_iterator_item_t *item) {
-+ if (item->filename_key && item->filename_key != item->key) {
-+ efree(item->filename_key);
-+ }
-+ if (item->key) {
-+ efree(item->key);
-+ }
-+ if (item->value) {
-+ zval_ptr_dtor(&item->value);
-+ }
-+ efree(item);
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_destroy */
-+static void apc_iterator_destroy(void *object, zend_object_handle handle TSRMLS_DC) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)object;
-+
-+ if (iterator->initialized == 0) {
-+ return;
-+ }
-+
-+ while (apc_stack_size(iterator->stack) > 0) {
-+ apc_iterator_item_dtor(apc_stack_pop(iterator->stack));
-+ }
-+ if (iterator->regex) {
-+ efree(iterator->regex);
-+ }
-+ if (iterator->search_hash) {
-+ zend_hash_destroy(iterator->search_hash);
-+ efree(iterator->search_hash);
-+ }
-+ iterator->initialized = 0;
-+
-+}
-+/* }}} */
-+
-+/* {{{ acp_iterator_free */
-+static void apc_iterator_free(void *object TSRMLS_DC) {
-+ zend_object_std_dtor(object TSRMLS_CC);
-+ efree(object);
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_create */
-+static zend_object_value apc_iterator_create(zend_class_entry *ce TSRMLS_DC) {
-+ zend_object_value retval;
-+ apc_iterator_t *iterator;
-+
-+ iterator = emalloc(sizeof(apc_iterator_t));
-+ iterator->obj.ce = ce;
-+ ALLOC_HASHTABLE(iterator->obj.properties);
-+ zend_hash_init(iterator->obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
-+#ifdef ZEND_ENGINE_2_4
-+ iterator->obj.properties_table = NULL;
-+#endif
-+ iterator->obj.guards = NULL;
-+ iterator->initialized = 0;
-+ retval.handle = zend_objects_store_put(iterator, apc_iterator_destroy, apc_iterator_free, NULL TSRMLS_CC);
-+ retval.handlers = &apc_iterator_object_handlers;
-+
-+ return retval;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_search_match
-+ * Verify if the key matches oru search parameters
-+ */
-+static int apc_iterator_search_match(apc_iterator_t *iterator, slot_t **slot) {
-+ char *key;
-+ int key_len;
-+ char *fname_key = NULL;
-+ int fname_key_len = 0;
-+ int rval = 1;
-+
-+ if ((*slot)->key.type == APC_CACHE_KEY_FILE) {
-+ key = (*slot)->value->data.file.filename;
-+ key_len = strlen(key);
-+ fname_key_len = spprintf(&fname_key, 0, "%ld %ld", (*slot)->key.data.file.device, (*slot)->key.data.file.inode);
-+ } else if ((*slot)->key.type == APC_CACHE_KEY_USER) {
-+ key = (char*)(*slot)->key.data.user.identifier;
-+ key_len = (*slot)->key.data.user.identifier_len;
-+ } else if ((*slot)->key.type == APC_CACHE_KEY_FPFILE) {
-+ key = (char*)(*slot)->key.data.fpfile.fullpath;
-+ key_len = (*slot)->key.data.fpfile.fullpath_len;
-+ } else {
-+ return 0;
-+ }
-+
-+#ifdef ITERATOR_PCRE
-+ if (iterator->regex) {
-+ rval = (pcre_exec(iterator->re, NULL, key, strlen(key), 0, 0, NULL, 0) >= 0);
-+ }
-+#endif
-+
-+ if (iterator->search_hash) {
-+ rval = zend_hash_exists(iterator->search_hash, key, key_len);
-+ if (!rval && fname_key) {
-+ rval = zend_hash_exists(iterator->search_hash, fname_key, fname_key_len+1);
-+ }
-+ }
-+
-+ return rval;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_check_expiry */
-+static int apc_iterator_check_expiry(apc_cache_t* cache, slot_t **slot, time_t t)
-+{
-+ if((*slot)->value->type == APC_CACHE_ENTRY_USER) {
-+ if((*slot)->value->data.user.ttl) {
-+ if((time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t) {
-+ return 0;
-+ }
-+ } else if(cache->ttl) {
-+ if((*slot)->creation_time + cache->ttl < t) {
-+ return 0;
-+ }
-+ }
-+ } else if((*slot)->access_time < (t - cache->ttl)) {
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_fetch_active */
-+static int apc_iterator_fetch_active(apc_iterator_t *iterator TSRMLS_DC) {
-+ int count=0;
-+ slot_t **slot;
-+ apc_iterator_item_t *item;
-+ time_t t;
-+
-+ t = apc_time();
-+
-+ while (apc_stack_size(iterator->stack) > 0) {
-+ apc_iterator_item_dtor(apc_stack_pop(iterator->stack));
-+ }
-+
-+ CACHE_LOCK(iterator->cache);
-+ while(count <= iterator->chunk_size && iterator->slot_idx < iterator->cache->num_slots) {
-+ slot = &iterator->cache->slots[iterator->slot_idx];
-+ while(*slot) {
-+ if (apc_iterator_check_expiry(iterator->cache, slot, t)) {
-+ if (apc_iterator_search_match(iterator, slot)) {
-+ count++;
-+ item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
-+ if (item) {
-+ apc_stack_push(iterator->stack, item TSRMLS_CC);
-+ }
-+ }
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ iterator->slot_idx++;
-+ }
-+ CACHE_UNLOCK(iterator->cache);
-+ iterator->stack_idx = 0;
-+ return count;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_fetch_deleted */
-+static int apc_iterator_fetch_deleted(apc_iterator_t *iterator TSRMLS_DC) {
-+ int count=0;
-+ slot_t **slot;
-+ apc_iterator_item_t *item;
-+
-+ CACHE_LOCK(iterator->cache);
-+ slot = &iterator->cache->header->deleted_list;
-+ while ((*slot) && count <= iterator->slot_idx) {
-+ count++;
-+ slot = &(*slot)->next;
-+ }
-+ count = 0;
-+ while ((*slot) && count < iterator->chunk_size) {
-+ if (apc_iterator_search_match(iterator, slot)) {
-+ count++;
-+ item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
-+ if (item) {
-+ apc_stack_push(iterator->stack, item TSRMLS_CC);
-+ }
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ CACHE_UNLOCK(iterator->cache);
-+ iterator->slot_idx += count;
-+ iterator->stack_idx = 0;
-+ return count;
-+}
-+/* }}} */
-+
-+/* {{{ apc_iterator_totals */
-+static void apc_iterator_totals(apc_iterator_t *iterator TSRMLS_DC) {
-+ slot_t **slot;
-+ int i;
-+
-+ CACHE_LOCK(iterator->cache);
-+ for (i=0; i < iterator->cache->num_slots; i++) {
-+ slot = &iterator->cache->slots[i];
-+ while((*slot)) {
-+ if (apc_iterator_search_match(iterator, slot)) {
-+ iterator->size += (*slot)->value->mem_size;
-+ iterator->hits += (*slot)->num_hits;
-+ iterator->count++;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+ }
-+ CACHE_UNLOCK(iterator->cache);
-+ iterator->totals_flag = 1;
-+}
-+/* }}} */
-+
-+/* {{{ proto object APCIterator::__costruct(string cache [, mixed search [, long format [, long chunk_size [, long list ]]]]) */
-+PHP_METHOD(apc_iterator, __construct) {
-+ zval *object = getThis();
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
-+ char *cachetype;
-+ int cachetype_len;
-+ long format = APC_ITER_ALL;
-+ long chunk_size=0;
-+ zval *search = NULL;
-+ long list = APC_LIST_ACTIVE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zlll", &cachetype, &cachetype_len, &search, &format, &chunk_size, &list) == FAILURE) {
-+ return;
-+ }
-+
-+ if (!APCG(enabled)) {
-+ apc_error("APC must be enabled to use APCIterator." TSRMLS_CC);
-+ }
-+
-+ if (chunk_size < 0) {
-+ apc_error("APCIterator chunk size must be 0 or greater." TSRMLS_CC);
-+ return;
-+ }
-+
-+ if (format > APC_ITER_ALL) {
-+ apc_error("APCIterator format is invalid." TSRMLS_CC);
-+ return;
-+ }
-+
-+ if (list == APC_LIST_ACTIVE) {
-+ iterator->fetch = apc_iterator_fetch_active;
-+ } else if (list == APC_LIST_DELETED) {
-+ iterator->fetch = apc_iterator_fetch_deleted;
-+ } else {
-+ apc_warning("APCIterator invalid list type." TSRMLS_CC);
-+ return;
-+ }
-+
-+ if(!strcasecmp(cachetype,"user")) {
-+ iterator->cache = apc_user_cache;
-+ } else {
-+ iterator->cache = apc_cache;
-+ }
-+
-+ iterator->slot_idx = 0;
-+ iterator->stack_idx = 0;
-+ iterator->key_idx = 0;
-+ iterator->chunk_size = chunk_size == 0 ? APC_DEFAULT_CHUNK_SIZE : chunk_size;
-+ iterator->stack = apc_stack_create(chunk_size TSRMLS_CC);
-+ iterator->format = format;
-+ iterator->totals_flag = 0;
-+ iterator->count = 0;
-+ iterator->size = 0;
-+ iterator->hits = 0;
-+ iterator->regex = NULL;
-+ iterator->regex_len = 0;
-+ iterator->search_hash = NULL;
-+ if (search && Z_TYPE_P(search) == IS_STRING && Z_STRLEN_P(search)) {
-+#ifdef ITERATOR_PCRE
-+ iterator->regex = estrndup(Z_STRVAL_P(search), Z_STRLEN_P(search));
-+ iterator->regex_len = Z_STRLEN_P(search);
-+ iterator->re = pcre_get_compiled_regex(Z_STRVAL_P(search), NULL, NULL TSRMLS_CC);
-+
-+ if(!iterator->re) {
-+ apc_error("Could not compile regular expression: %s" TSRMLS_CC, Z_STRVAL_P(search));
-+ }
-+#else
-+ apc_error("Regular expressions support is not enabled, please enable PCRE for APCIterator regex support" TSRMLS_CC);
-+#endif
-+ } else if (search && Z_TYPE_P(search) == IS_ARRAY) {
-+ Z_ADDREF_P(search);
-+ iterator->search_hash = apc_flip_hash(Z_ARRVAL_P(search));
-+ }
-+ iterator->initialized = 1;
-+}
-+/* }}} */
-+
-+/* {{{ proto APCIterator::rewind() */
-+PHP_METHOD(apc_iterator, rewind) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ iterator->slot_idx = 0;
-+ iterator->stack_idx = 0;
-+ iterator->key_idx = 0;
-+ iterator->fetch(iterator TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto boolean APCIterator::valid() */
-+PHP_METHOD(apc_iterator, valid) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
-+ iterator->fetch(iterator TSRMLS_CC);
-+ }
-+
-+ RETURN_BOOL(apc_stack_size(iterator->stack) == 0 ? 0 : 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed APCIterator::current() */
-+PHP_METHOD(apc_iterator, current) {
-+ apc_iterator_item_t *item;
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
-+ if (iterator->fetch(iterator TSRMLS_CC) == 0) {
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ item = apc_stack_get(iterator->stack, iterator->stack_idx);
-+ RETURN_ZVAL(item->value, 1, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto string APCIterator::key() */
-+PHP_METHOD(apc_iterator, key) {
-+ apc_iterator_item_t *item;
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0 || apc_stack_size(iterator->stack) == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
-+ if (iterator->fetch(iterator TSRMLS_CC) == 0) {
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ item = apc_stack_get(iterator->stack, iterator->stack_idx);
-+
-+ if (item->key) {
-+ RETURN_STRINGL(item->key, (item->key_len-1), 1);
-+ } else {
-+ RETURN_LONG(iterator->key_idx);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto APCIterator::next() */
-+PHP_METHOD(apc_iterator, next) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0 || apc_stack_size(iterator->stack) == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ iterator->stack_idx++;
-+ iterator->key_idx++;
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto long APCIterator::getTotalHits() */
-+PHP_METHOD(apc_iterator, getTotalHits) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (iterator->totals_flag == 0) {
-+ apc_iterator_totals(iterator TSRMLS_CC);
-+ }
-+
-+ RETURN_LONG(iterator->hits);
-+}
-+/* }}} */
-+
-+/* {{{ proto long APCIterator::getTotalSize() */
-+PHP_METHOD(apc_iterator, getTotalSize) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (iterator->totals_flag == 0) {
-+ apc_iterator_totals(iterator TSRMLS_CC);
-+ }
-+
-+ RETURN_LONG(iterator->size);
-+}
-+/* }}} */
-+
-+/* {{{ proto long APCIterator::getTotalCount() */
-+PHP_METHOD(apc_iterator, getTotalCount) {
-+ apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(getThis() TSRMLS_CC);
-+
-+ if (zend_parse_parameters_none() == FAILURE) {
-+ return;
-+ }
-+
-+ if (iterator->initialized == 0) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (iterator->totals_flag == 0) {
-+ apc_iterator_totals(iterator TSRMLS_CC);
-+ }
-+
-+ RETURN_LONG(iterator->count);
-+}
-+/* }}} */
-+
-+/* {{{ arginfo */
-+#if (PHP_MAJOR_VERSION >= 6 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3))
-+# define PHP_APC_ARGINFO
-+#else
-+# define PHP_APC_ARGINFO static
-+#endif
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_iterator___construct, 0, 0, 1)
-+ ZEND_ARG_INFO(0, cache)
-+ ZEND_ARG_INFO(0, search)
-+ ZEND_ARG_INFO(0, format)
-+ ZEND_ARG_INFO(0, chunk_size)
-+ ZEND_ARG_INFO(0, list)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_iterator_void, 0, 0, 0)
-+ZEND_END_ARG_INFO()
-+/* }}} */
-+
-+/* {{{ apc_iterator_functions */
-+static zend_function_entry apc_iterator_functions[] = {
-+ PHP_ME(apc_iterator, __construct, arginfo_apc_iterator___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+ PHP_ME(apc_iterator, rewind, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, current, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, key, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, next, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, valid, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, getTotalHits, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, getTotalSize, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ PHP_ME(apc_iterator, getTotalCount, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC)
-+ {NULL, NULL, NULL}
-+};
-+/* }}} */
-+
-+/* {{{ apc_iterator_init */
-+int apc_iterator_init(int module_number TSRMLS_DC) {
-+ zend_class_entry ce;
-+
-+ INIT_CLASS_ENTRY(ce, APC_ITERATOR_NAME, apc_iterator_functions);
-+ apc_iterator_ce = zend_register_internal_class(&ce TSRMLS_CC);
-+ apc_iterator_ce->create_object = apc_iterator_create;
-+ zend_class_implements(apc_iterator_ce TSRMLS_CC, 1, zend_ce_iterator);
-+
-+ zend_register_long_constant("APC_LIST_ACTIVE", sizeof("APC_LIST_ACTIVE"), APC_LIST_ACTIVE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_LIST_DELETED", sizeof("APC_LIST_DELETED"), APC_LIST_DELETED, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+
-+ zend_register_long_constant("APC_ITER_TYPE", sizeof("APC_ITER_TYPE"), APC_ITER_TYPE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_KEY", sizeof("APC_ITER_KEY"), APC_ITER_KEY, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_FILENAME", sizeof("APC_ITER_FILENAME"), APC_ITER_FILENAME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_DEVICE", sizeof("APC_ITER_DEVICE"), APC_ITER_DEVICE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_INODE", sizeof("APC_ITER_INODE"), APC_ITER_INODE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_VALUE", sizeof("APC_ITER_VALUE"), APC_ITER_VALUE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_MD5", sizeof("APC_ITER_MD5"), APC_ITER_MD5, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_NUM_HITS", sizeof("APC_ITER_NUM_HITS"), APC_ITER_NUM_HITS, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_MTIME", sizeof("APC_ITER_MTIME"), APC_ITER_MTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_CTIME", sizeof("APC_ITER_CTIME"), APC_ITER_CTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_DTIME", sizeof("APC_ITER_DTIME"), APC_ITER_DTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_ATIME", sizeof("APC_ITER_ATIME"), APC_ITER_ATIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_REFCOUNT", sizeof("APC_ITER_REFCOUNT"), APC_ITER_REFCOUNT, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_MEM_SIZE", sizeof("APC_ITER_MEM_SIZE"), APC_ITER_MEM_SIZE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_TTL", sizeof("APC_ITER_TTL"), APC_ITER_TTL, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_NONE", sizeof("APC_ITER_NONE"), APC_ITER_NONE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_ITER_ALL", sizeof("APC_ITER_ALL"), APC_ITER_ALL, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
-+
-+ memcpy(&apc_iterator_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-+ apc_iterator_object_handlers.clone_obj = apc_iterator_clone;
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+
-+int apc_iterator_delete(zval *zobj TSRMLS_DC) {
-+ apc_iterator_t *iterator;
-+ zend_class_entry *ce = Z_OBJCE_P(zobj);
-+ apc_iterator_item_t *item;
-+
-+ if (!ce || !instanceof_function(ce, apc_iterator_ce TSRMLS_CC)) {
-+ apc_error("apc_delete object argument must be instance of APCIterator" TSRMLS_CC);
-+ return 0;
-+ }
-+ iterator = (apc_iterator_t*)zend_object_store_get_object(zobj TSRMLS_CC);
-+
-+ if (iterator->initialized == 0) {
-+ return 0;
-+ }
-+
-+ while (iterator->fetch(iterator TSRMLS_CC)) {
-+ while (iterator->stack_idx < apc_stack_size(iterator->stack)) {
-+ item = apc_stack_get(iterator->stack, iterator->stack_idx++);
-+ if (iterator->cache == apc_cache) {
-+ apc_cache_delete(apc_cache, item->filename_key, strlen(item->filename_key) + 1 TSRMLS_CC);
-+ } else {
-+ apc_cache_user_delete(apc_user_cache, item->key, item->key_len TSRMLS_CC);
-+ }
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_iterator.h b/ext/apc/apc_iterator.h
---- a/ext/apc/apc_iterator.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_iterator.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,117 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@.php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_iterator.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_ITERATOR_H
-+#define APC_ITERATOR_H
-+
-+#include "apc.h"
-+#include "apc_stack.h"
-+
-+#if HAVE_PCRE || HAVE_BUNDLED_PCRE
-+/* Deal with problem present until php-5.2.2 where php_pcre.h was not installed correctly */
-+# if !HAVE_BUNDLED_PCRE && PHP_MAJOR_VERSION == 5 && (PHP_MINOR_VERSION < 2 || (PHP_MINOR_VERSION == 2 && PHP_RELEASE_VERSION < 2))
-+# include "apc_php_pcre.h"
-+# else
-+# include "ext/pcre/php_pcre.h"
-+# endif
-+# include "ext/standard/php_smart_str.h"
-+# define ITERATOR_PCRE 1
-+#endif
-+
-+
-+#define APC_ITERATOR_NAME "APCIterator"
-+
-+#define APC_DEFAULT_CHUNK_SIZE 100
-+
-+#define APC_LIST_ACTIVE 0x1
-+#define APC_LIST_DELETED 0x2
-+
-+#define APC_ITER_TYPE (1L << 0)
-+#define APC_ITER_KEY (1L << 1)
-+#define APC_ITER_FILENAME (1L << 2)
-+#define APC_ITER_DEVICE (1L << 3)
-+#define APC_ITER_INODE (1L << 4)
-+#define APC_ITER_VALUE (1L << 5)
-+#define APC_ITER_MD5 (1L << 6)
-+#define APC_ITER_NUM_HITS (1L << 7)
-+#define APC_ITER_MTIME (1L << 8)
-+#define APC_ITER_CTIME (1L << 9)
-+#define APC_ITER_DTIME (1L << 10)
-+#define APC_ITER_ATIME (1L << 11)
-+#define APC_ITER_REFCOUNT (1L << 12)
-+#define APC_ITER_MEM_SIZE (1L << 13)
-+#define APC_ITER_TTL (1L << 14)
-+
-+#define APC_ITER_NONE (0x00000000L)
-+#define APC_ITER_ALL (0xffffffffL)
-+
-+typedef void* (*apc_iterator_item_cb_t)(slot_t **slot);
-+
-+
-+/* {{{ apc_iterator_t */
-+typedef struct _apc_iterator_t {
-+ zend_object obj; /* must always be first */
-+ short int initialized; /* sanity check in case __construct failed */
-+ long format; /* format bitmask of the return values ie: key, value, info */
-+ int (*fetch)(struct _apc_iterator_t *iterator TSRMLS_DC);
-+ /* fetch callback to fetch items from cache slots or lists */
-+ apc_cache_t *cache; /* cache which we are iterating on */
-+ long slot_idx; /* index to the slot array or linked list */
-+ long chunk_size; /* number of entries to pull down per fetch */
-+ apc_stack_t *stack; /* stack of entries pulled from cache */
-+ int stack_idx; /* index into the current stack */
-+#ifdef ITERATOR_PCRE
-+ pcre *re; /* regex filter on entry identifiers */
-+#endif
-+ char *regex; /* original regex expression or NULL */
-+ int regex_len; /* regex length */
-+ HashTable *search_hash; /* hash of keys to iterate over */
-+ long key_idx; /* incrementing index for numerical keys */
-+ short int totals_flag; /* flag if totals have been calculated */
-+ long hits; /* hit total */
-+ size_t size; /* size total */
-+ long count; /* count total */
-+} apc_iterator_t;
-+/* }}} */
-+
-+/* {{{ apc_iterator_item */
-+typedef struct _apc_iterator_item_t {
-+ char *key; /* string key */
-+ long key_len; /* strlen of key */
-+ char *filename_key; /* filename key used for deletion */
-+ zval *value;
-+} apc_iterator_item_t;
-+/* }}} */
-+
-+
-+extern int apc_iterator_init(int module_number TSRMLS_DC);
-+extern int apc_iterator_delete(zval *zobj TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_lock.h b/ext/apc/apc_lock.h
---- a/ext/apc/apc_lock.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_lock.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,160 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Pierre Joye <pierre@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_lock.h 311339 2011-05-22 17:18:49Z gopalv $ */
-+
-+#ifndef APC_LOCK
-+#define APC_LOCK
-+
-+#ifdef HAVE_CONFIG_H
-+# include <config.h>
-+#endif
-+
-+#include "apc.h"
-+#include "apc_sem.h"
-+#include "apc_fcntl.h"
-+#include "apc_pthreadmutex.h"
-+#include "apc_pthreadrwlock.h"
-+#include "apc_spin.h"
-+#include "apc_windows_srwlock_kernel.h"
-+
-+/* {{{ generic locking macros */
-+#define CREATE_LOCK(lock) apc_lck_create(NULL, 0, 1, lock)
-+#define DESTROY_LOCK(lock) apc_lck_destroy(lock)
-+#define LOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_lock(lock); }
-+#define RDLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_rdlock(lock); }
-+#define UNLOCK(lock) { apc_lck_unlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
-+#define RDUNLOCK(lock) { apc_lck_rdunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
-+/* }}} */
-+
-+/* atomic operations : rdlocks are impossible without these */
-+#if HAVE_ATOMIC_OPERATIONS
-+# ifdef PHP_WIN32
-+# define ATOMIC_INC(a) InterlockedIncrement(&a)
-+# define ATOMIC_DEC(a) InterlockedDecrement(&a)
-+# else
-+# define ATOMIC_INC(a) __sync_add_and_fetch(&a, 1)
-+# define ATOMIC_DEC(a) __sync_sub_and_fetch(&a, 1)
-+# endif
-+#endif
-+
-+#if defined(APC_SEM_LOCKS)
-+# define APC_LOCK_TYPE "IPC Semaphore"
-+# define RDLOCK_AVAILABLE 0
-+# define NONBLOCKING_LOCK_AVAILABLE 1
-+# define apc_lck_t int
-+# define apc_lck_create(a,b,c,d) d=apc_sem_create((b),(c) TSRMLS_CC)
-+# define apc_lck_destroy(a) apc_sem_destroy(a)
-+# define apc_lck_lock(a) apc_sem_lock(a TSRMLS_CC)
-+# define apc_lck_nb_lock(a) apc_sem_nonblocking_lock(a TSRMLS_CC)
-+# define apc_lck_rdlock(a) apc_sem_lock(a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_sem_unlock(a TSRMLS_CC)
-+# define apc_lck_rdunlock(a) apc_sem_unlock(a TSRMLS_CC)
-+#elif defined(APC_PTHREADMUTEX_LOCKS)
-+# define APC_LOCK_TYPE "pthread mutex Locks"
-+# define RDLOCK_AVAILABLE 0
-+# define NONBLOCKING_LOCK_AVAILABLE 1
-+# define apc_lck_t pthread_mutex_t
-+# define apc_lck_create(a,b,c,d) apc_pthreadmutex_create((pthread_mutex_t*)&d TSRMLS_CC)
-+# define apc_lck_destroy(a) apc_pthreadmutex_destroy(&a)
-+# define apc_lck_lock(a) apc_pthreadmutex_lock(&a TSRMLS_CC)
-+# define apc_lck_nb_lock(a) apc_pthreadmutex_nonblocking_lock(&a TSRMLS_CC)
-+# define apc_lck_rdlock(a) apc_pthreadmutex_lock(&a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_pthreadmutex_unlock(&a TSRMLS_CC)
-+# define apc_lck_rdunlock(a) apc_pthreadmutex_unlock(&a TSRMLS_CC)
-+#elif defined(APC_PTHREADRW_LOCKS)
-+# define APC_LOCK_TYPE "pthread read/write Locks"
-+# define RDLOCK_AVAILABLE 1
-+# define NONBLOCKING_LOCK_AVAILABLE 1
-+# define apc_lck_t pthread_rwlock_t
-+# define apc_lck_create(a,b,c,d) apc_pthreadrwlock_create((pthread_rwlock_t*)&d TSRMLS_CC)
-+# define apc_lck_destroy(a) apc_pthreadrwlock_destroy(&a)
-+# define apc_lck_lock(a) apc_pthreadrwlock_lock(&a TSRMLS_CC)
-+# define apc_lck_nb_lock(a) apc_pthreadrwlock_nonblocking_lock(&a TSRMLS_CC)
-+# define apc_lck_rdlock(a) apc_pthreadrwlock_rdlock(&a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_pthreadrwlock_unlock(&a TSRMLS_CC)
-+# define apc_lck_rdunlock(a) apc_pthreadrwlock_unlock(&a TSRMLS_CC)
-+#elif defined(APC_SPIN_LOCKS)
-+# define APC_LOCK_TYPE "spin Locks"
-+# define RDLOCK_AVAILABLE 0
-+# define NONBLOCKING_LOCK_AVAILABLE APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE
-+# define apc_lck_t slock_t
-+# define apc_lck_create(a,b,c,d) apc_slock_create((slock_t*)&(d))
-+# define apc_lck_destroy(a) apc_slock_destroy(&a)
-+# define apc_lck_lock(a) apc_slock_lock(&a TSRMLS_CC)
-+# define apc_lck_nb_lock(a) apc_slock_nonblocking_lock(&a)
-+# define apc_lck_rdlock(a) apc_slock_lock(&a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_slock_unlock(&a)
-+# define apc_lck_rdunlock(a) apc_slock_unlock(&a)
-+#elif defined(APC_SRWLOCK_NATIVE) && defined(PHP_WIN32)
-+# define APC_LOCK_TYPE "Windows Slim RWLOCK (native)"
-+# define RDLOCK_AVAILABLE 1
-+# define NONBLOCKING_LOCK_AVAILABLE 0
-+# define apc_lck_t SRWLOCK
-+# define apc_lck_create(a,b,c,d) InitializeSRWLock((SRWLOCK*)&(d))
-+# define apc_lck_destroy(a)
-+# define apc_lck_lock(a) AcquireSRWLockExclusive(&a)
-+# define apc_lck_rdlock(a) AcquireSRWLockShared(&a)
-+# define apc_lck_unlock(a) ReleaseSRWLockExclusive(&a)
-+# define apc_lck_rdunlock(a) ReleaseSRWLockShared(&a)
-+# if NONBLOCKING_LOCK_AVAILABLE==1 /* Only in win7/2008 */
-+# define apc_lck_nb_lock(a) (TryAcquireSRWLockExclusive(&a TSRMLS_CC) == 0 ? 1 : 0);
-+# endif
-+#elif defined(APC_SRWLOCK_KERNEL) && defined(PHP_WIN32)
-+# define APC_LOCK_TYPE "Windows Slim RWLOCK (kernel)"
-+# define RDLOCK_AVAILABLE 1
-+# define NONBLOCKING_LOCK_AVAILABLE 0
-+# define apc_lck_t apc_windows_cs_rwlock_t
-+# define apc_lck_create(a,b,c,d) apc_windows_cs_create((apc_windows_cs_rwlock_t*)&(d) TSRMLS_CC)
-+# define apc_lck_destroy(a) apc_windows_cs_destroy(&a);
-+# define apc_lck_lock(a) apc_windows_cs_lock(&a TSRMLS_CC)
-+# define apc_lck_rdlock(a) apc_windows_cs_rdlock(&a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_windows_cs_unlock_wr(&a TSRMLS_CC)
-+# define apc_lck_rdunlock(a) apc_windows_cs_unlock_rd(&a TSRMLS_CC)
-+#else
-+# define APC_LOCK_TYPE "File Locks"
-+# ifdef HAVE_ATOMIC_OPERATIONS
-+# define RDLOCK_AVAILABLE 1
-+# endif
-+# ifdef PHP_WIN32
-+# define NONBLOCKING_LOCK_AVAILABLE 0
-+# else
-+# define NONBLOCKING_LOCK_AVAILABLE 1
-+# endif
-+# define apc_lck_t int
-+# define apc_lck_create(a,b,c,d) d=apc_fcntl_create((a) TSRMLS_CC)
-+# define apc_lck_destroy(a) apc_fcntl_destroy(a)
-+# define apc_lck_lock(a) apc_fcntl_lock(a TSRMLS_CC)
-+# define apc_lck_nb_lock(a) apc_fcntl_nonblocking_lock(a TSRMLS_CC)
-+# define apc_lck_rdlock(a) apc_fcntl_rdlock(a TSRMLS_CC)
-+# define apc_lck_unlock(a) apc_fcntl_unlock(a TSRMLS_CC)
-+# define apc_lck_rdunlock(a) apc_fcntl_unlock(a TSRMLS_CC)
-+#endif
-+
-+#endif
-diff -Naur a/ext/apc/apc_main.c b/ext/apc/apc_main.c
---- a/ext/apc/apc_main.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_main.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,1030 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_main.c 324326 2012-03-18 13:19:50Z pajoye $ */
-+
-+#include "apc_php.h"
-+#include "apc_main.h"
-+#include "apc.h"
-+#include "apc_lock.h"
-+#include "apc_cache.h"
-+#include "apc_compile.h"
-+#include "apc_globals.h"
-+#include "apc_sma.h"
-+#include "apc_stack.h"
-+#include "apc_zend.h"
-+#include "apc_pool.h"
-+#include "apc_string.h"
-+#include "SAPI.h"
-+#include "php_scandir.h"
-+#include "ext/standard/php_var.h"
-+#include "ext/standard/md5.h"
-+
-+#define APC_MAX_SERIALIZERS 16
-+
-+/* {{{ module variables */
-+
-+/* pointer to the original Zend engine compile_file function */
-+typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC);
-+static zend_compile_t *old_compile_file;
-+static apc_serializer_t apc_serializers[APC_MAX_SERIALIZERS] = {{0,}};
-+
-+/* }}} */
-+
-+/* {{{ get/set old_compile_file (to interact with other extensions that need the compile hook) */
-+static zend_compile_t* set_compile_hook(zend_compile_t *ptr)
-+{
-+ zend_compile_t *retval = old_compile_file;
-+
-+ if (ptr != NULL) old_compile_file = ptr;
-+ return retval;
-+}
-+/* }}} */
-+
-+/* {{{ install_function */
-+static int install_function(apc_function_t fn, apc_context_t* ctxt, int lazy TSRMLS_DC)
-+{
-+ int status;
-+
-+#if APC_HAVE_LOOKUP_HOOKS
-+ if(lazy && fn.name[0] != '\0' && strncmp(fn.name, "__autoload", fn.name_len) != 0) {
-+ status = zend_hash_add(APCG(lazy_function_table),
-+ fn.name,
-+ fn.name_len+1,
-+ &fn,
-+ sizeof(apc_function_t),
-+ NULL);
-+#else
-+ if(0) {
-+#endif
-+ } else {
-+ zend_function *func = apc_copy_function_for_execution(fn.function, ctxt TSRMLS_CC);
-+ status = zend_hash_add(EG(function_table),
-+ fn.name,
-+ fn.name_len+1,
-+ func,
-+ sizeof(fn.function[0]),
-+ NULL);
-+ efree(func);
-+ }
-+
-+ if (status == FAILURE) {
-+ /* apc_error("Cannot redeclare %s()" TSRMLS_CC, fn.name); */
-+ }
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ apc_lookup_function_hook */
-+int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) {
-+ apc_function_t *fn;
-+ int status = FAILURE;
-+ apc_context_t ctxt = {0,};
-+ TSRMLS_FETCH();
-+
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ ctxt.copy = APC_COPY_OUT_OPCODE;
-+
-+ if(zend_hash_quick_find(APCG(lazy_function_table), name, len, hash, (void**)&fn) == SUCCESS) {
-+ *fe = apc_copy_function_for_execution(fn->function, &ctxt TSRMLS_CC);
-+ status = zend_hash_add(EG(function_table),
-+ fn->name,
-+ fn->name_len+1,
-+ *fe,
-+ sizeof(zend_function),
-+ NULL);
-+ }
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ install_class */
-+static int install_class(apc_class_t cl, apc_context_t* ctxt, int lazy TSRMLS_DC)
-+{
-+ zend_class_entry* class_entry = cl.class_entry;
-+ zend_class_entry* parent = NULL;
-+ int status;
-+ zend_class_entry** allocated_ce = NULL;
-+
-+ /* Special case for mangled names. Mangled names are unique to a file.
-+ * There is no way two classes with the same mangled name will occur,
-+ * unless a file is included twice. And if in case, a file is included
-+ * twice, all mangled name conflicts can be ignored and the class redeclaration
-+ * error may be deferred till runtime of the corresponding DECLARE_CLASS
-+ * calls.
-+ */
-+
-+ if(cl.name_len != 0 && cl.name[0] == '\0') {
-+ if(zend_hash_exists(CG(class_table), cl.name, cl.name_len+1)) {
-+ return SUCCESS;
-+ }
-+ }
-+
-+ if(lazy && cl.name_len != 0 && cl.name[0] != '\0') {
-+ status = zend_hash_add(APCG(lazy_class_table),
-+ cl.name,
-+ cl.name_len+1,
-+ &cl,
-+ sizeof(apc_class_t),
-+ NULL);
-+ if(status == FAILURE) {
-+ zend_error(E_ERROR, "Cannot redeclare class %s", cl.name);
-+ }
-+ return status;
-+ }
-+
-+ /*
-+ * XXX: We need to free this somewhere...
-+ */
-+ allocated_ce = apc_php_malloc(sizeof(zend_class_entry*) TSRMLS_CC);
-+
-+ if(!allocated_ce) {
-+ return FAILURE;
-+ }
-+
-+ *allocated_ce =
-+ class_entry =
-+ apc_copy_class_entry_for_execution(cl.class_entry, ctxt TSRMLS_CC);
-+
-+
-+ /* restore parent class pointer for compile-time inheritance */
-+ if (cl.parent_name != NULL) {
-+ zend_class_entry** parent_ptr = NULL;
-+ /*
-+ * __autoload brings in the old issues with mixed inheritance.
-+ * When a statically inherited class triggers autoload, it runs
-+ * afoul of a potential require_once "parent.php" in the previous
-+ * line, which when executed provides the parent class, but right
-+ * now goes and hits __autoload which could fail.
-+ *
-+ * missing parent == re-compile.
-+ *
-+ * whether __autoload is enabled or not, because __autoload errors
-+ * cause php to die.
-+ *
-+ * Aside: Do NOT pass *strlen(cl.parent_name)+1* because
-+ * zend_lookup_class_ex does it internally anyway!
-+ */
-+ status = zend_lookup_class_ex(cl.parent_name,
-+ strlen(cl.parent_name),
-+#ifdef ZEND_ENGINE_2_4
-+ NULL,
-+#endif
-+ 0,
-+ &parent_ptr TSRMLS_CC);
-+ if (status == FAILURE) {
-+ if(APCG(report_autofilter)) {
-+ apc_warning("Dynamic inheritance detected for class %s" TSRMLS_CC, cl.name);
-+ }
-+ class_entry->parent = NULL;
-+ return status;
-+ }
-+ else {
-+ parent = *parent_ptr;
-+ class_entry->parent = parent;
-+ zend_do_inheritance(class_entry, parent TSRMLS_CC);
-+ }
-+
-+
-+ }
-+
-+ status = zend_hash_add(EG(class_table),
-+ cl.name,
-+ cl.name_len+1,
-+ allocated_ce,
-+ sizeof(zend_class_entry*),
-+ NULL);
-+
-+ if (status == FAILURE) {
-+ apc_error("Cannot redeclare class %s" TSRMLS_CC, cl.name);
-+ }
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ apc_lookup_class_hook */
-+int apc_lookup_class_hook(char *name, int len, ulong hash, zend_class_entry ***ce) {
-+
-+ apc_class_t *cl;
-+ apc_context_t ctxt = {0,};
-+ TSRMLS_FETCH();
-+
-+ if(zend_is_compiling(TSRMLS_C)) { return FAILURE; }
-+
-+ if(zend_hash_quick_find(APCG(lazy_class_table), name, len, hash, (void**)&cl) == FAILURE) {
-+ return FAILURE;
-+ }
-+
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ ctxt.copy = APC_COPY_OUT_OPCODE;
-+
-+ if(install_class(*cl, &ctxt, 0 TSRMLS_CC) == FAILURE) {
-+ apc_warning("apc_lookup_class_hook: could not install %s" TSRMLS_CC, name);
-+ return FAILURE;
-+ }
-+
-+ if(zend_hash_quick_find(EG(class_table), name, len, hash, (void**)ce) == FAILURE) {
-+ apc_warning("apc_lookup_class_hook: known error trying to fetch class %s" TSRMLS_CC, name);
-+ return FAILURE;
-+ }
-+
-+ return SUCCESS;
-+
-+}
-+/* }}} */
-+
-+/* {{{ uninstall_class */
-+static int uninstall_class(apc_class_t cl TSRMLS_DC)
-+{
-+ int status;
-+
-+ status = zend_hash_del(EG(class_table),
-+ cl.name,
-+ cl.name_len+1);
-+ if (status == FAILURE) {
-+ apc_error("Cannot delete class %s" TSRMLS_CC, cl.name);
-+ }
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ copy_function_name (taken from zend_builtin_functions.c to ensure future compatibility with APC) */
-+static int copy_function_name(apc_function_t *pf TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
-+{
-+ zval *internal_ar = va_arg(args, zval *),
-+ *user_ar = va_arg(args, zval *);
-+ zend_function *func = pf->function;
-+
-+ if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
-+ return 0;
-+ }
-+
-+ if (func->type == ZEND_INTERNAL_FUNCTION) {
-+ add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
-+ } else if (func->type == ZEND_USER_FUNCTION) {
-+ add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
-+ }
-+
-+ return 0;
-+}
-+
-+/* {{{ copy_class_or_interface_name (taken from zend_builtin_functions.c to ensure future compatibility with APC) */
-+static int copy_class_or_interface_name(apc_class_t *cl TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
-+{
-+ zval *array = va_arg(args, zval *);
-+ zend_uint mask = va_arg(args, zend_uint);
-+ zend_uint comply = va_arg(args, zend_uint);
-+ zend_uint comply_mask = (comply)? mask:0;
-+ zend_class_entry *ce = cl->class_entry;
-+
-+ if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
-+ && (comply_mask == (ce->ce_flags & mask))) {
-+ add_next_index_stringl(array, ce->name, ce->name_length, 1);
-+ }
-+ return ZEND_HASH_APPLY_KEEP;
-+}
-+/* }}} */
-+
-+/* }}} */
-+
-+/* {{{ apc_defined_function_hook */
-+int apc_defined_function_hook(zval *internal, zval *user) {
-+ TSRMLS_FETCH();
-+ zend_hash_apply_with_arguments(APCG(lazy_function_table)
-+#ifdef ZEND_ENGINE_2_3
-+ TSRMLS_CC
-+#endif
-+ ,(apply_func_args_t) copy_function_name, 2, internal, user);
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_declared_class_hook */
-+int apc_declared_class_hook(zval *classes, zend_uint mask, zend_uint comply) {
-+ TSRMLS_FETCH();
-+ zend_hash_apply_with_arguments(APCG(lazy_class_table)
-+#ifdef ZEND_ENGINE_2_3
-+ TSRMLS_CC
-+#endif
-+ , (apply_func_args_t) copy_class_or_interface_name, 3, classes, mask, comply);
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ cached_compile */
-+static zend_op_array* cached_compile(zend_file_handle* h,
-+ int type,
-+ apc_context_t* ctxt TSRMLS_DC)
-+{
-+ apc_cache_entry_t* cache_entry;
-+ int i, ii;
-+
-+ cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack));
-+ assert(cache_entry != NULL);
-+
-+ if (cache_entry->data.file.classes) {
-+ int lazy_classes = APCG(lazy_classes);
-+ for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-+ if(install_class(cache_entry->data.file.classes[i], ctxt, lazy_classes TSRMLS_CC) == FAILURE) {
-+ goto default_compile;
-+ }
-+ }
-+ }
-+
-+ if (cache_entry->data.file.functions) {
-+ int lazy_functions = APCG(lazy_functions);
-+ for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
-+ install_function(cache_entry->data.file.functions[i], ctxt, lazy_functions TSRMLS_CC);
-+ }
-+ }
-+
-+ apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
-+
-+
-+ return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
-+
-+default_compile:
-+
-+ if(cache_entry->data.file.classes) {
-+ for(ii = 0; ii < i ; ii++) {
-+ uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC);
-+ }
-+ }
-+
-+ apc_stack_pop(APCG(cache_stack)); /* pop out cache_entry */
-+
-+ apc_cache_release(apc_cache, cache_entry TSRMLS_CC);
-+
-+ /* cannot free up cache data yet, it maybe in use */
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_compile_cache_entry */
-+zend_bool apc_compile_cache_entry(apc_cache_key_t *key, zend_file_handle* h, int type, time_t t, zend_op_array** op_array, apc_cache_entry_t** cache_entry TSRMLS_DC) {
-+ int num_functions, num_classes;
-+ apc_function_t* alloc_functions;
-+ zend_op_array* alloc_op_array;
-+ apc_class_t* alloc_classes;
-+ char *path;
-+ apc_context_t ctxt;
-+
-+ /* remember how many functions and classes existed before compilation */
-+ num_functions = zend_hash_num_elements(CG(function_table));
-+ num_classes = zend_hash_num_elements(CG(class_table));
-+
-+ /* compile the file using the default compile function, *
-+ * we set *op_array here so we return opcodes during *
-+ * a failure. We should not return prior to this line. */
-+ *op_array = old_compile_file(h, type TSRMLS_CC);
-+ if (*op_array == NULL) {
-+ return FAILURE;
-+ }
-+
-+ ctxt.pool = apc_pool_create(APC_MEDIUM_POOL, apc_sma_malloc, apc_sma_free,
-+ apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ if (!ctxt.pool) {
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ return FAILURE;
-+ }
-+ ctxt.copy = APC_COPY_IN_OPCODE;
-+
-+ if(APCG(file_md5)) {
-+ int n;
-+ unsigned char buf[1024];
-+ PHP_MD5_CTX context;
-+ php_stream *stream;
-+ char *filename;
-+
-+ if(h->opened_path) {
-+ filename = h->opened_path;
-+ } else {
-+ filename = h->filename;
-+ }
-+ stream = php_stream_open_wrapper(filename, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
-+ if(stream) {
-+ PHP_MD5Init(&context);
-+ while((n = php_stream_read(stream, (char*)buf, sizeof(buf))) > 0) {
-+ PHP_MD5Update(&context, buf, n);
-+ }
-+ PHP_MD5Final(key->md5, &context);
-+ php_stream_close(stream);
-+ if(n<0) {
-+ apc_warning("Error while reading '%s' for md5 generation." TSRMLS_CC, filename);
-+ }
-+ } else {
-+ apc_warning("Unable to open '%s' for md5 generation." TSRMLS_CC, filename);
-+ }
-+ }
-+
-+ if(!(alloc_op_array = apc_copy_op_array(NULL, *op_array, &ctxt TSRMLS_CC))) {
-+ goto freepool;
-+ }
-+
-+ if(!(alloc_functions = apc_copy_new_functions(num_functions, &ctxt TSRMLS_CC))) {
-+ goto freepool;
-+ }
-+ if(!(alloc_classes = apc_copy_new_classes(*op_array, num_classes, &ctxt TSRMLS_CC))) {
-+ goto freepool;
-+ }
-+
-+ path = h->opened_path;
-+ if(!path && key->type == APC_CACHE_KEY_FPFILE) path = (char*)key->data.fpfile.fullpath;
-+ if(!path) path=h->filename;
-+
-+ apc_debug("2. h->opened_path=[%s] h->filename=[%s]\n" TSRMLS_CC, h->opened_path?h->opened_path:"null",h->filename);
-+
-+ if(!(*cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes, &ctxt TSRMLS_CC))) {
-+ goto freepool;
-+ }
-+
-+ return SUCCESS;
-+
-+freepool:
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ ctxt.pool = NULL;
-+
-+ return FAILURE;
-+
-+}
-+/* }}} */
-+
-+/* {{{ my_compile_file
-+ Overrides zend_compile_file */
-+static zend_op_array* my_compile_file(zend_file_handle* h,
-+ int type TSRMLS_DC)
-+{
-+ apc_cache_key_t key;
-+ apc_cache_entry_t* cache_entry;
-+ zend_op_array* op_array = NULL;
-+ time_t t;
-+ apc_context_t ctxt = {0,};
-+ int bailout=0;
-+ const char* filename = NULL;
-+
-+ if (!APCG(enabled) || apc_cache_busy(apc_cache)) {
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+
-+ if(h->opened_path) {
-+ filename = h->opened_path;
-+ } else {
-+ filename = h->filename;
-+ }
-+
-+ /* check our regular expression filters */
-+ if (APCG(filters) && APCG(compiled_filters) && filename) {
-+ int ret = apc_regex_match_array(APCG(compiled_filters), filename);
-+
-+ if(ret == APC_NEGATIVE_MATCH || (ret != APC_POSITIVE_MATCH && !APCG(cache_by_default))) {
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ } else if(!APCG(cache_by_default)) {
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ APCG(current_cache) = apc_cache;
-+
-+
-+ t = apc_time();
-+
-+ apc_debug("1. h->opened_path=[%s] h->filename=[%s]\n" TSRMLS_CC, h->opened_path?h->opened_path:"null",h->filename);
-+
-+ /* try to create a cache key; if we fail, give up on caching */
-+ if (!apc_cache_make_file_key(&key, h->filename, PG(include_path), t TSRMLS_CC)) {
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+
-+ if(!APCG(force_file_update)) {
-+ /* search for the file in the cache */
-+ cache_entry = apc_cache_find(apc_cache, key, t TSRMLS_CC);
-+ ctxt.force_update = 0;
-+ } else {
-+ cache_entry = NULL;
-+ ctxt.force_update = 1;
-+ }
-+
-+ if (cache_entry != NULL) {
-+ int dummy = 1;
-+
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free,
-+ apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ if (!ctxt.pool) {
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ ctxt.copy = APC_COPY_OUT_OPCODE;
-+
-+ zend_hash_add(&EG(included_files), cache_entry->data.file.filename,
-+ strlen(cache_entry->data.file.filename)+1,
-+ (void *)&dummy, sizeof(int), NULL);
-+
-+ apc_stack_push(APCG(cache_stack), cache_entry TSRMLS_CC);
-+ op_array = cached_compile(h, type, &ctxt TSRMLS_CC);
-+
-+ if(op_array) {
-+#ifdef APC_FILEHITS
-+ /* If the file comes from the cache, add it to the global request file list */
-+ add_next_index_string(APCG(filehits), h->filename, 1);
-+#endif
-+ /* this is an unpool, which has no cleanup - this only free's the pool header */
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+
-+ /* We might leak fds without this hack */
-+ if (h->type != ZEND_HANDLE_FILENAME) {
-+ zend_llist_add_element(&CG(open_files), h);
-+ }
-+ return op_array;
-+ }
-+ if(APCG(report_autofilter)) {
-+ apc_warning("Autofiltering %s" TSRMLS_CC,
-+ (h->opened_path ? h->opened_path : h->filename));
-+ apc_warning("Recompiling %s" TSRMLS_CC, cache_entry->data.file.filename);
-+ }
-+ /* TODO: check what happens with EG(included_files) */
-+ }
-+
-+ /* Make sure the mtime reflects the files last known mtime, and we respect max_file_size in the case of fpstat==0 */
-+ if(key.type == APC_CACHE_KEY_FPFILE) {
-+ apc_fileinfo_t fileinfo;
-+ struct stat *tmp_buf = NULL;
-+ if(!strcmp(SG(request_info).path_translated, h->filename)) {
-+ tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */
-+ }
-+ if(tmp_buf) {
-+ fileinfo.st_buf.sb = *tmp_buf;
-+ } else {
-+ if (apc_search_paths(h->filename, PG(include_path), &fileinfo TSRMLS_CC) != 0) {
-+ apc_debug("Stat failed %s - bailing (%s) (%d)\n" TSRMLS_CC,h->filename,SG(request_info).path_translated);
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ }
-+ if (APCG(max_file_size) < fileinfo.st_buf.sb.st_size) {
-+ apc_debug("File is too big %s (%ld) - bailing\n" TSRMLS_CC, h->filename, fileinfo.st_buf.sb.st_size);
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ key.mtime = fileinfo.st_buf.sb.st_mtime;
-+ }
-+
-+ HANDLE_BLOCK_INTERRUPTIONS();
-+
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ if(APCG(write_lock)) {
-+ if(!apc_cache_write_lock(apc_cache TSRMLS_CC)) {
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+ return old_compile_file(h, type TSRMLS_CC);
-+ }
-+ }
-+#endif
-+
-+ zend_try {
-+ if (apc_compile_cache_entry(&key, h, type, t, &op_array, &cache_entry TSRMLS_CC) == SUCCESS) {
-+ ctxt.pool = cache_entry->pool;
-+ ctxt.copy = APC_COPY_IN_OPCODE;
-+ if (apc_cache_insert(apc_cache, key, cache_entry, &ctxt, t TSRMLS_CC) != 1) {
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ ctxt.pool = NULL;
-+ }
-+ }
-+ } zend_catch {
-+ bailout=1; /* in the event of a bailout, ensure we don't create a dead-lock */
-+ } zend_end_try();
-+
-+ APCG(current_cache) = NULL;
-+
-+#if NONBLOCKING_LOCK_AVAILABLE
-+ if(APCG(write_lock)) {
-+ apc_cache_write_unlock(apc_cache TSRMLS_CC);
-+ }
-+#endif
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+
-+ if (bailout) zend_bailout();
-+
-+ return op_array;
-+}
-+/* }}} */
-+
-+/* {{{ data preload */
-+
-+extern int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC);
-+
-+static zval* data_unserialize(const char *filename TSRMLS_DC)
-+{
-+ zval* retval;
-+ long len = 0;
-+ struct stat sb;
-+ char *contents, *tmp;
-+ FILE *fp;
-+ php_unserialize_data_t var_hash;
-+
-+ if(VCWD_STAT(filename, &sb) == -1) {
-+ return NULL;
-+ }
-+
-+ fp = fopen(filename, "rb");
-+
-+ len = sizeof(char)*sb.st_size;
-+
-+ tmp = contents = malloc(len);
-+
-+ if(!contents) {
-+ return NULL;
-+ }
-+
-+ if(fread(contents, 1, len, fp) < 1) {
-+ free(contents);
-+ return NULL;
-+ }
-+
-+ MAKE_STD_ZVAL(retval);
-+
-+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
-+
-+ /* I wish I could use json */
-+ if(!php_var_unserialize(&retval, (const unsigned char**)&tmp, (const unsigned char*)(contents+len), &var_hash TSRMLS_CC)) {
-+ zval_ptr_dtor(&retval);
-+ return NULL;
-+ }
-+
-+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-+
-+ free(contents);
-+ fclose(fp);
-+
-+ return retval;
-+}
-+
-+static int apc_load_data(const char *data_file TSRMLS_DC)
-+{
-+ char *p;
-+ char key[MAXPATHLEN] = {0,};
-+ unsigned int key_len;
-+ zval *data;
-+
-+ p = strrchr(data_file, DEFAULT_SLASH);
-+
-+ if(p && p[1]) {
-+ strlcpy(key, p+1, sizeof(key));
-+ p = strrchr(key, '.');
-+
-+ if(p) {
-+ p[0] = '\0';
-+ key_len = strlen(key);
-+
-+ data = data_unserialize(data_file TSRMLS_CC);
-+ if(data) {
-+ _apc_store(key, key_len, data, 0, 1 TSRMLS_CC);
-+ }
-+ return 1;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int apc_walk_dir(const char *path TSRMLS_DC)
-+{
-+ char file[MAXPATHLEN]={0,};
-+ int ndir, i;
-+ char *p = NULL;
-+ struct dirent **namelist = NULL;
-+
-+ if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0)
-+ {
-+ for (i = 0; i < ndir; i++)
-+ {
-+ /* check for extension */
-+ if (!(p = strrchr(namelist[i]->d_name, '.'))
-+ || (p && strcmp(p, ".data")))
-+ {
-+ free(namelist[i]);
-+ continue;
-+ }
-+ snprintf(file, MAXPATHLEN, "%s%c%s",
-+ path, DEFAULT_SLASH, namelist[i]->d_name);
-+ if(!apc_load_data(file TSRMLS_CC))
-+ {
-+ /* print error */
-+ }
-+ free(namelist[i]);
-+ }
-+ free(namelist);
-+ }
-+
-+ return 1;
-+}
-+
-+void apc_data_preload(TSRMLS_D)
-+{
-+ if(!APCG(preload_path)) return;
-+
-+ apc_walk_dir(APCG(preload_path) TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_serializer hooks */
-+static int _apc_register_serializer(const char* name, apc_serialize_t serialize,
-+ apc_unserialize_t unserialize,
-+ void *config TSRMLS_DC)
-+{
-+ int i;
-+ apc_serializer_t *serializer;
-+
-+ for(i = 0; i < APC_MAX_SERIALIZERS; i++) {
-+ serializer = &apc_serializers[i];
-+ if(!serializer->name) {
-+ /* empty entry */
-+ serializer->name = name; /* assumed to be const */
-+ serializer->serialize = serialize;
-+ serializer->unserialize = unserialize;
-+ serializer->config = config;
-+ apc_serializers[i+1].name = NULL;
-+ return 1;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+apc_serializer_t* apc_find_serializer(const char* name TSRMLS_DC)
-+{
-+ int i;
-+ apc_serializer_t *serializer;
-+
-+ for(i = 0; i < APC_MAX_SERIALIZERS; i++) {
-+ serializer = &apc_serializers[i];
-+ if(serializer->name && (strcmp(serializer->name, name) == 0)) {
-+ return serializer;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+apc_serializer_t* apc_get_serializers(TSRMLS_D)
-+{
-+ return &(apc_serializers[0]);
-+}
-+/* }}} */
-+
-+/* {{{ module init and shutdown */
-+
-+int apc_module_init(int module_number TSRMLS_DC)
-+{
-+ /* apc initialization */
-+#if APC_MMAP
-+ apc_sma_init(APCG(shm_segments), APCG(shm_size), APCG(mmap_file_mask) TSRMLS_CC);
-+#else
-+ apc_sma_init(APCG(shm_segments), APCG(shm_size), NULL TSRMLS_CC);
-+#endif
-+ apc_cache = apc_cache_create(APCG(num_files_hint), APCG(gc_ttl), APCG(ttl) TSRMLS_CC);
-+ apc_user_cache = apc_cache_create(APCG(user_entries_hint), APCG(gc_ttl), APCG(user_ttl) TSRMLS_CC);
-+
-+ /* override compilation */
-+ old_compile_file = zend_compile_file;
-+ zend_compile_file = my_compile_file;
-+ REGISTER_LONG_CONSTANT("\000apc_magic", (long)&set_compile_hook, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("\000apc_compile_file", (long)&my_compile_file, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT(APC_SERIALIZER_CONSTANT, (long)&_apc_register_serializer, CONST_PERSISTENT | CONST_CS);
-+
-+ /* test out the constant function pointer */
-+ apc_register_serializer("php", APC_SERIALIZER_NAME(php), APC_UNSERIALIZER_NAME(php), NULL TSRMLS_CC);
-+
-+ assert(apc_serializers[0].name != NULL);
-+
-+ apc_pool_init();
-+
-+ apc_data_preload(TSRMLS_C);
-+
-+#if APC_HAVE_LOOKUP_HOOKS
-+ if(APCG(lazy_functions)) {
-+ zend_set_lookup_function_hook(apc_lookup_function_hook TSRMLS_CC);
-+ zend_set_defined_function_hook(apc_defined_function_hook TSRMLS_CC);
-+ }
-+ if(APCG(lazy_classes)) {
-+ zend_set_lookup_class_hook(apc_lookup_class_hook TSRMLS_CC);
-+ zend_set_declared_class_hook(apc_declared_class_hook TSRMLS_CC);
-+ }
-+#else
-+ if(APCG(lazy_functions) || APCG(lazy_classes)) {
-+ apc_warning("Lazy function/class loading not available with this version of PHP, please disable APC lazy loading." TSRMLS_CC);
-+ APCG(lazy_functions) = APCG(lazy_classes) = 0;
-+ }
-+#endif
-+
-+#ifdef ZEND_ENGINE_2_4
-+#ifndef ZTS
-+ apc_interned_strings_init(TSRMLS_C);
-+#endif
-+#endif
-+
-+ APCG(initialized) = 1;
-+ return 0;
-+}
-+
-+int apc_module_shutdown(TSRMLS_D)
-+{
-+ if (!APCG(initialized))
-+ return 0;
-+
-+ /* restore compilation */
-+ zend_compile_file = old_compile_file;
-+
-+ /*
-+ * In case we got interrupted by a SIGTERM or something else during execution
-+ * we may have cache entries left on the stack that we need to check to make
-+ * sure that any functions or classes these may have added to the global function
-+ * and class tables are removed before we blow away the memory that hold them.
-+ *
-+ * This is merely to remove memory leak warnings - as the process is terminated
-+ * immediately after shutdown. The following while loop can be removed without
-+ * affecting anything else.
-+ */
-+ while (apc_stack_size(APCG(cache_stack)) > 0) {
-+ int i;
-+ apc_cache_entry_t* cache_entry = (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
-+ if (cache_entry->data.file.functions) {
-+ for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
-+ zend_hash_del(EG(function_table),
-+ cache_entry->data.file.functions[i].name,
-+ cache_entry->data.file.functions[i].name_len+1);
-+ }
-+ }
-+ if (cache_entry->data.file.classes) {
-+ for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-+ zend_hash_del(EG(class_table),
-+ cache_entry->data.file.classes[i].name,
-+ cache_entry->data.file.classes[i].name_len+1);
-+ }
-+ }
-+ apc_cache_release(apc_cache, cache_entry TSRMLS_CC);
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+#ifndef ZTS
-+ apc_interned_strings_shutdown(TSRMLS_C);
-+#endif
-+#endif
-+
-+ apc_cache_destroy(apc_cache TSRMLS_CC);
-+ apc_cache_destroy(apc_user_cache TSRMLS_CC);
-+ apc_sma_cleanup(TSRMLS_C);
-+
-+ APCG(initialized) = 0;
-+ return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ process init and shutdown */
-+int apc_process_init(int module_number TSRMLS_DC)
-+{
-+ return 0;
-+}
-+
-+int apc_process_shutdown(TSRMLS_D)
-+{
-+ return 0;
-+}
-+/* }}} */
-+
-+
-+/* {{{ apc_deactivate */
-+static void apc_deactivate(TSRMLS_D)
-+{
-+ /* The execution stack was unwound, which prevented us from decrementing
-+ * the reference counts on active cache entries in `my_execute`.
-+ */
-+ while (apc_stack_size(APCG(cache_stack)) > 0) {
-+ int i;
-+ zend_class_entry* zce = NULL;
-+ void ** centry = (void*)(&zce);
-+ zend_class_entry** pzce = NULL;
-+
-+ apc_cache_entry_t* cache_entry =
-+ (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
-+
-+ if (cache_entry->data.file.classes) {
-+ for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-+ centry = (void**)&pzce; /* a triple indirection to get zend_class_entry*** */
-+ if(zend_hash_find(EG(class_table),
-+ cache_entry->data.file.classes[i].name,
-+ cache_entry->data.file.classes[i].name_len+1,
-+ (void**)centry) == FAILURE)
-+ {
-+ /* double inclusion of conditional classes ends up failing
-+ * this lookup the second time around.
-+ */
-+ continue;
-+ }
-+
-+ zce = *pzce;
-+
-+ zend_hash_del(EG(class_table),
-+ cache_entry->data.file.classes[i].name,
-+ cache_entry->data.file.classes[i].name_len+1);
-+
-+ apc_free_class_entry_after_execution(zce TSRMLS_CC);
-+ }
-+ }
-+ apc_cache_release(apc_cache, cache_entry TSRMLS_CC);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ request init and shutdown */
-+
-+int apc_request_init(TSRMLS_D)
-+{
-+ apc_stack_clear(APCG(cache_stack));
-+ if (!APCG(compiled_filters) && APCG(filters)) {
-+ /* compile regex filters here to avoid race condition between MINIT of PCRE and APC.
-+ * This should be moved to apc_cache_create() if this race condition between modules is resolved */
-+ APCG(compiled_filters) = apc_regex_compile_array(APCG(filters) TSRMLS_CC);
-+ }
-+
-+ if (!APCG(serializer) && APCG(serializer_name)) {
-+ /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */
-+ APCG(serializer) = apc_find_serializer(APCG(serializer_name) TSRMLS_CC);
-+ }
-+
-+#if APC_HAVE_LOOKUP_HOOKS
-+ if(APCG(lazy_functions)) {
-+ APCG(lazy_function_table) = emalloc(sizeof(HashTable));
-+ zend_hash_init(APCG(lazy_function_table), 0, NULL, NULL, 0);
-+ }
-+ if(APCG(lazy_classes)) {
-+ APCG(lazy_class_table) = emalloc(sizeof(HashTable));
-+ zend_hash_init(APCG(lazy_class_table), 0, NULL, NULL, 0);
-+ }
-+#endif
-+
-+#ifdef APC_FILEHITS
-+ ALLOC_INIT_ZVAL(APCG(filehits));
-+ array_init(APCG(filehits));
-+#endif
-+
-+ return 0;
-+}
-+
-+int apc_request_shutdown(TSRMLS_D)
-+{
-+#if APC_HAVE_LOOKUP_HOOKS
-+ if(APCG(lazy_class_table)) {
-+ zend_hash_destroy(APCG(lazy_class_table));
-+ efree(APCG(lazy_class_table));
-+ }
-+ if(APCG(lazy_function_table)) {
-+ zend_hash_destroy(APCG(lazy_function_table));
-+ efree(APCG(lazy_function_table));
-+ }
-+#endif
-+
-+ apc_deactivate(TSRMLS_C);
-+
-+#ifdef APC_FILEHITS
-+ zval_ptr_dtor(&APCG(filehits));
-+#endif
-+ return 0;
-+}
-+
-+/* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_main.h b/ext/apc/apc_main.h
---- a/ext/apc/apc_main.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_main.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,88 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_main.h 308594 2011-02-23 12:35:33Z gopalv $ */
-+
-+#ifndef APC_MAIN_H
-+#define APC_MAIN_H
-+
-+#include "apc_pool.h"
-+#include "apc_serializer.h"
-+
-+/*
-+ * This module provides the primary interface between PHP and APC.
-+ */
-+
-+extern int apc_module_init(int module_number TSRMLS_DC);
-+extern int apc_module_shutdown(TSRMLS_D);
-+extern int apc_process_init(int module_number TSRMLS_DC);
-+extern int apc_process_shutdown(TSRMLS_D);
-+extern int apc_request_init(TSRMLS_D);
-+extern int apc_request_shutdown(TSRMLS_D);
-+
-+typedef enum _apc_copy_type {
-+ APC_NO_COPY = 0,
-+ APC_COPY_IN_OPCODE,
-+ APC_COPY_OUT_OPCODE,
-+ APC_COPY_IN_USER,
-+ APC_COPY_OUT_USER
-+} apc_copy_type;
-+
-+typedef struct _apc_context_t
-+{
-+ apc_pool *pool;
-+ apc_copy_type copy;
-+ unsigned int force_update:1;
-+} apc_context_t;
-+
-+/* {{{ struct apc_serializer_t */
-+typedef struct apc_serializer_t apc_serializer_t;
-+struct apc_serializer_t {
-+ const char *name;
-+ apc_serialize_t serialize;
-+ apc_unserialize_t unserialize;
-+ void *config;
-+};
-+/* }}} */
-+
-+apc_serializer_t* apc_get_serializers(TSRMLS_D);
-+apc_serializer_t* apc_find_serializer(const char* name TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_mmap.c b/ext/apc/apc_mmap.c
---- a/ext/apc/apc_mmap.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_mmap.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,177 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_mmap.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc.h"
-+#include "apc_mmap.h"
-+#include "apc_lock.h"
-+
-+#if APC_MMAP
-+
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#include <sys/mman.h>
-+
-+/*
-+ * Some operating systems (like FreeBSD) have a MAP_NOSYNC flag that
-+ * tells whatever update daemons might be running to not flush dirty
-+ * vm pages to disk unless absolutely necessary. My guess is that
-+ * most systems that don't have this probably default to only synching
-+ * to disk when absolutely necessary.
-+ */
-+#ifndef MAP_NOSYNC
-+#define MAP_NOSYNC 0
-+#endif
-+
-+/* support for systems where MAP_ANONYMOUS is defined but not MAP_ANON, ie: HP-UX bug #14615 */
-+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
-+# define MAP_ANON MAP_ANONYMOUS
-+#endif
-+
-+apc_segment_t apc_mmap(char *file_mask, size_t size TSRMLS_DC)
-+{
-+ apc_segment_t segment;
-+
-+ int fd = -1;
-+ int flags = MAP_SHARED | MAP_NOSYNC;
-+ int remap = 1;
-+
-+ /* If no filename was provided, do an anonymous mmap */
-+ if(!file_mask || (file_mask && !strlen(file_mask))) {
-+#if !defined(MAP_ANON)
-+ apc_error("Anonymous mmap does not apear to be available on this system (MAP_ANON/MAP_ANONYMOUS). Please see the apc.mmap_file_mask INI option." TSRMLS_CC);
-+#else
-+ fd = -1;
-+ flags = MAP_SHARED | MAP_ANON;
-+ remap = 0;
-+#endif
-+ } else if(!strcmp(file_mask,"/dev/zero")) {
-+ fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
-+ if(fd == -1) {
-+ apc_error("apc_mmap: open on /dev/zero failed:" TSRMLS_CC);
-+ goto error;
-+ }
-+ remap = 0; /* cannot remap */
-+ } else if(strstr(file_mask,".shm")) {
-+ /*
-+ * If the filemask contains .shm we try to do a POSIX-compliant shared memory
-+ * backed mmap which should avoid synchs on some platforms. At least on
-+ * FreeBSD this implies MAP_NOSYNC and on Linux it is equivalent of mmap'ing
-+ * a file in a mounted shmfs. For this to work on Linux you need to make sure
-+ * you actually have shmfs mounted. Also on Linux, make sure the file_mask you
-+ * pass in has a leading / and no other /'s. eg. /apc.shm.XXXXXX
-+ * On FreeBSD these are mapped onto the regular filesystem so you can put whatever
-+ * path you want here.
-+ */
-+ if(!mktemp(file_mask)) {
-+ apc_error("apc_mmap: mktemp on %s failed:" TSRMLS_CC, file_mask);
-+ goto error;
-+ }
-+ fd = shm_open(file_mask, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
-+ if(fd == -1) {
-+ apc_error("apc_mmap: shm_open on %s failed:" TSRMLS_CC, file_mask);
-+ goto error;
-+ }
-+ if (ftruncate(fd, size) < 0) {
-+ close(fd);
-+ shm_unlink(file_mask);
-+ apc_error("apc_mmap: ftruncate failed:" TSRMLS_CC);
-+ goto error;
-+ }
-+ shm_unlink(file_mask);
-+ } else {
-+ /*
-+ * Otherwise we do a normal filesystem mmap
-+ */
-+ fd = mkstemp(file_mask);
-+ if(fd == -1) {
-+ apc_error("apc_mmap: mkstemp on %s failed:" TSRMLS_CC, file_mask);
-+ goto error;
-+ }
-+ if (ftruncate(fd, size) < 0) {
-+ close(fd);
-+ unlink(file_mask);
-+ apc_error("apc_mmap: ftruncate failed:" TSRMLS_CC);
-+ goto error;
-+ }
-+ unlink(file_mask);
-+ }
-+
-+ segment.shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0);
-+ segment.size = size;
-+
-+#ifdef APC_MEMPROTECT
-+ if(remap) {
-+ segment.roaddr = (void *)mmap(NULL, size, PROT_READ, flags, fd, 0);
-+ } else {
-+ segment.roaddr = NULL;
-+ }
-+#endif
-+
-+ if((long)segment.shmaddr == -1) {
-+ apc_error("apc_mmap: mmap failed:" TSRMLS_CC);
-+ }
-+
-+ if(fd != -1) close(fd);
-+
-+ return segment;
-+
-+error:
-+
-+ segment.shmaddr = (void*)-1;
-+ segment.size = 0;
-+#ifdef APC_MEMPROTECT
-+ segment.roaddr = NULL;
-+#endif
-+ return segment;
-+}
-+
-+void apc_unmap(apc_segment_t *segment TSRMLS_DC)
-+{
-+ if (munmap(segment->shmaddr, segment->size) < 0) {
-+ apc_warning("apc_unmap: munmap failed:" TSRMLS_CC);
-+ }
-+
-+#ifdef APC_MEMPROTECT
-+ if (segment->roaddr && munmap(segment->roaddr, segment->size) < 0) {
-+ apc_warning("apc_unmap: munmap failed:" TSRMLS_CC);
-+ }
-+#endif
-+
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_mmap.h b/ext/apc/apc_mmap.h
---- a/ext/apc/apc_mmap.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_mmap.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,54 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal V <gopalv@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_mmap.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_MMAP_H
-+#define APC_MMAP_H
-+
-+#include <limits.h>
-+
-+#include "apc.h"
-+#include "apc_sma.h"
-+
-+/* Wrapper functions for shared memory mapped files */
-+
-+#if APC_MMAP
-+apc_segment_t apc_mmap(char *file_mask, size_t size TSRMLS_DC);
-+void apc_unmap(apc_segment_t* segment TSRMLS_DC);
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc.php b/ext/apc/apc.php
---- a/ext/apc/apc.php 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc.php 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,1362 @@
-+<?php
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Ralf Becker <beckerr@php.net> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Ilia Alshanetsky <ilia@prohost.org> |
-+ +----------------------------------------------------------------------+
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+$VERSION='$Id: apc.php 325483 2012-05-01 00:34:04Z rasmus $';
-+
-+////////// READ OPTIONAL CONFIGURATION FILE ////////////
-+if (file_exists("apc.conf.php")) include("apc.conf.php");
-+////////////////////////////////////////////////////////
-+
-+////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
-+
-+defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if
-+ // no other authentication is available
-+ // If set to 0:
-+ // There will be no further authentication. You
-+ // will have to handle this by yourself!
-+ // If set to 1:
-+ // You need to change ADMIN_PASSWORD to make
-+ // this work!
-+defaults('ADMIN_USERNAME','apc'); // Admin Username
-+defaults('ADMIN_PASSWORD','password'); // Admin Password - CHANGE THIS TO ENABLE!!!
-+
-+// (beckerr) I'm using a clear text password here, because I've no good idea how to let
-+// users generate a md5 or crypt password in a easy way to fill it in above
-+
-+//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
-+defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
-+
-+defaults('GRAPH_SIZE',200); // Image size
-+
-+//defaults('PROXY', 'tcp://127.0.0.1:8080');
-+
-+////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
-+
-+
-+// "define if not defined"
-+function defaults($d,$v) {
-+ if (!defined($d)) define($d,$v); // or just @define(...)
-+}
-+
-+// rewrite $PHP_SELF to block XSS attacks
-+//
-+$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : '';
-+$time = time();
-+$host = php_uname('n');
-+if($host) { $host = '('.$host.')'; }
-+if (isset($_SERVER['SERVER_ADDR'])) {
-+ $host .= ' ('.$_SERVER['SERVER_ADDR'].')';
-+}
-+
-+// operation constants
-+define('OB_HOST_STATS',1);
-+define('OB_SYS_CACHE',2);
-+define('OB_USER_CACHE',3);
-+define('OB_SYS_CACHE_DIR',4);
-+define('OB_VERSION_CHECK',9);
-+
-+// check validity of input variables
-+$vardom=array(
-+ 'OB' => '/^\d+$/', // operational mode switch
-+ 'CC' => '/^[01]$/', // clear cache requested
-+ 'DU' => '/^.*$/', // Delete User Key
-+ 'SH' => '/^[a-z0-9]+$/', // shared object description
-+
-+ 'IMG' => '/^[123]$/', // image to generate
-+ 'LO' => '/^1$/', // login requested
-+
-+ 'COUNT' => '/^\d+$/', // number of line displayed in list
-+ 'SCOPE' => '/^[AD]$/', // list view scope
-+ 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
-+ 'SORT2' => '/^[DA]$/', // second sort key
-+ 'AGGR' => '/^\d+$/', // aggregation by dir level
-+ 'SEARCH' => '~^[a-zA-Z0-9/_.-]*$~' // aggregation by dir level
-+);
-+
-+// default cache mode
-+$cache_mode='opcode';
-+
-+// cache scope
-+$scope_list=array(
-+ 'A' => 'cache_list',
-+ 'D' => 'deleted_list'
-+);
-+
-+// handle POST and GET requests
-+if (empty($_REQUEST)) {
-+ if (!empty($_GET) && !empty($_POST)) {
-+ $_REQUEST = array_merge($_GET, $_POST);
-+ } else if (!empty($_GET)) {
-+ $_REQUEST = $_GET;
-+ } else if (!empty($_POST)) {
-+ $_REQUEST = $_POST;
-+ } else {
-+ $_REQUEST = array();
-+ }
-+}
-+
-+// check parameter syntax
-+foreach($vardom as $var => $dom) {
-+ if (!isset($_REQUEST[$var])) {
-+ $MYREQUEST[$var]=NULL;
-+ } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) {
-+ $MYREQUEST[$var]=$_REQUEST[$var];
-+ } else {
-+ $MYREQUEST[$var]=$_REQUEST[$var]=NULL;
-+ }
-+}
-+
-+// check parameter sematics
-+if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
-+if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
-+if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
-+if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
-+if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
-+if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
-+
-+$MY_SELF=
-+ "$PHP_SELF".
-+ "?SCOPE=".$MYREQUEST['SCOPE'].
-+ "&SORT1=".$MYREQUEST['SORT1'].
-+ "&SORT2=".$MYREQUEST['SORT2'].
-+ "&COUNT=".$MYREQUEST['COUNT'];
-+$MY_SELF_WO_SORT=
-+ "$PHP_SELF".
-+ "?SCOPE=".$MYREQUEST['SCOPE'].
-+ "&COUNT=".$MYREQUEST['COUNT'];
-+
-+// authentication needed?
-+//
-+if (!USE_AUTHENTICATION) {
-+ $AUTHENTICATED=1;
-+} else {
-+ $AUTHENTICATED=0;
-+ if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
-+
-+ if (!isset($_SERVER['PHP_AUTH_USER']) ||
-+ !isset($_SERVER['PHP_AUTH_PW']) ||
-+ $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
-+ $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
-+ Header("WWW-Authenticate: Basic realm=\"APC Login\"");
-+ Header("HTTP/1.0 401 Unauthorized");
-+
-+ echo <<<EOB
-+ <html><body>
-+ <h1>Rejected!</h1>
-+ <big>Wrong Username or Password!</big><br/> <br/>
-+ <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
-+ </body></html>
-+EOB;
-+ exit;
-+
-+ } else {
-+ $AUTHENTICATED=1;
-+ }
-+ }
-+}
-+
-+// select cache mode
-+if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
-+ $cache_mode='user';
-+}
-+// clear cache
-+if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
-+ apc_clear_cache($cache_mode);
-+}
-+
-+if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
-+ apc_delete($MYREQUEST['DU']);
-+}
-+
-+if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
-+ echo "No cache info available. APC does not appear to be running.";
-+ exit;
-+}
-+
-+$cache_user = apc_cache_info('user', 1);
-+$mem=apc_sma_info();
-+if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
-+
-+// don't cache this page
-+//
-+header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
-+header("Cache-Control: post-check=0, pre-check=0", false);
-+header("Pragma: no-cache"); // HTTP/1.0
-+
-+function duration($ts) {
-+ global $time;
-+ $years = (int)((($time - $ts)/(7*86400))/52.177457);
-+ $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
-+ $weeks = (int)(($rem)/(7*86400));
-+ $days = (int)(($rem)/86400) - $weeks*7;
-+ $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
-+ $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
-+ $str = '';
-+ if($years==1) $str .= "$years year, ";
-+ if($years>1) $str .= "$years years, ";
-+ if($weeks==1) $str .= "$weeks week, ";
-+ if($weeks>1) $str .= "$weeks weeks, ";
-+ if($days==1) $str .= "$days day,";
-+ if($days>1) $str .= "$days days,";
-+ if($hours == 1) $str .= " $hours hour and";
-+ if($hours>1) $str .= " $hours hours and";
-+ if($mins == 1) $str .= " 1 minute";
-+ else $str .= " $mins minutes";
-+ return $str;
-+}
-+
-+// create graphics
-+//
-+function graphics_avail() {
-+ return extension_loaded('gd');
-+}
-+if (isset($MYREQUEST['IMG']))
-+{
-+ if (!graphics_avail()) {
-+ exit(0);
-+ }
-+
-+ function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
-+ $r=$diameter/2;
-+ $w=deg2rad((360+$start+($end-$start)/2)%360);
-+
-+
-+ if (function_exists("imagefilledarc")) {
-+ // exists only if GD 2.0.1 is avaliable
-+ imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
-+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
-+ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
-+ } else {
-+ imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
-+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
-+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
-+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
-+ imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
-+ imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
-+ }
-+ if ($text) {
-+ if ($placeindex>0) {
-+ imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
-+ imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
-+
-+ } else {
-+ imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
-+ }
-+ }
-+ }
-+
-+ function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
-+ $r=$diameter/2;
-+ $w=deg2rad((360+$start+($end-$start)/2)%360);
-+
-+ if ($placeindex>0) {
-+ imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
-+ imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
-+
-+ } else {
-+ imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
-+ }
-+ }
-+
-+ function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
-+ global $col_black;
-+ $x1=$x+$w-1;
-+ $y1=$y+$h-1;
-+
-+ imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
-+ if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
-+ else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
-+ imagerectangle($im, $x, $y1, $x1, $y, $color1);
-+ if ($text) {
-+ if ($placeindex>0) {
-+
-+ if ($placeindex<16)
-+ {
-+ $px=5;
-+ $py=$placeindex*12+6;
-+ imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
-+ imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
-+ imagestring($im,2,$px,$py-6,$text,$color1);
-+
-+ } else {
-+ if ($placeindex<31) {
-+ $px=$x+40*2;
-+ $py=($placeindex-15)*12+6;
-+ } else {
-+ $px=$x+40*2+100*intval(($placeindex-15)/15);
-+ $py=($placeindex%15)*12+6;
-+ }
-+ imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
-+ imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
-+ imagestring($im,2,$px+2,$py-6,$text,$color1);
-+ }
-+ } else {
-+ imagestring($im,4,$x+5,$y1-16,$text,$color1);
-+ }
-+ }
-+ }
-+
-+
-+ $size = GRAPH_SIZE; // image size
-+ if ($MYREQUEST['IMG']==3)
-+ $image = imagecreate(2*$size+150, $size+10);
-+ else
-+ $image = imagecreate($size+50, $size+10);
-+
-+ $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
-+ $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
-+ $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
-+ $col_black = imagecolorallocate($image, 0, 0, 0);
-+ imagecolortransparent($image,$col_white);
-+
-+ switch ($MYREQUEST['IMG']) {
-+
-+ case 1:
-+ $s=$mem['num_seg']*$mem['seg_size'];
-+ $a=$mem['avail_mem'];
-+ $x=$y=$size/2;
-+ $fuzz = 0.000001;
-+
-+ // This block of code creates the pie chart. It is a lot more complex than you
-+ // would expect because we try to visualize any memory fragmentation as well.
-+ $angle_from = 0;
-+ $string_placement=array();
-+ for($i=0; $i<$mem['num_seg']; $i++) {
-+ $ptr = 0;
-+ $free = $mem['block_lists'][$i];
-+ uasort($free, 'block_sort');
-+ foreach($free as $block) {
-+ if($block['offset']!=$ptr) { // Used block
-+ $angle_to = $angle_from+($block['offset']-$ptr)/$s;
-+ if(($angle_to+$fuzz)>1) $angle_to = 1;
-+ if( ($angle_to*360) - ($angle_from*360) >= 1) {
-+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
-+ if (($angle_to-$angle_from)>0.05) {
-+ array_push($string_placement, array($angle_from,$angle_to));
-+ }
-+ }
-+ $angle_from = $angle_to;
-+ }
-+ $angle_to = $angle_from+($block['size'])/$s;
-+ if(($angle_to+$fuzz)>1) $angle_to = 1;
-+ if( ($angle_to*360) - ($angle_from*360) >= 1) {
-+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
-+ if (($angle_to-$angle_from)>0.05) {
-+ array_push($string_placement, array($angle_from,$angle_to));
-+ }
-+ }
-+ $angle_from = $angle_to;
-+ $ptr = $block['offset']+$block['size'];
-+ }
-+ if ($ptr < $mem['seg_size']) { // memory at the end
-+ $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
-+ if(($angle_to+$fuzz)>1) $angle_to = 1;
-+ fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
-+ if (($angle_to-$angle_from)>0.05) {
-+ array_push($string_placement, array($angle_from,$angle_to));
-+ }
-+ }
-+ }
-+ foreach ($string_placement as $angle) {
-+ text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
-+ }
-+ break;
-+
-+ case 2:
-+ $s=$cache['num_hits']+$cache['num_misses'];
-+ $a=$cache['num_hits'];
-+
-+ fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
-+ fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
-+ break;
-+
-+ case 3:
-+ $s=$mem['num_seg']*$mem['seg_size'];
-+ $a=$mem['avail_mem'];
-+ $x=130;
-+ $y=1;
-+ $j=1;
-+
-+ // This block of code creates the bar chart. It is a lot more complex than you
-+ // would expect because we try to visualize any memory fragmentation as well.
-+ for($i=0; $i<$mem['num_seg']; $i++) {
-+ $ptr = 0;
-+ $free = $mem['block_lists'][$i];
-+ uasort($free, 'block_sort');
-+ foreach($free as $block) {
-+ if($block['offset']!=$ptr) { // Used block
-+ $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
-+ if ($h>0) {
-+ $j++;
-+ if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
-+ else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
-+ }
-+ $y+=$h;
-+ }
-+ $h=(GRAPH_SIZE-5)*($block['size'])/$s;
-+ if ($h>0) {
-+ $j++;
-+ if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
-+ else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
-+ }
-+ $y+=$h;
-+ $ptr = $block['offset']+$block['size'];
-+ }
-+ if ($ptr < $mem['seg_size']) { // memory at the end
-+ $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
-+ if ($h > 0) {
-+ fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
-+ }
-+ }
-+ }
-+ break;
-+ case 4:
-+ $s=$cache['num_hits']+$cache['num_misses'];
-+ $a=$cache['num_hits'];
-+
-+ fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
-+ fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
-+ break;
-+
-+ }
-+ header("Content-type: image/png");
-+ imagepng($image);
-+ exit;
-+}
-+
-+// pretty printer for byte values
-+//
-+function bsize($s) {
-+ foreach (array('','K','M','G') as $i => $k) {
-+ if ($s < 1024) break;
-+ $s/=1024;
-+ }
-+ return sprintf("%5.1f %sBytes",$s,$k);
-+}
-+
-+// sortable table header in "scripts for this host" view
-+function sortheader($key,$name,$extra='') {
-+ global $MYREQUEST, $MY_SELF_WO_SORT;
-+
-+ if ($MYREQUEST['SORT1']==$key) {
-+ $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
-+ }
-+ return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
-+
-+}
-+
-+// create menu entry
-+function menu_entry($ob,$title) {
-+ global $MYREQUEST,$MY_SELF;
-+ if ($MYREQUEST['OB']!=$ob) {
-+ return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
-+ } else if (empty($MYREQUEST['SH'])) {
-+ return "<li><span class=active>$title</span></li>";
-+ } else {
-+ return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
-+ }
-+}
-+
-+function put_login_link($s="Login")
-+{
-+ global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
-+ // needs ADMIN_PASSWORD to be changed!
-+ //
-+ if (!USE_AUTHENTICATION) {
-+ return;
-+ } else if (ADMIN_PASSWORD=='password')
-+ {
-+ print <<<EOB
-+ <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
-+EOB;
-+ } else if ($AUTHENTICATED) {
-+ print <<<EOB
-+ '{$_SERVER['PHP_AUTH_USER']}' logged in!
-+EOB;
-+ } else{
-+ print <<<EOB
-+ <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
-+EOB;
-+ }
-+}
-+
-+function block_sort($array1, $array2)
-+{
-+ if ($array1['offset'] > $array2['offset']) {
-+ return 1;
-+ } else {
-+ return -1;
-+ }
-+}
-+
-+
-+?>
-+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-+<html>
-+<head><title>APC INFO <?php echo $host ?></title>
-+<style><!--
-+body { background:white; font-size:100.01%; margin:0; padding:0; }
-+body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
-+* html body {font-size:0.8em}
-+* html p {font-size:0.8em}
-+* html td {font-size:0.8em}
-+* html th {font-size:0.8em}
-+* html input {font-size:0.8em}
-+* html submit {font-size:0.8em}
-+td { vertical-align:top }
-+a { color:black; font-weight:none; text-decoration:none; }
-+a:hover { text-decoration:underline; }
-+div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
-+
-+
-+div.head div.login {
-+ position:absolute;
-+ right: 1em;
-+ top: 1.2em;
-+ color:white;
-+ width:6em;
-+ }
-+div.head div.login a {
-+ position:absolute;
-+ right: 0em;
-+ background:rgb(119,123,180);
-+ border:solid rgb(102,102,153) 2px;
-+ color:white;
-+ font-weight:bold;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ text-decoration:none;
-+ }
-+div.head div.login a:hover {
-+ background:rgb(193,193,244);
-+ }
-+
-+h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
-+* html h1.apc { margin-bottom:-7px; }
-+h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
-+h1.apc div.logo span.logo {
-+ background:rgb(119,123,180);
-+ color:black;
-+ border-right: solid black 1px;
-+ border-bottom: solid black 1px;
-+ font-style:italic;
-+ font-size:1em;
-+ padding-left:1.2em;
-+ padding-right:1.2em;
-+ text-align:right;
-+ }
-+h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
-+h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
-+h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
-+hr.apc {
-+ background:white;
-+ border-bottom:solid rgb(102,102,153) 1px;
-+ border-style:none;
-+ border-top:solid rgb(102,102,153) 10px;
-+ height:12px;
-+ margin:0;
-+ margin-top:1px;
-+ padding:0;
-+}
-+
-+ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
-+ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
-+ol.menu a {
-+ background:rgb(153,153,204);
-+ border:solid rgb(102,102,153) 2px;
-+ color:white;
-+ font-weight:bold;
-+ margin-right:0em;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ text-decoration:none;
-+ margin-left: 5px;
-+ }
-+ol.menu a.child_active {
-+ background:rgb(153,153,204);
-+ border:solid rgb(102,102,153) 2px;
-+ color:white;
-+ font-weight:bold;
-+ margin-right:0em;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ text-decoration:none;
-+ border-left: solid black 5px;
-+ margin-left: 0px;
-+ }
-+ol.menu span.active {
-+ background:rgb(153,153,204);
-+ border:solid rgb(102,102,153) 2px;
-+ color:black;
-+ font-weight:bold;
-+ margin-right:0em;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ text-decoration:none;
-+ border-left: solid black 5px;
-+ }
-+ol.menu span.inactive {
-+ background:rgb(193,193,244);
-+ border:solid rgb(182,182,233) 2px;
-+ color:white;
-+ font-weight:bold;
-+ margin-right:0em;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ text-decoration:none;
-+ margin-left: 5px;
-+ }
-+ol.menu a:hover {
-+ background:rgb(193,193,244);
-+ text-decoration:none;
-+ }
-+
-+
-+div.info {
-+ background:rgb(204,204,204);
-+ border:solid rgb(204,204,204) 1px;
-+ margin-bottom:1em;
-+ }
-+div.info h2 {
-+ background:rgb(204,204,204);
-+ color:black;
-+ font-size:1em;
-+ margin:0;
-+ padding:0.1em 1em 0.1em 1em;
-+ }
-+div.info table {
-+ border:solid rgb(204,204,204) 1px;
-+ border-spacing:0;
-+ width:100%;
-+ }
-+div.info table th {
-+ background:rgb(204,204,204);
-+ color:white;
-+ margin:0;
-+ padding:0.1em 1em 0.1em 1em;
-+ }
-+div.info table th a.sortable { color:black; }
-+div.info table tr.tr-0 { background:rgb(238,238,238); }
-+div.info table tr.tr-1 { background:rgb(221,221,221); }
-+div.info table td { padding:0.3em 1em 0.3em 1em; }
-+div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
-+div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
-+div.info table td h3 {
-+ color:black;
-+ font-size:1.1em;
-+ margin-left:-0.3em;
-+ }
-+
-+div.graph { margin-bottom:1em }
-+div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
-+div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
-+div.graph table td.td-0 { background:rgb(238,238,238); }
-+div.graph table td.td-1 { background:rgb(221,221,221); }
-+div.graph table td { padding:0.2em 1em 0.4em 1em; }
-+
-+div.div1,div.div2 { margin-bottom:1em; width:35em; }
-+div.div3 { position:absolute; left:40em; top:1em; width:580px; }
-+//div.div3 { position:absolute; left:37em; top:1em; right:1em; }
-+
-+div.sorting { margin:1.5em 0em 1.5em 2em }
-+.center { text-align:center }
-+.aright { position:absolute;right:1em }
-+.right { text-align:right }
-+.ok { color:rgb(0,200,0); font-weight:bold}
-+.failed { color:rgb(200,0,0); font-weight:bold}
-+
-+span.box {
-+ border: black solid 1px;
-+ border-right:solid black 2px;
-+ border-bottom:solid black 2px;
-+ padding:0 0.5em 0 0.5em;
-+ margin-right:1em;
-+}
-+span.green { background:#60F060; padding:0 0.5em 0 0.5em}
-+span.red { background:#D06030; padding:0 0.5em 0 0.5em }
-+
-+div.authneeded {
-+ background:rgb(238,238,238);
-+ border:solid rgb(204,204,204) 1px;
-+ color:rgb(200,0,0);
-+ font-size:1.2em;
-+ font-weight:bold;
-+ padding:2em;
-+ text-align:center;
-+ }
-+
-+input {
-+ background:rgb(153,153,204);
-+ border:solid rgb(102,102,153) 2px;
-+ color:white;
-+ font-weight:bold;
-+ margin-right:1em;
-+ padding:0.1em 0.5em 0.1em 0.5em;
-+ }
-+//-->
-+</style>
-+</head>
-+<body>
-+<div class="head">
-+ <h1 class="apc">
-+ <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
-+ <div class="nameinfo">Opcode Cache</div>
-+ </h1>
-+ <div class="login">
-+ <?php put_login_link(); ?>
-+ </div>
-+ <hr class="apc">
-+</div>
-+<?php
-+
-+
-+// Display main Menu
-+echo <<<EOB
-+ <ol class=menu>
-+ <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
-+EOB;
-+echo
-+ menu_entry(1,'View Host Stats'),
-+ menu_entry(2,'System Cache Entries');
-+if ($AUTHENTICATED) {
-+ echo menu_entry(4,'Per-Directory Entries');
-+}
-+echo
-+ menu_entry(3,'User Cache Entries'),
-+ menu_entry(9,'Version Check');
-+
-+if ($AUTHENTICATED) {
-+ echo <<<EOB
-+ <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascript:return confirm('Are you sure?');">Clear $cache_mode Cache</a></li>
-+EOB;
-+}
-+echo <<<EOB
-+ </ol>
-+EOB;
-+
-+
-+// CONTENT
-+echo <<<EOB
-+ <div class=content>
-+EOB;
-+
-+// MAIN SWITCH STATEMENT
-+
-+switch ($MYREQUEST['OB']) {
-+
-+
-+
-+
-+
-+// -----------------------------------------------
-+// Host Stats
-+// -----------------------------------------------
-+case OB_HOST_STATS:
-+ $mem_size = $mem['num_seg']*$mem['seg_size'];
-+ $mem_avail= $mem['avail_mem'];
-+ $mem_used = $mem_size-$mem_avail;
-+ $seg_size = bsize($mem['seg_size']);
-+ $req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
-+ $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
-+ $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
-+ $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
-+ $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
-+ $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
-+ $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
-+ $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
-+ $apcversion = phpversion('apc');
-+ $phpversion = phpversion();
-+ $number_files = $cache['num_entries'];
-+ $size_files = bsize($cache['mem_size']);
-+ $number_vars = $cache_user['num_entries'];
-+ $size_vars = bsize($cache_user['mem_size']);
-+ $i=0;
-+ echo <<< EOB
-+ <div class="info div1"><h2>General Cache Information</h2>
-+ <table cellspacing=0><tbody>
-+ <tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
-+ <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
-+EOB;
-+
-+ if(!empty($_SERVER['SERVER_NAME']))
-+ echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
-+ if(!empty($_SERVER['SERVER_SOFTWARE']))
-+ echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
-+
-+ echo <<<EOB
-+ <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
-+ <br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
-+ </td></tr>
-+EOB;
-+ echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
-+ echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
-+ echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
-+ echo <<<EOB
-+ </tbody></table>
-+ </div>
-+
-+ <div class="info div1"><h2>File Cache Information</h2>
-+ <table cellspacing=0><tbody>
-+ <tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
-+ <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
-+ <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
-+ <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
-+ <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
-+ <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
-+ <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
-+ <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
-+ </tbody></table>
-+ </div>
-+
-+ <div class="info div1"><h2>User Cache Information</h2>
-+ <table cellspacing=0><tbody>
-+ <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
-+ <tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
-+ <tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
-+ <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
-+ <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
-+ <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
-+ <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
-+ <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
-+
-+ </tbody></table>
-+ </div>
-+
-+ <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
-+EOB;
-+
-+ $j = 0;
-+ foreach (ini_get_all('apc') as $k => $v) {
-+ echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
-+ $j = 1 - $j;
-+ }
-+
-+ if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
-+ $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
-+ else
-+ $mem_note = "Memory Usage";
-+
-+ echo <<< EOB
-+ </tbody></table>
-+ </div>
-+
-+ <div class="graph div3"><h2>Host Status Diagrams</h2>
-+ <table cellspacing=0><tbody>
-+EOB;
-+ $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
-+ echo <<<EOB
-+ <tr>
-+ <td class=td-0>$mem_note</td>
-+ <td class=td-1>Hits & Misses</td>
-+ </tr>
-+EOB;
-+
-+ echo
-+ graphics_avail() ?
-+ '<tr>'.
-+ "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
-+ "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
-+ : "",
-+ '<tr>',
-+ '<td class=td-0><span class="green box"> </span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
-+ '<td class=td-1><span class="green box"> </span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
-+ '</tr>',
-+ '<tr>',
-+ '<td class=td-0><span class="red box"> </span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
-+ '<td class=td-1><span class="red box"> </span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
-+ echo <<< EOB
-+ </tr>
-+ </tbody></table>
-+
-+ <br/>
-+ <h2>Detailed Memory Usage and Fragmentation</h2>
-+ <table cellspacing=0><tbody>
-+ <tr>
-+ <td class=td-0 colspan=2><br/>
-+EOB;
-+
-+ // Fragementation: (freeseg - 1) / total_seg
-+ $nseg = $freeseg = $fragsize = $freetotal = 0;
-+ for($i=0; $i<$mem['num_seg']; $i++) {
-+ $ptr = 0;
-+ foreach($mem['block_lists'][$i] as $block) {
-+ if ($block['offset'] != $ptr) {
-+ ++$nseg;
-+ }
-+ $ptr = $block['offset'] + $block['size'];
-+ /* Only consider blocks <5M for the fragmentation % */
-+ if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
-+ $freetotal+=$block['size'];
-+ }
-+ $freeseg += count($mem['block_lists'][$i]);
-+ }
-+
-+ if ($freeseg > 1) {
-+ $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
-+ } else {
-+ $frag = "0%";
-+ }
-+
-+ if (graphics_avail()) {
-+ $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
-+ echo <<<EOB
-+ <img alt="" $size src="$PHP_SELF?IMG=3&$time">
-+EOB;
-+ }
-+ echo <<<EOB
-+ </br>Fragmentation: $frag
-+ </td>
-+ </tr>
-+EOB;
-+ if(isset($mem['adist'])) {
-+ foreach($mem['adist'] as $i=>$v) {
-+ $cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
-+ if($i==0) $range = "1";
-+ else $range = "$cur - $nxt";
-+ echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
-+ }
-+ }
-+ echo <<<EOB
-+ </tbody></table>
-+ </div>
-+EOB;
-+
-+ break;
-+
-+
-+// -----------------------------------------------
-+// User Cache Entries
-+// -----------------------------------------------
-+case OB_USER_CACHE:
-+ if (!$AUTHENTICATED) {
-+ echo '<div class="error">You need to login to see the user values here!<br/> <br/>';
-+ put_login_link("Login now!");
-+ echo '</div>';
-+ break;
-+ }
-+ $fieldname='info';
-+ $fieldheading='User Entry Label';
-+ $fieldkey='info';
-+
-+// -----------------------------------------------
-+// System Cache Entries
-+// -----------------------------------------------
-+case OB_SYS_CACHE:
-+ if (!isset($fieldname))
-+ {
-+ $fieldname='filename';
-+ $fieldheading='Script Filename';
-+ if(ini_get("apc.stat")) $fieldkey='inode';
-+ else $fieldkey='filename';
-+ }
-+ if (!empty($MYREQUEST['SH']))
-+ {
-+ echo <<< EOB
-+ <div class="info"><table cellspacing=0><tbody>
-+ <tr><th>Attribute</th><th>Value</th></tr>
-+EOB;
-+
-+ $m=0;
-+ foreach($scope_list as $j => $list) {
-+ foreach($cache[$list] as $i => $entry) {
-+ if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
-+ foreach($entry as $k => $value) {
-+ if (!$AUTHENTICATED) {
-+ // hide all path entries if not logged in
-+ $value=preg_replace('/^.*(\\/|\\\\)/','<i><hidden></i>/',$value);
-+ }
-+
-+ if ($k == "num_hits") {
-+ $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
-+ }
-+ if ($k == 'deletion_time') {
-+ if(!$entry['deletion_time']) $value = "None";
-+ }
-+ echo
-+ "<tr class=tr-$m>",
-+ "<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
-+ "<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8'),"</td>",
-+ "</tr>";
-+ $m=1-$m;
-+ }
-+ if($fieldkey=='info') {
-+ echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
-+ $output = var_export(apc_fetch($entry[$fieldkey]),true);
-+ echo htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
-+ echo "</pre></td></tr>\n";
-+ }
-+ break;
-+ }
-+ }
-+
-+ echo <<<EOB
-+ </tbody></table>
-+ </div>
-+EOB;
-+ break;
-+ }
-+
-+ $cols=6;
-+ echo <<<EOB
-+ <div class=sorting><form>Scope:
-+ <input type=hidden name=OB value={$MYREQUEST['OB']}>
-+ <select name=SCOPE>
-+EOB;
-+ echo
-+ "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
-+ "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
-+ "</select>",
-+ ", Sorting:<select name=SORT1>",
-+ "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
-+ "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
-+ "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
-+ "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
-+ "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
-+ "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
-+ "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
-+ if($fieldname=='info') echo
-+ "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
-+ echo
-+ '</select>',
-+ '<select name=SORT2>',
-+ '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
-+ '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
-+ '</select>',
-+ '<select name=COUNT onChange="form.submit()">',
-+ '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
-+ '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
-+ '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
-+ '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
-+ '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
-+ '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
-+ '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
-+ '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
-+ '</select>',
-+ ' Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
-+ ' <input type=submit value="GO!">',
-+ '</form></div>';
-+
-+ if (isset($MYREQUEST['SEARCH'])) {
-+ // Don't use preg_quote because we want the user to be able to specify a
-+ // regular expression subpattern.
-+ $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i';
-+ if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
-+ echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
-+ break;
-+ }
-+ }
-+
-+ echo
-+ '<div class="info"><table cellspacing=0><tbody>',
-+ '<tr>',
-+ '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
-+
-+ if($fieldname=='info') {
-+ $cols+=2;
-+ echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
-+ }
-+ echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
-+
-+ // builds list with alpha numeric sortable keys
-+ //
-+ $list = array();
-+ foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
-+ switch($MYREQUEST['SORT1']) {
-+ case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
-+ case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
-+ case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
-+ case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
-+ case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
-+ case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
-+ case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
-+ case 'S': $k=''; break;
-+ }
-+ if (!$AUTHENTICATED) {
-+ // hide all path entries if not logged in
-+ $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry);
-+ } else {
-+ $list[$k.$entry[$fieldname]]=$entry;
-+ }
-+ }
-+
-+ if ($list) {
-+
-+ // sort list
-+ //
-+ switch ($MYREQUEST['SORT2']) {
-+ case "A": krsort($list); break;
-+ case "D": ksort($list); break;
-+ }
-+
-+ // output list
-+ $i=0;
-+ foreach($list as $k => $entry) {
-+ if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
-+ $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8');
-+ echo
-+ '<tr class=tr-',$i%2,'>',
-+ "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$field_value,'</a></td>',
-+ '<td class="td-n center">',$entry['num_hits'],'</td>',
-+ '<td class="td-n right">',$entry['mem_size'],'</td>',
-+ '<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
-+ '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
-+ '<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
-+
-+ if($fieldname=='info') {
-+ if($entry['ttl'])
-+ echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
-+ else
-+ echo '<td class="td-n center">None</td>';
-+ }
-+ if ($entry['deletion_time']) {
-+
-+ echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>';
-+ } else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
-+
-+ echo '<td class="td-last center">';
-+ echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
-+ echo '</td>';
-+ } else {
-+ echo '<td class="td-last center"> </td>';
-+ }
-+ echo '</tr>';
-+ $i++;
-+ if ($i == $MYREQUEST['COUNT'])
-+ break;
-+ }
-+ }
-+
-+ } else {
-+ echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
-+ }
-+ echo <<< EOB
-+ </tbody></table>
-+EOB;
-+
-+ if ($list && $i < count($list)) {
-+ echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
-+ }
-+
-+ echo <<< EOB
-+ </div>
-+EOB;
-+ break;
-+
-+
-+// -----------------------------------------------
-+// Per-Directory System Cache Entries
-+// -----------------------------------------------
-+case OB_SYS_CACHE_DIR:
-+ if (!$AUTHENTICATED) {
-+ break;
-+ }
-+
-+ echo <<<EOB
-+ <div class=sorting><form>Scope:
-+ <input type=hidden name=OB value={$MYREQUEST['OB']}>
-+ <select name=SCOPE>
-+EOB;
-+ echo
-+ "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
-+ "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
-+ "</select>",
-+ ", Sorting:<select name=SORT1>",
-+ "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
-+ "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
-+ "<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
-+ "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
-+ "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
-+ "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
-+ '</select>',
-+ '<select name=SORT2>',
-+ '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
-+ '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
-+ '</select>',
-+ '<select name=COUNT onChange="form.submit()">',
-+ '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
-+ '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
-+ '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
-+ '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
-+ '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
-+ '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
-+ '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
-+ '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
-+ '</select>',
-+ ", Group By Dir Level:<select name=AGGR>",
-+ "<option value='' selected>None</option>";
-+ for ($i = 1; $i < 10; $i++)
-+ echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
-+ echo '</select>',
-+ ' <input type=submit value="GO!">',
-+ '</form></div>',
-+
-+ '<div class="info"><table cellspacing=0><tbody>',
-+ '<tr>',
-+ '<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
-+ '</tr>';
-+
-+ // builds list with alpha numeric sortable keys
-+ //
-+ $tmp = $list = array();
-+ foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
-+ $n = dirname($entry['filename']);
-+ if ($MYREQUEST['AGGR'] > 0) {
-+ $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
-+ }
-+ if (!isset($tmp[$n])) {
-+ $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
-+ }
-+ $tmp[$n]['hits'] += $entry['num_hits'];
-+ $tmp[$n]['size'] += $entry['mem_size'];
-+ ++$tmp[$n]['ents'];
-+ }
-+
-+ foreach ($tmp as $k => $v) {
-+ switch($MYREQUEST['SORT1']) {
-+ case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
-+ case 'T': $kn=sprintf('%015d-',$v['ents']); break;
-+ case 'H': $kn=sprintf('%015d-',$v['hits']); break;
-+ case 'Z': $kn=sprintf('%015d-',$v['size']); break;
-+ case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
-+ case 'S': $kn = $k; break;
-+ }
-+ $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
-+ }
-+
-+ if ($list) {
-+
-+ // sort list
-+ //
-+ switch ($MYREQUEST['SORT2']) {
-+ case "A": krsort($list); break;
-+ case "D": ksort($list); break;
-+ }
-+
-+ // output list
-+ $i = 0;
-+ foreach($list as $entry) {
-+ echo
-+ '<tr class=tr-',$i%2,'>',
-+ "<td class=td-0>",$entry[0],'</a></td>',
-+ '<td class="td-n center">',$entry[1],'</td>',
-+ '<td class="td-n center">',$entry[2],'</td>',
-+ '<td class="td-n center">',$entry[3],'</td>',
-+ '<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
-+ '<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
-+ '</tr>';
-+
-+ if (++$i == $MYREQUEST['COUNT']) break;
-+ }
-+
-+ } else {
-+ echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
-+ }
-+ echo <<< EOB
-+ </tbody></table>
-+EOB;
-+
-+ if ($list && $i < count($list)) {
-+ echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
-+ }
-+
-+ echo <<< EOB
-+ </div>
-+EOB;
-+ break;
-+
-+// -----------------------------------------------
-+// Version check
-+// -----------------------------------------------
-+case OB_VERSION_CHECK:
-+ echo <<<EOB
-+ <div class="info"><h2>APC Version Information</h2>
-+ <table cellspacing=0><tbody>
-+ <tr>
-+ <th></th>
-+ </tr>
-+EOB;
-+ if (defined('PROXY')) {
-+ $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) );
-+ $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt);
-+ } else {
-+ $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
-+ }
-+ if (!$rss) {
-+ echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
-+ } else {
-+ $apcversion = phpversion('apc');
-+
-+ preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
-+ echo '<tr class="tr-0 center"><td>';
-+ if (version_compare($apcversion, $match[1], '>=')) {
-+ echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
-+ $i = 3;
-+ } else {
-+ echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
-+ newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
-+ http://pecl.php.net/package/APC/'.$match[1].'</a>
-+ </div>';
-+ $i = -1;
-+ }
-+ echo '</td></tr>';
-+ echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
-+
-+ preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
-+ next($match[2]); next($match[2]);
-+
-+ while (list(,$v) = each($match[2])) {
-+ list(,$ver) = explode(' ', $v, 2);
-+ if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
-+ break;
-+ } else if (!$i--) {
-+ break;
-+ }
-+ echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>";
-+ echo nl2br(htmlspecialchars(current($match[2]), ENT_QUOTES, 'UTF-8'))."</blockquote>";
-+ next($match[2]);
-+ }
-+ echo '</td></tr>';
-+ }
-+ echo <<< EOB
-+ </tbody></table>
-+ </div>
-+EOB;
-+ break;
-+
-+}
-+
-+echo <<< EOB
-+ </div>
-+EOB;
-+
-+?>
-+
-+<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
-+</body>
-+</html>
-diff -Naur a/ext/apc/apc_php.h b/ext/apc/apc_php.h
---- a/ext/apc/apc_php.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_php.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,81 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ | Arun C. Murthy <arunc@yahoo-inc.com> |
-+ | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_php.h 313808 2011-07-28 06:17:10Z gopalv $ */
-+
-+#ifndef APC_PHP_H
-+#define APC_PHP_H
-+
-+/*
-+ * The purpose of this header file is to include all PHP and Zend headers that
-+ * are typically needed elsewhere in APC. This makes it easy to insure that
-+ * all required headers are available.
-+ */
-+
-+#include "php.h"
-+#include "zend.h"
-+#include "zend_API.h"
-+#include "zend_compile.h"
-+#include "zend_hash.h"
-+#include "zend_extensions.h"
-+
-+#if ZEND_MODULE_API_NO >= 20100409
-+#define ZEND_ENGINE_2_4
-+#endif
-+#if ZEND_MODULE_API_NO > 20060613
-+#define ZEND_ENGINE_2_3
-+#endif
-+#if ZEND_MODULE_API_NO > 20050922
-+#define ZEND_ENGINE_2_2
-+#endif
-+#if ZEND_MODULE_API_NO > 20050921
-+#define ZEND_ENGINE_2_1
-+#endif
-+#ifdef ZEND_ENGINE_2_1
-+#include "zend_vm.h"
-+#endif
-+
-+#ifndef IS_CONSTANT_TYPE_MASK
-+#define IS_CONSTANT_TYPE_MASK (~IS_CONSTANT_INDEX)
-+#endif
-+
-+#include "rfc1867.h"
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_php_pcre.h b/ext/apc/apc_php_pcre.h
---- a/ext/apc/apc_php_pcre.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_php_pcre.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,98 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC/PHP Version 5 |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 1997-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Author: Andrei Zmievski <andrei@php.net> |
-+ +----------------------------------------------------------------------+
-+ */
-+
-+/* $Id: apc_php_pcre.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef PHP_PCRE_H
-+#define PHP_PCRE_H
-+
-+#if HAVE_PCRE || HAVE_BUNDLED_PCRE
-+
-+#if HAVE_BUNDLED_PCRE
-+#include "ext/pcre/pcrelib/pcre.h"
-+#else
-+#include "pcre.h"
-+#endif
-+
-+#if HAVE_LOCALE_H
-+#include <locale.h>
-+#endif
-+
-+PHP_FUNCTION(preg_match);
-+PHP_FUNCTION(preg_match_all);
-+PHP_FUNCTION(preg_replace);
-+PHP_FUNCTION(preg_replace_callback);
-+PHP_FUNCTION(preg_split);
-+PHP_FUNCTION(preg_quote);
-+PHP_FUNCTION(preg_grep);
-+
-+PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
-+PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC);
-+PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC);
-+
-+extern zend_module_entry pcre_module_entry;
-+#define pcre_module_ptr &pcre_module_entry
-+
-+typedef struct {
-+ pcre *re;
-+ pcre_extra *extra;
-+ int preg_options;
-+#if HAVE_SETLOCALE
-+ char *locale;
-+ unsigned const char *tables;
-+#endif
-+ int compile_options;
-+ int refcount;
-+} pcre_cache_entry;
-+
-+PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len TSRMLS_DC);
-+
-+PHPAPI void php_pcre_match_impl( pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
-+ zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC);
-+
-+PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
-+ int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
-+
-+PHPAPI void php_pcre_split_impl( pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
-+ long limit_val, long flags TSRMLS_DC);
-+
-+PHPAPI void php_pcre_grep_impl( pcre_cache_entry *pce, zval *input, zval *return_value,
-+ long flags TSRMLS_DC);
-+
-+ZEND_BEGIN_MODULE_GLOBALS(pcre)
-+ HashTable pcre_cache;
-+ long backtrack_limit;
-+ long recursion_limit;
-+ int error_code;
-+ZEND_END_MODULE_GLOBALS(pcre)
-+
-+#ifdef ZTS
-+# define PCRE_G(v) TSRMG(pcre_globals_id, zend_pcre_globals *, v)
-+#else
-+# define PCRE_G(v) (pcre_globals.v)
-+#endif
-+
-+#else
-+
-+#define pcre_module_ptr NULL
-+
-+#endif /* HAVE_PCRE || HAVE_BUNDLED_PCRE */
-+
-+#define phpext_pcre_ptr pcre_module_ptr
-+
-+#endif /* PHP_PCRE_H */
-diff -Naur a/ext/apc/apc_pool.c b/ext/apc/apc_pool.c
---- a/ext/apc/apc_pool.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pool.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,507 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Yahoo! Inc. in 2008.
-+
-+ Future revisions and derivatives of this source code must acknowledge
-+ Yahoo! Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_pool.c 307555 2011-01-18 07:17:21Z gopalv $ */
-+
-+
-+#include "apc_pool.h"
-+#include <assert.h>
-+
-+#ifdef HAVE_VALGRIND_MEMCHECK_H
-+#include <valgrind/memcheck.h>
-+#endif
-+
-+
-+/* {{{ forward references */
-+static apc_pool* apc_unpool_create(apc_pool_type type, apc_malloc_t, apc_free_t, apc_protect_t, apc_unprotect_t TSRMLS_DC);
-+static apc_pool* apc_realpool_create(apc_pool_type type, apc_malloc_t, apc_free_t, apc_protect_t, apc_unprotect_t TSRMLS_DC);
-+/* }}} */
-+
-+/* {{{ apc_pool_create */
-+apc_pool* apc_pool_create(apc_pool_type pool_type,
-+ apc_malloc_t allocate,
-+ apc_free_t deallocate,
-+ apc_protect_t protect,
-+ apc_unprotect_t unprotect
-+ TSRMLS_DC)
-+{
-+ if(pool_type == APC_UNPOOL) {
-+ return apc_unpool_create(pool_type, allocate, deallocate,
-+ protect, unprotect TSRMLS_CC);
-+ }
-+
-+ return apc_realpool_create(pool_type, allocate, deallocate,
-+ protect, unprotect TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_pool_destroy */
-+void apc_pool_destroy(apc_pool *pool TSRMLS_DC)
-+{
-+ apc_free_t deallocate = pool->deallocate;
-+ apc_pcleanup_t cleanup = pool->cleanup;
-+
-+ cleanup(pool TSRMLS_CC);
-+ deallocate(pool TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_unpool implementation */
-+
-+typedef struct _apc_unpool apc_unpool;
-+
-+struct _apc_unpool {
-+ apc_pool parent;
-+ /* apc_unpool is a lie! */
-+};
-+
-+static void* apc_unpool_alloc(apc_pool* pool, size_t size TSRMLS_DC)
-+{
-+ apc_unpool *upool = (apc_unpool*)pool;
-+
-+ apc_malloc_t allocate = upool->parent.allocate;
-+
-+ upool->parent.size += size;
-+ upool->parent.used += size;
-+
-+ return allocate(size TSRMLS_CC);
-+}
-+
-+static void apc_unpool_free(apc_pool* pool, void *ptr TSRMLS_DC)
-+{
-+ apc_unpool *upool = (apc_unpool*) pool;
-+
-+ apc_free_t deallocate = upool->parent.deallocate;
-+
-+ deallocate(ptr TSRMLS_CC);
-+}
-+
-+static void apc_unpool_cleanup(apc_pool* pool TSRMLS_DC)
-+{
-+}
-+
-+static apc_pool* apc_unpool_create(apc_pool_type type,
-+ apc_malloc_t allocate, apc_free_t deallocate,
-+ apc_protect_t protect, apc_unprotect_t unprotect
-+ TSRMLS_DC)
-+{
-+ apc_unpool* upool = allocate(sizeof(apc_unpool) TSRMLS_CC);
-+
-+ if (!upool) {
-+ return NULL;
-+ }
-+
-+ upool->parent.type = type;
-+ upool->parent.allocate = allocate;
-+ upool->parent.deallocate = deallocate;
-+
-+ upool->parent.protect = protect;
-+ upool->parent.unprotect = unprotect;
-+
-+ upool->parent.palloc = apc_unpool_alloc;
-+ upool->parent.pfree = apc_unpool_free;
-+
-+ upool->parent.cleanup = apc_unpool_cleanup;
-+
-+ upool->parent.used = 0;
-+ upool->parent.size = 0;
-+
-+ return &(upool->parent);
-+}
-+/* }}} */
-+
-+
-+/*{{{ apc_realpool implementation */
-+
-+/* {{{ typedefs */
-+typedef struct _pool_block
-+{
-+ size_t avail;
-+ size_t capacity;
-+ unsigned char *mark;
-+ struct _pool_block *next;
-+ unsigned :0; /* this should align to word */
-+ /* data comes here */
-+}pool_block;
-+
-+/*
-+ parts in ? are optional and turned on for fun, memory loss,
-+ and for something else that I forgot about ... ah, debugging
-+
-+ |--------> data[] |<-- non word boundary (too)
-+ +-------------+--------------+-----------+-------------+-------------->>>
-+ | pool_block | ?sizeinfo<1> | block<1> | ?redzone<1> | ?sizeinfo<2>
-+ | | (size_t) | | padded left |
-+ +-------------+--------------+-----------+-------------+-------------->>>
-+ */
-+
-+typedef struct _apc_realpool apc_realpool;
-+
-+struct _apc_realpool
-+{
-+ struct _apc_pool parent;
-+
-+ size_t dsize;
-+ void *owner;
-+
-+ unsigned long count;
-+
-+ pool_block *head;
-+ pool_block first;
-+};
-+
-+/* }}} */
-+
-+/* {{{ redzone code */
-+static const unsigned char decaff[] = {
-+ 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
-+ 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
-+ 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
-+ 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad
-+};
-+
-+/* a redzone is at least 4 (0xde,0xca,0xc0,0xff) bytes */
-+#define REDZONE_SIZE(size) \
-+ ((ALIGNWORD((size)) > ((size) + 4)) ? \
-+ (ALIGNWORD((size)) - (size)) : /* does not change realsize */\
-+ ALIGNWORD((size)) - (size) + ALIGNWORD((sizeof(char)))) /* adds 1 word to realsize */
-+
-+#define SIZEINFO_SIZE ALIGNWORD(sizeof(size_t))
-+
-+#define MARK_REDZONE(block, redsize) do {\
-+ memcpy(block, decaff, redsize );\
-+ } while(0)
-+
-+#define CHECK_REDZONE(block, redsize) (memcmp(block, decaff, redsize) == 0)
-+
-+/* }}} */
-+
-+#define INIT_POOL_BLOCK(rpool, entry, size) do {\
-+ (entry)->avail = (entry)->capacity = (size);\
-+ (entry)->mark = ((unsigned char*)(entry)) + ALIGNWORD(sizeof(pool_block));\
-+ (entry)->next = (rpool)->head;\
-+ (rpool)->head = (entry);\
-+} while(0)
-+
-+/* {{{ create_pool_block */
-+static pool_block* create_pool_block(apc_realpool *rpool, size_t size TSRMLS_DC)
-+{
-+ apc_malloc_t allocate = rpool->parent.allocate;
-+
-+ size_t realsize = sizeof(pool_block) + ALIGNWORD(size);
-+
-+ pool_block* entry = allocate(realsize TSRMLS_CC);
-+
-+ if (!entry) {
-+ return NULL;
-+ }
-+
-+ INIT_POOL_BLOCK(rpool, entry, size);
-+
-+ rpool->parent.size += realsize;
-+
-+ rpool->count++;
-+
-+ return entry;
-+}
-+/* }}} */
-+
-+/* {{{ apc_realpool_alloc */
-+static void* apc_realpool_alloc(apc_pool *pool, size_t size TSRMLS_DC)
-+{
-+ apc_realpool *rpool = (apc_realpool*)pool;
-+ unsigned char *p = NULL;
-+ size_t realsize = ALIGNWORD(size);
-+ size_t poolsize;
-+ unsigned char *redzone = NULL;
-+ size_t redsize = 0;
-+ size_t *sizeinfo= NULL;
-+ pool_block *entry = NULL;
-+ unsigned long i;
-+
-+ if(APC_POOL_HAS_REDZONES(pool)) {
-+ redsize = REDZONE_SIZE(size); /* redsize might be re-using word size padding */
-+ realsize = size + redsize; /* recalculating realsize */
-+ } else {
-+ redsize = realsize - size; /* use padding space */
-+ }
-+
-+ if(APC_POOL_HAS_SIZEINFO(pool)) {
-+ realsize += ALIGNWORD(sizeof(size_t));
-+ }
-+
-+ /* minimize look-back, a value of 8 seems to give similar fill-ratios (+2%)
-+ * as looping through the entire list. And much faster in allocations. */
-+ for(entry = rpool->head, i = 0; entry != NULL && (i < 8); entry = entry->next, i++) {
-+ if(entry->avail >= realsize) {
-+ goto found;
-+ }
-+ }
-+
-+ /* upgrade the pool type to reduce overhead */
-+ if(rpool->count > 4 && rpool->dsize < 4096) {
-+ rpool->dsize = 4096;
-+ } else if(rpool->count > 8 && rpool->dsize < 8192) {
-+ rpool->dsize = 8192;
-+ }
-+
-+ poolsize = ALIGNSIZE(realsize, rpool->dsize);
-+
-+ entry = create_pool_block(rpool, poolsize TSRMLS_CC);
-+
-+ if(!entry) {
-+ return NULL;
-+ }
-+
-+found:
-+ p = entry->mark;
-+
-+ if(APC_POOL_HAS_SIZEINFO(pool)) {
-+ sizeinfo = (size_t*)p;
-+ p += SIZEINFO_SIZE;
-+ *sizeinfo = size;
-+ }
-+
-+ redzone = p + size;
-+
-+ if(APC_POOL_HAS_REDZONES(pool)) {
-+ MARK_REDZONE(redzone, redsize);
-+ }
-+
-+#ifdef VALGRIND_MAKE_MEM_NOACCESS
-+ if(redsize != 0) {
-+ VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize);
-+ }
-+#endif
-+
-+ entry->avail -= realsize;
-+ entry->mark += realsize;
-+ pool->used += realsize;
-+
-+#ifdef VALGRIND_MAKE_MEM_UNDEFINED
-+ /* need to write before reading data off this */
-+ VALGRIND_MAKE_MEM_UNDEFINED(p, size);
-+#endif
-+
-+ return (void*)p;
-+}
-+/* }}} */
-+
-+/* {{{ apc_realpool_check_integrity */
-+/*
-+ * Checking integrity at runtime, does an
-+ * overwrite check only when the sizeinfo
-+ * is set.
-+ *
-+ * Marked as used in gcc, so that this function
-+ * is accessible from gdb, eventhough it is never
-+ * used in code in non-debug builds.
-+ */
-+static APC_USED int apc_realpool_check_integrity(apc_realpool *rpool)
-+{
-+ apc_pool *pool = &(rpool->parent);
-+ pool_block *entry;
-+ size_t *sizeinfo = NULL;
-+ unsigned char *start;
-+ size_t realsize;
-+ unsigned char *redzone;
-+ size_t redsize;
-+
-+ for(entry = rpool->head; entry != NULL; entry = entry->next) {
-+ start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block));
-+ if((entry->mark - start) != (entry->capacity - entry->avail)) {
-+ return 0;
-+ }
-+ }
-+
-+ if(!APC_POOL_HAS_REDZONES(pool) ||
-+ !APC_POOL_HAS_SIZEINFO(pool)) {
-+ (void)pool; /* remove unused warning */
-+ return 1;
-+ }
-+
-+ for(entry = rpool->head; entry != NULL; entry = entry->next) {
-+ start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block));
-+
-+ while(start < entry->mark) {
-+ sizeinfo = (size_t*)start;
-+ /* redzone starts where real data ends, in a non-word boundary
-+ * redsize is at least 4 bytes + whatever's needed to make it
-+ * to another word boundary.
-+ */
-+ redzone = start + SIZEINFO_SIZE + (*sizeinfo);
-+ redsize = REDZONE_SIZE(*sizeinfo);
-+#ifdef VALGRIND_MAKE_MEM_DEFINED
-+ VALGRIND_MAKE_MEM_DEFINED(redzone, redsize);
-+#endif
-+ if(!CHECK_REDZONE(redzone, redsize))
-+ {
-+ /*
-+ fprintf(stderr, "Redzone check failed for %p\n",
-+ start + ALIGNWORD(sizeof(size_t)));*/
-+ return 0;
-+ }
-+#ifdef VALGRIND_MAKE_MEM_NOACCESS
-+ VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize);
-+#endif
-+ realsize = SIZEINFO_SIZE + *sizeinfo + redsize;
-+ start += realsize;
-+ }
-+ }
-+
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ apc_realpool_free */
-+/*
-+ * free does not do anything other than
-+ * check for redzone values when free'ing
-+ * data areas.
-+ */
-+static void apc_realpool_free(apc_pool *pool, void *p TSRMLS_DC)
-+{
-+}
-+/* }}} */
-+
-+static void apc_realpool_cleanup(apc_pool *pool TSRMLS_DC)
-+{
-+ pool_block *entry;
-+ pool_block *tmp;
-+ apc_realpool *rpool = (apc_realpool*)pool;
-+ apc_free_t deallocate = pool->deallocate;
-+
-+ assert(apc_realpool_check_integrity(rpool)!=0);
-+
-+ entry = rpool->head;
-+
-+ while(entry->next != NULL) {
-+ tmp = entry->next;
-+ deallocate(entry TSRMLS_CC);
-+ entry = tmp;
-+ }
-+}
-+
-+/* {{{ apc_realpool_create */
-+static apc_pool* apc_realpool_create(apc_pool_type type, apc_malloc_t allocate, apc_free_t deallocate,
-+ apc_protect_t protect, apc_unprotect_t unprotect
-+ TSRMLS_DC)
-+{
-+
-+ size_t dsize = 0;
-+ apc_realpool *rpool;
-+
-+ switch(type & APC_POOL_SIZE_MASK) {
-+ case APC_SMALL_POOL:
-+ dsize = 512;
-+ break;
-+
-+ case APC_LARGE_POOL:
-+ dsize = 8192;
-+ break;
-+
-+ case APC_MEDIUM_POOL:
-+ dsize = 4096;
-+ break;
-+
-+ default:
-+ return NULL;
-+ }
-+
-+ rpool = (apc_realpool*)allocate((sizeof(apc_realpool) + ALIGNWORD(dsize)) TSRMLS_CC);
-+
-+ if(!rpool) {
-+ return NULL;
-+ }
-+
-+ rpool->parent.type = type;
-+
-+ rpool->parent.allocate = allocate;
-+ rpool->parent.deallocate = deallocate;
-+
-+ rpool->parent.size = sizeof(apc_realpool) + ALIGNWORD(dsize);
-+
-+ rpool->parent.palloc = apc_realpool_alloc;
-+ rpool->parent.pfree = apc_realpool_free;
-+
-+ rpool->parent.protect = protect;
-+ rpool->parent.unprotect = unprotect;
-+
-+ rpool->parent.cleanup = apc_realpool_cleanup;
-+
-+ rpool->dsize = dsize;
-+ rpool->head = NULL;
-+ rpool->count = 0;
-+
-+ INIT_POOL_BLOCK(rpool, &(rpool->first), dsize);
-+
-+ return &(rpool->parent);
-+}
-+
-+
-+/* }}} */
-+
-+/* {{{ apc_pool_init */
-+void apc_pool_init()
-+{
-+ /* put all ye sanity checks here */
-+ assert(sizeof(decaff) > REDZONE_SIZE(ALIGNWORD(sizeof(char))));
-+ assert(sizeof(pool_block) == ALIGNWORD(sizeof(pool_block)));
-+#if APC_POOL_DEBUG
-+ assert((APC_POOL_SIZE_MASK & (APC_POOL_SIZEINFO | APC_POOL_REDZONES)) == 0);
-+#endif
-+}
-+/* }}} */
-+
-+/* {{{ apc_pstrdup */
-+void* APC_ALLOC apc_pstrdup(const char* s, apc_pool* pool TSRMLS_DC)
-+{
-+ return s != NULL ? apc_pmemcpy(s, (strlen(s) + 1), pool TSRMLS_CC) : NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_pmemcpy */
-+void* APC_ALLOC apc_pmemcpy(const void* p, size_t n, apc_pool* pool TSRMLS_DC)
-+{
-+ void* q;
-+
-+ if (p != NULL && (q = apc_pool_alloc(pool, n)) != NULL) {
-+ memcpy(q, p, n);
-+ return q;
-+ }
-+ return NULL;
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_pool.h b/ext/apc/apc_pool.h
---- a/ext/apc/apc_pool.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pool.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Yahoo! Inc. in 2008.
-+
-+ Future revisions and derivatives of this source code must acknowledge
-+ Yahoo! Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_pool.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_POOL_H
-+#define APC_POOL_H
-+
-+#include "apc.h"
-+#include "apc_sma.h"
-+
-+/* #define APC_POOL_DEBUG 1 */
-+
-+typedef enum {
-+ APC_UNPOOL = 0x0,
-+ APC_SMALL_POOL = 0x1,
-+ APC_MEDIUM_POOL = 0x2,
-+ APC_LARGE_POOL = 0x3,
-+ APC_POOL_SIZE_MASK = 0x7, /* waste a bit */
-+#if APC_POOL_DEBUG
-+ APC_POOL_REDZONES = 0x08,
-+ APC_POOL_SIZEINFO = 0x10,
-+ APC_POOL_OPT_MASK = 0x18
-+#endif
-+} apc_pool_type;
-+
-+#if APC_POOL_DEBUG
-+#define APC_POOL_HAS_SIZEINFO(pool) ((pool->type & APC_POOL_SIZEINFO)!=0)
-+#define APC_POOL_HAS_REDZONES(pool) ((pool->type & APC_POOL_REDZONES)!=0)
-+#else
-+/* let gcc optimize away the optional features */
-+#define APC_POOL_HAS_SIZEINFO(pool) (0)
-+#define APC_POOL_HAS_REDZONES(pool) (0)
-+#endif
-+
-+
-+typedef struct _apc_pool apc_pool;
-+
-+typedef void (*apc_pcleanup_t)(apc_pool *pool TSRMLS_DC);
-+
-+typedef void* (*apc_palloc_t)(apc_pool *pool, size_t size TSRMLS_DC);
-+typedef void (*apc_pfree_t) (apc_pool *pool, void* p TSRMLS_DC);
-+
-+typedef void* (*apc_protect_t) (void *p);
-+typedef void* (*apc_unprotect_t)(void *p);
-+
-+struct _apc_pool {
-+ apc_pool_type type;
-+
-+ apc_malloc_t allocate;
-+ apc_free_t deallocate;
-+
-+ apc_palloc_t palloc;
-+ apc_pfree_t pfree;
-+
-+ apc_protect_t protect;
-+ apc_unprotect_t unprotect;
-+
-+ apc_pcleanup_t cleanup;
-+
-+ size_t size;
-+ size_t used;
-+
-+ /* apc_realpool and apc_unpool add more here */
-+};
-+
-+#define apc_pool_alloc(pool, size) ((void *) pool->palloc(pool, size TSRMLS_CC))
-+#define apc_pool_free(pool, ptr) ((void) pool->pfree (pool, ptr TSRMLS_CC))
-+
-+#define apc_pool_protect(pool, ptr) (pool->protect ? \
-+ (pool)->protect((ptr)) : (ptr))
-+
-+#define apc_pool_unprotect(pool, ptr) (pool->unprotect ? \
-+ (pool)->unprotect((ptr)) : (ptr))
-+
-+extern void apc_pool_init();
-+
-+extern apc_pool* apc_pool_create(apc_pool_type pool_type,
-+ apc_malloc_t allocate,
-+ apc_free_t deallocate,
-+ apc_protect_t protect,
-+ apc_unprotect_t unprotect
-+ TSRMLS_DC);
-+
-+extern void apc_pool_destroy(apc_pool* pool TSRMLS_DC);
-+
-+extern void* apc_pmemcpy(const void* p, size_t n, apc_pool* pool TSRMLS_DC);
-+extern void* apc_pstrdup(const char* s, apc_pool* pool TSRMLS_DC);
-+
-+#endif
-diff -Naur a/ext/apc/apc_pthreadmutex.c b/ext/apc/apc_pthreadmutex.c
---- a/ext/apc/apc_pthreadmutex.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pthreadmutex.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,111 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_pthreadmutex.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc_pthreadmutex.h"
-+
-+#ifdef APC_PTHREADMUTEX_LOCKS
-+
-+pthread_mutex_t *apc_pthreadmutex_create(pthread_mutex_t *lock TSRMLS_DC)
-+{
-+ int result;
-+ pthread_mutexattr_t* attr;
-+ attr = malloc(sizeof(pthread_mutexattr_t));
-+
-+ result = pthread_mutexattr_init(attr);
-+ if(result == ENOMEM) {
-+ apc_error("pthread mutex error: Insufficient memory exists to create the mutex attribute object." TSRMLS_CC);
-+ } else if(result == EINVAL) {
-+ apc_error("pthread mutex error: attr does not point to writeable memory." TSRMLS_CC);
-+ } else if(result == EFAULT) {
-+ apc_error("pthread mutex error: attr is an invalid pointer." TSRMLS_CC);
-+ }
-+
-+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-+ result = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ADAPTIVE_NP);
-+ if (result == EINVAL) {
-+ apc_error("pthread_mutexattr_settype: unable to set adaptive mutexes" TSRMLS_CC);
-+ }
-+#endif
-+
-+ /* pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ERRORCHECK); */
-+ result = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
-+ if(result == EINVAL) {
-+ apc_error("pthread mutex error: attr is not an initialized mutex attribute object, or pshared is not a valid process-shared state setting." TSRMLS_CC);
-+ } else if(result == EFAULT) {
-+ apc_error("pthread mutex error: attr is an invalid pointer." TSRMLS_CC);
-+ } else if(result == ENOTSUP) {
-+ apc_error("pthread mutex error: pshared was set to PTHREAD_PROCESS_SHARED." TSRMLS_CC);
-+ }
-+
-+ if(pthread_mutex_init(lock, attr)) {
-+ apc_error("unable to initialize pthread lock" TSRMLS_CC);
-+ }
-+ return lock;
-+}
-+
-+void apc_pthreadmutex_destroy(pthread_mutex_t *lock)
-+{
-+ return; /* we don't actually destroy the mutex, as it would destroy it for all processes */
-+}
-+
-+void apc_pthreadmutex_lock(pthread_mutex_t *lock TSRMLS_DC)
-+{
-+ int result;
-+ result = pthread_mutex_lock(lock);
-+ if(result == EINVAL) {
-+ apc_error("unable to obtain pthread lock (EINVAL)" TSRMLS_CC);
-+ } else if(result == EDEADLK) {
-+ apc_error("unable to obtain pthread lock (EDEADLK)" TSRMLS_CC);
-+ }
-+}
-+
-+void apc_pthreadmutex_unlock(pthread_mutex_t *lock TSRMLS_DC)
-+{
-+ if(pthread_mutex_unlock(lock)) {
-+ apc_error("unable to unlock pthread lock" TSRMLS_CC);
-+ }
-+}
-+
-+zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock TSRMLS_DC)
-+{
-+ int rval;
-+ rval = pthread_mutex_trylock(lock);
-+ if(rval == EBUSY) { /* Lock is already held */
-+ return 0;
-+ } else if(rval == 0) { /* Obtained lock */
-+ return 1;
-+ } else { /* Other error */
-+ apc_error("unable to obtain pthread trylock" TSRMLS_CC);
-+ return 0;
-+ }
-+}
-+
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_pthreadmutex.h b/ext/apc/apc_pthreadmutex.h
---- a/ext/apc/apc_pthreadmutex.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pthreadmutex.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_pthreadmutex.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_PTHREADMUTEX_H
-+#define APC_PTHREADMUTEX_H
-+
-+#include "apc.h"
-+
-+#ifdef APC_PTHREADMUTEX_LOCKS
-+
-+#include <pthread.h>
-+
-+pthread_mutex_t *apc_pthreadmutex_create(pthread_mutex_t *lock TSRMLS_DC);
-+void apc_pthreadmutex_destroy(pthread_mutex_t *lock);
-+void apc_pthreadmutex_lock(pthread_mutex_t *lock TSRMLS_DC);
-+void apc_pthreadmutex_unlock(pthread_mutex_t *lock TSRMLS_DC);
-+zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock TSRMLS_DC);
-+
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_pthreadrwlock.c b/ext/apc/apc_pthreadrwlock.c
---- a/ext/apc/apc_pthreadrwlock.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pthreadrwlock.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,120 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal V <gopalv@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: $ */
-+
-+#include "apc_pthreadrwlock.h"
-+
-+#ifdef APC_PTHREADRW_LOCKS
-+
-+pthread_rwlock_t *apc_pthreadrwlock_create(pthread_rwlock_t *lock TSRMLS_DC)
-+{
-+ int result;
-+ pthread_rwlockattr_t attr;
-+
-+ result = pthread_rwlockattr_init(&attr);
-+ if(result == ENOMEM) {
-+ apc_error("pthread rwlock error: Insufficient memory exists to create the rwlock attribute object." TSRMLS_CC);
-+ } else if(result == EINVAL) {
-+ apc_error("pthread rwlock error: attr does not point to writeable memory." TSRMLS_CC);
-+ } else if(result == EFAULT) {
-+ apc_error("pthread rwlock error: attr is an invalid pointer." TSRMLS_CC);
-+ }
-+
-+#ifdef __USE_UNIX98
-+ pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
-+#endif
-+
-+ result = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-+ if(result == EINVAL) {
-+ apc_error("pthread rwlock error: attr is not an initialized rwlock attribute object, or pshared is not a valid process-shared state setting." TSRMLS_CC);
-+ } else if(result == EFAULT) {
-+ apc_error("pthread rwlock error: attr is an invalid pointer." TSRMLS_CC);
-+ } else if(result == ENOTSUP) {
-+ apc_error("pthread rwlock error: pshared was set to PTHREAD_PROCESS_SHARED." TSRMLS_CC);
-+ }
-+
-+ if(pthread_rwlock_init(lock, &attr)) {
-+ apc_error("unable to initialize pthread rwlock" TSRMLS_CC);
-+ }
-+
-+ pthread_rwlockattr_destroy(&attr);
-+
-+ return lock;
-+}
-+
-+void apc_pthreadrwlock_destroy(pthread_rwlock_t *lock)
-+{
-+ return; /* we don't actually destroy the rwlock, as it would destroy it for all processes */
-+}
-+
-+void apc_pthreadrwlock_lock(pthread_rwlock_t *lock TSRMLS_DC)
-+{
-+ int result;
-+ result = pthread_rwlock_wrlock(lock);
-+ if(result == EINVAL) {
-+ apc_error("unable to obtain pthread lock (EINVAL)" TSRMLS_CC);
-+ } else if(result == EDEADLK) {
-+ apc_error("unable to obtain pthread lock (EDEADLK)" TSRMLS_CC);
-+ }
-+}
-+
-+void apc_pthreadrwlock_rdlock(pthread_rwlock_t *lock TSRMLS_DC)
-+{
-+ int result;
-+ result = pthread_rwlock_rdlock(lock);
-+ if(result == EINVAL) {
-+ apc_error("unable to obtain pthread lock (EINVAL)" TSRMLS_CC);
-+ } else if(result == EDEADLK) {
-+ apc_error("unable to obtain pthread lock (EDEADLK)" TSRMLS_CC);
-+ }
-+}
-+
-+void apc_pthreadrwlock_unlock(pthread_rwlock_t *lock TSRMLS_DC)
-+{
-+ if(pthread_rwlock_unlock(lock)) {
-+ apc_error("unable to unlock pthread lock" TSRMLS_CC);
-+ }
-+}
-+
-+zend_bool apc_pthreadrwlock_nonblocking_lock(pthread_rwlock_t *lock TSRMLS_DC)
-+{
-+ int rval;
-+ rval = pthread_rwlock_trywrlock(lock);
-+ if(rval == EBUSY) { /* Lock is already held */
-+ return 0;
-+ } else if(rval == 0) { /* Obtained lock */
-+ return 1;
-+ } else { /* Other error */
-+ apc_error("unable to obtain pthread trylock" TSRMLS_CC);
-+ return 0;
-+ }
-+}
-+
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_pthreadrwlock.h b/ext/apc/apc_pthreadrwlock.h
---- a/ext/apc/apc_pthreadrwlock.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_pthreadrwlock.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,49 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal V <gopalv@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_pthreadrwlock.h 302175 2010-08-13 06:20:28Z kalle $ */
-+
-+#ifndef APC_PTHREADRWLOCK_H
-+#define APC_PTHREADRWLOCK_H
-+
-+#include "apc.h"
-+
-+#ifdef APC_PTHREADRW_LOCKS
-+
-+#include <pthread.h>
-+
-+pthread_rwlock_t *apc_pthreadrwlock_create(pthread_rwlock_t *lock TSRMLS_DC);
-+void apc_pthreadrwlock_destroy(pthread_rwlock_t *lock);
-+void apc_pthreadrwlock_lock(pthread_rwlock_t *lock TSRMLS_DC);
-+void apc_pthreadrwlock_rdlock(pthread_rwlock_t *lock TSRMLS_DC);
-+void apc_pthreadrwlock_unlock(pthread_rwlock_t *lock TSRMLS_DC);
-+zend_bool apc_pthreadrwlock_nonblocking_lock(pthread_rwlock_t *lock TSRMLS_DC);
-+
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_rfc1867.c b/ext/apc/apc_rfc1867.c
---- a/ext/apc/apc_rfc1867.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_rfc1867.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,236 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_rfc1867.c 309694 2011-03-25 18:47:38Z rasmus $*/
-+
-+#include "apc.h"
-+#include "apc_globals.h"
-+#include "rfc1867.h"
-+
-+#ifdef PHP_WIN32
-+#include "win32/time.h"
-+#endif
-+
-+#ifdef MULTIPART_EVENT_FORMDATA
-+extern int _apc_store(char *strkey, int strkey_len, const zval *val, const uint ttl, const int exclusive TSRMLS_DC);
-+extern int _apc_update(char *strkey, int strkey_len, apc_cache_updater_t updater, void* data TSRMLS_DC);
-+
-+static int update_bytes_processed(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
-+ int *bytes_ptr = (int*)data;
-+ zval* val = entry->data.user.val;
-+
-+ if(Z_TYPE_P(val) == IS_ARRAY) {
-+ HashTable *ht = val->value.ht;
-+ Bucket* curr = NULL;
-+ for (curr = ht->pListHead; curr != NULL; curr = curr->pListNext) {
-+ if(curr->nKeyLength == 8 &&
-+ (!memcmp(curr->arKey, "current", curr->nKeyLength))) {
-+ zval* current = ((zval**)curr->pData)[0];
-+ current->value.lval = *bytes_ptr;
-+ return 1;
-+ }
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static double my_time() {
-+ struct timeval a;
-+ double t;
-+ gettimeofday(&a, NULL);
-+ t = a.tv_sec + (a.tv_usec/1000000.00);
-+ return t;
-+}
-+
-+
-+#define RFC1867_DATA(name) \
-+ ((request_data)->name)
-+
-+int apc_rfc1867_progress(uint event, void *event_data, void **extra TSRMLS_DC) {
-+ apc_rfc1867_data *request_data = &APCG(rfc1867_data);
-+ zval *track = NULL;
-+
-+ switch (event) {
-+ case MULTIPART_EVENT_START:
-+ {
-+ multipart_event_start *data = (multipart_event_start *) event_data;
-+
-+ RFC1867_DATA(content_length) = data->content_length;
-+ RFC1867_DATA(tracking_key)[0] = '\0';
-+ RFC1867_DATA(name)[0] = '\0';
-+ RFC1867_DATA(cancel_upload) = 0;
-+ RFC1867_DATA(temp_filename) = NULL;
-+ RFC1867_DATA(filename)[0] = '\0';
-+ RFC1867_DATA(key_length) = 0;
-+ RFC1867_DATA(start_time) = my_time();
-+ RFC1867_DATA(bytes_processed) = 0;
-+ RFC1867_DATA(prev_bytes_processed) = 0;
-+ RFC1867_DATA(rate) = 0;
-+ RFC1867_DATA(update_freq) = (int) APCG(rfc1867_freq);
-+ RFC1867_DATA(started) = 0;
-+
-+ if(RFC1867_DATA(update_freq) < 0) { // frequency is a percentage, not bytes
-+ RFC1867_DATA(update_freq) = (int) (RFC1867_DATA(content_length) * APCG(rfc1867_freq) / 100);
-+ }
-+ }
-+ break;
-+
-+ case MULTIPART_EVENT_FORMDATA:
-+ {
-+ int prefix_len = strlen(APCG(rfc1867_prefix));
-+ multipart_event_formdata *data = (multipart_event_formdata *) event_data;
-+ if(data->name && !strncasecmp(data->name, APCG(rfc1867_name), strlen(APCG(rfc1867_name)))
-+ && data->value && data->length) {
-+
-+ if(data->length >= sizeof(RFC1867_DATA(tracking_key)) - prefix_len) {
-+ apc_warning("Key too long for '%s'. Maximum size is '%d' characters." TSRMLS_CC,
-+ APCG(rfc1867_name),
-+ sizeof(RFC1867_DATA(tracking_key)) - prefix_len);
-+ break;
-+ }
-+
-+ if(RFC1867_DATA(started)) {
-+ apc_warning("Upload progress key '%s' should be before the file upload entry in the form." TSRMLS_CC,
-+ APCG(rfc1867_name));
-+ break;
-+ }
-+
-+ strlcat(RFC1867_DATA(tracking_key), APCG(rfc1867_prefix), 63);
-+ strlcat(RFC1867_DATA(tracking_key), *data->value, 63);
-+ RFC1867_DATA(key_length) = data->length + prefix_len;
-+ RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
-+ }
-+ }
-+ break;
-+
-+ case MULTIPART_EVENT_FILE_START:
-+ {
-+ RFC1867_DATA(started) = 1;
-+ if(*RFC1867_DATA(tracking_key)) {
-+ multipart_event_file_start *data = (multipart_event_file_start *) event_data;
-+
-+ RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
-+ strlcpy(RFC1867_DATA(filename),*data->filename,128);
-+ RFC1867_DATA(temp_filename) = NULL;
-+ strlcpy(RFC1867_DATA(name),data->name,64);
-+ ALLOC_INIT_ZVAL(track);
-+ array_init(track);
-+ add_assoc_long(track, "total", RFC1867_DATA(content_length));
-+ add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
-+ add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
-+ add_assoc_string(track, "name", RFC1867_DATA(name), 1);
-+ add_assoc_long(track, "done", 0);
-+ add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
-+ _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length)+1, track, APCG(rfc1867_ttl), 0 TSRMLS_CC);
-+ zval_ptr_dtor(&track);
-+ }
-+ }
-+ break;
-+
-+ case MULTIPART_EVENT_FILE_DATA:
-+ if(*RFC1867_DATA(tracking_key)) {
-+ multipart_event_file_data *data = (multipart_event_file_data *) event_data;
-+ RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
-+ if(RFC1867_DATA(bytes_processed) - RFC1867_DATA(prev_bytes_processed) > (uint) RFC1867_DATA(update_freq)) {
-+ if(!_apc_update(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), update_bytes_processed, &RFC1867_DATA(bytes_processed) TSRMLS_CC)) {
-+ ALLOC_INIT_ZVAL(track);
-+ array_init(track);
-+ add_assoc_long(track, "total", RFC1867_DATA(content_length));
-+ add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
-+ add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
-+ add_assoc_string(track, "name", RFC1867_DATA(name), 1);
-+ add_assoc_long(track, "done", 0);
-+ add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
-+ _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length)+1, track, APCG(rfc1867_ttl), 0 TSRMLS_CC);
-+ zval_ptr_dtor(&track);
-+ }
-+ RFC1867_DATA(prev_bytes_processed) = RFC1867_DATA(bytes_processed);
-+ }
-+ }
-+ break;
-+
-+ case MULTIPART_EVENT_FILE_END:
-+ if(*RFC1867_DATA(tracking_key)) {
-+ multipart_event_file_end *data = (multipart_event_file_end *) event_data;
-+ RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
-+ RFC1867_DATA(cancel_upload) = data->cancel_upload;
-+ if(data->temp_filename) {
-+ RFC1867_DATA(temp_filename) = data->temp_filename;
-+ } else {
-+ RFC1867_DATA(temp_filename) = "";
-+ }
-+ ALLOC_INIT_ZVAL(track);
-+ array_init(track);
-+ add_assoc_long(track, "total", RFC1867_DATA(content_length));
-+ add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
-+ add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
-+ add_assoc_string(track, "name", RFC1867_DATA(name), 1);
-+ add_assoc_string(track, "temp_filename", RFC1867_DATA(temp_filename), 1);
-+ add_assoc_long(track, "cancel_upload", RFC1867_DATA(cancel_upload));
-+ add_assoc_long(track, "done", 0);
-+ add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
-+ _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length)+1, track, APCG(rfc1867_ttl), 0 TSRMLS_CC);
-+ zval_ptr_dtor(&track);
-+ }
-+ break;
-+
-+ case MULTIPART_EVENT_END:
-+ if(*RFC1867_DATA(tracking_key)) {
-+ double now = my_time();
-+ multipart_event_end *data = (multipart_event_end *) event_data;
-+ RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
-+ if(now>RFC1867_DATA(start_time)) RFC1867_DATA(rate) = 8.0*RFC1867_DATA(bytes_processed)/(now-RFC1867_DATA(start_time));
-+ else RFC1867_DATA(rate) = 8.0*RFC1867_DATA(bytes_processed); /* Too quick */
-+ ALLOC_INIT_ZVAL(track);
-+ array_init(track);
-+ add_assoc_long(track, "total", RFC1867_DATA(content_length));
-+ add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
-+ add_assoc_double(track, "rate", RFC1867_DATA(rate));
-+ add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
-+ add_assoc_string(track, "name", RFC1867_DATA(name), 1);
-+ add_assoc_long(track, "cancel_upload", RFC1867_DATA(cancel_upload));
-+ add_assoc_long(track, "done", 1);
-+ add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
-+ _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length)+1, track, APCG(rfc1867_ttl), 0 TSRMLS_CC);
-+ zval_ptr_dtor(&track);
-+ }
-+ break;
-+ }
-+
-+ return SUCCESS;
-+}
-+
-+#endif
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_sem.c b/ext/apc/apc_sem.c
---- a/ext/apc/apc_sem.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_sem.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,192 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_sem.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc.h"
-+
-+#ifdef APC_SEM_LOCKS
-+
-+#include "apc_sem.h"
-+#include "php.h"
-+#include <sys/types.h>
-+#include <sys/ipc.h>
-+#include <sys/sem.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+
-+#if HAVE_SEMUN
-+/* we have semun, no need to define */
-+#else
-+#undef HAVE_SEMUN
-+union semun {
-+ int val; /* value for SETVAL */
-+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
-+ unsigned short *array; /* array for GETALL, SETALL */
-+ /* Linux specific part: */
-+ struct seminfo *__buf; /* buffer for IPC_INFO */
-+};
-+#define HAVE_SEMUN 1
-+#endif
-+
-+#ifndef SEM_R
-+# define SEM_R 0444
-+#endif
-+#ifndef SEM_A
-+# define SEM_A 0222
-+#endif
-+
-+/* always use SEM_UNDO, otherwise we risk deadlock */
-+#define USE_SEM_UNDO
-+
-+#ifdef USE_SEM_UNDO
-+# define UNDO SEM_UNDO
-+#else
-+# define UNDO 0
-+#endif
-+
-+int apc_sem_create(int proj, int initval TSRMLS_DC)
-+{
-+ int semid;
-+ int perms = 0777;
-+ union semun arg;
-+ key_t key = IPC_PRIVATE;
-+
-+ if ((semid = semget(key, 1, IPC_CREAT | IPC_EXCL | perms)) >= 0) {
-+ /* sempahore created for the first time, initialize now */
-+ arg.val = initval;
-+ if (semctl(semid, 0, SETVAL, arg) < 0) {
-+ apc_error("apc_sem_create: semctl(%d,...) failed:" TSRMLS_CC, semid);
-+ }
-+ }
-+ else if (errno == EEXIST) {
-+ /* sempahore already exists, don't initialize */
-+ if ((semid = semget(key, 1, perms)) < 0) {
-+ apc_error("apc_sem_create: semget(%u,...) failed:" TSRMLS_CC, key);
-+ }
-+ /* insert <sleazy way to avoid race condition> here */
-+ }
-+ else {
-+ apc_error("apc_sem_create: semget(%u,...) failed:" TSRMLS_CC, key);
-+ }
-+
-+ return semid;
-+}
-+
-+void apc_sem_destroy(int semid)
-+{
-+ /* we expect this call to fail often, so we do not check */
-+ union semun arg;
-+ semctl(semid, 0, IPC_RMID, arg);
-+}
-+
-+void apc_sem_lock(int semid TSRMLS_DC)
-+{
-+ struct sembuf op;
-+
-+ op.sem_num = 0;
-+ op.sem_op = -1;
-+ op.sem_flg = UNDO;
-+
-+ if (semop(semid, &op, 1) < 0) {
-+ if (errno != EINTR) {
-+ apc_error("apc_sem_lock: semop(%d) failed:" TSRMLS_CC, semid);
-+ }
-+ }
-+}
-+
-+int apc_sem_nonblocking_lock(int semid TSRMLS_DC)
-+{
-+ struct sembuf op;
-+
-+ op.sem_num = 0;
-+ op.sem_op = -1;
-+ op.sem_flg = UNDO | IPC_NOWAIT;
-+
-+ if (semop(semid, &op, 1) < 0) {
-+ if (errno == EAGAIN) {
-+ return 0; /* Lock is already held */
-+ } else if (errno != EINTR) {
-+ apc_error("apc_sem_lock: semop(%d) failed:" TSRMLS_CC, semid);
-+ }
-+ }
-+
-+ return 1; /* Lock obtained */
-+}
-+
-+void apc_sem_unlock(int semid TSRMLS_DC)
-+{
-+ struct sembuf op;
-+
-+ op.sem_num = 0;
-+ op.sem_op = 1;
-+ op.sem_flg = UNDO;
-+
-+ if (semop(semid, &op, 1) < 0) {
-+ if (errno != EINTR) {
-+ apc_error("apc_sem_unlock: semop(%d) failed:" TSRMLS_CC, semid);
-+ }
-+ }
-+}
-+
-+void apc_sem_wait_for_zero(int semid TSRMLS_DC)
-+{
-+ struct sembuf op;
-+
-+ op.sem_num = 0;
-+ op.sem_op = 0;
-+ op.sem_flg = UNDO;
-+
-+ if (semop(semid, &op, 1) < 0) {
-+ if (errno != EINTR) {
-+ apc_error("apc_sem_waitforzero: semop(%d) failed:" TSRMLS_CC, semid);
-+ }
-+ }
-+}
-+
-+int apc_sem_get_value(int semid TSRMLS_DC)
-+{
-+ union semun arg;
-+ unsigned short val[1];
-+
-+ arg.array = val;
-+ if (semctl(semid, 0, GETALL, arg) < 0) {
-+ apc_error("apc_sem_getvalue: semctl(%d,...) failed:" TSRMLS_CC, semid);
-+ }
-+ return val[0];
-+}
-+
-+#endif /* APC_SEM_LOCKS */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_sem.h b/ext/apc/apc_sem.h
---- a/ext/apc/apc_sem.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_sem.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,52 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_sem.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_SEM_H
-+#define APC_SEM_H
-+
-+/* Wrapper functions for SysV sempahores */
-+
-+extern int apc_sem_create(int proj, int initval TSRMLS_DC);
-+extern void apc_sem_destroy(int semid);
-+extern void apc_sem_lock(int semid TSRMLS_DC);
-+extern int apc_sem_nonblocking_lock(int semid TSRMLS_DC);
-+extern void apc_sem_unlock(int semid TSRMLS_DC);
-+extern void apc_sem_wait_for_zero(int semid TSRMLS_DC);
-+extern int apc_sem_get_value(int semid TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_serializer.h b/ext/apc/apc_serializer.h
---- a/ext/apc/apc_serializer.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_serializer.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,84 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt. |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Gopal Vijayaraghavan <gopalv@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: $ */
-+
-+#ifndef APC_SERIALIZER_H
-+#define APC_SERIALIZER_H
-+
-+/* this is a shipped .h file, do not include any other header in this file */
-+#define APC_SERIALIZER_NAME(module) module##_apc_serializer
-+#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer
-+
-+#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config TSRMLS_DC
-+#define APC_UNSERIALIZER_ARGS zval **value, unsigned char *buf, size_t buf_len, void *config TSRMLS_DC
-+
-+typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
-+typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);
-+
-+typedef int (*apc_register_serializer_t)(const char* name,
-+ apc_serialize_t serialize,
-+ apc_unserialize_t unserialize,
-+ void *config TSRMLS_DC);
-+
-+/*
-+ * ABI version for constant hooks. Increment this any time you make any changes
-+ * to any function in this file.
-+ */
-+#define APC_SERIALIZER_ABI "0"
-+#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI
-+
-+#if !defined(APC_UNUSED)
-+# if defined(__GNUC__)
-+# define APC_UNUSED __attribute__((unused))
-+# else
-+# define APC_UNUSED
-+# endif
-+#endif
-+
-+static APC_UNUSED int apc_register_serializer(const char* name,
-+ apc_serialize_t serialize,
-+ apc_unserialize_t unserialize,
-+ void *config TSRMLS_DC)
-+{
-+ zval apc_magic_constant;
-+ int retval = 0;
-+
-+ /* zend_get_constant will return 1 on success, otherwise apc_magic_constant wouldn't be touched at all */
-+ if (zend_get_constant(APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT)-1, &apc_magic_constant TSRMLS_CC)) {
-+ apc_register_serializer_t register_func = (apc_register_serializer_t)(Z_LVAL(apc_magic_constant));
-+ if(register_func) {
-+ retval = register_func(name, serialize, unserialize, NULL TSRMLS_CC);
-+ }
-+ zval_dtor(&apc_magic_constant);
-+ }
-+
-+ return retval;
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_shm.c b/ext/apc/apc_shm.c
---- a/ext/apc/apc_shm.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_shm.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,116 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_shm.c 307259 2011-01-08 12:05:24Z gopalv $ */
-+
-+#include "apc_shm.h"
-+#include "apc.h"
-+#ifdef PHP_WIN32
-+/* shm functions are available in TSRM */
-+#include <tsrm/tsrm_win32.h>
-+#define key_t long
-+#else
-+#include <sys/ipc.h>
-+#include <sys/shm.h>
-+#include <sys/stat.h>
-+#endif
-+
-+#ifndef SHM_R
-+# define SHM_R 0444 /* read permission */
-+#endif
-+#ifndef SHM_A
-+# define SHM_A 0222 /* write permission */
-+#endif
-+
-+int apc_shm_create(int proj, size_t size TSRMLS_DC)
-+{
-+ int shmid; /* shared memory id */
-+ int oflag; /* permissions on shm */
-+ key_t key = IPC_PRIVATE; /* shm key */
-+
-+ oflag = IPC_CREAT | SHM_R | SHM_A;
-+ if ((shmid = shmget(key, size, oflag)) < 0) {
-+ apc_error("apc_shm_create: shmget(%d, %d, %d) failed: %s. It is possible that the chosen SHM segment size is higher than the operation system allows. Linux has usually a default limit of 32MB per segment." TSRMLS_CC, key, size, oflag, strerror(errno));
-+ }
-+
-+ return shmid;
-+}
-+
-+void apc_shm_destroy(int shmid)
-+{
-+ /* we expect this call to fail often, so we do not check */
-+ shmctl(shmid, IPC_RMID, 0);
-+}
-+
-+apc_segment_t apc_shm_attach(int shmid, size_t size TSRMLS_DC)
-+{
-+ apc_segment_t segment; /* shm segment */
-+
-+ if ((long)(segment.shmaddr = shmat(shmid, 0, 0)) == -1) {
-+ apc_error("apc_shm_attach: shmat failed:" TSRMLS_CC);
-+ }
-+
-+#ifdef APC_MEMPROTECT
-+
-+ if ((long)(segment.roaddr = shmat(shmid, 0, SHM_RDONLY)) == -1) {
-+ segment.roaddr = NULL;
-+ }
-+
-+#endif
-+
-+ segment.size = size;
-+
-+ /*
-+ * We set the shmid for removal immediately after attaching to it. The
-+ * segment won't disappear until all processes have detached from it.
-+ */
-+ apc_shm_destroy(shmid);
-+ return segment;
-+}
-+
-+void apc_shm_detach(apc_segment_t* segment TSRMLS_DC)
-+{
-+ if (shmdt(segment->shmaddr) < 0) {
-+ apc_error("apc_shm_detach: shmdt failed:" TSRMLS_CC);
-+ }
-+
-+#ifdef APC_MEMPROTECT
-+ if (segment->roaddr && shmdt(segment->roaddr) < 0) {
-+ apc_error("apc_shm_detach: shmdt failed:" TSRMLS_CC);
-+ }
-+#endif
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_shm.h b/ext/apc/apc_shm.h
---- a/ext/apc/apc_shm.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_shm.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,56 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_shm.h 307259 2011-01-08 12:05:24Z gopalv $ */
-+
-+#ifndef APC_SHM_H
-+#define APC_SHM_H
-+
-+#include <sys/types.h>
-+#ifdef PHP_WIN32
-+#include <time.h>
-+#endif
-+
-+#include "apc_sma.h"
-+
-+/* Wrapper functions for unix shared memory */
-+
-+extern int apc_shm_create(int proj, size_t size TSRMLS_DC);
-+extern void apc_shm_destroy(int shmid);
-+extern apc_segment_t apc_shm_attach(int shmid, size_t size TSRMLS_DC);
-+extern void apc_shm_detach(apc_segment_t* segment TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_signal.c b/ext/apc/apc_signal.c
---- a/ext/apc/apc_signal.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_signal.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,197 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Lucas Nealan <lucas@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Facebook Inc. in 2007.
-+
-+ Future revisions and derivatives of this source code must acknowledge
-+ Facebook Inc. as the original contributor of this module by leaving
-+ this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+ */
-+
-+ /* $Id: apc_signal.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+ /* Allows apc to install signal handlers and maintain signalling
-+ to already registered handlers. Registers all signals that
-+ coredump by default and unmaps the shared memory segment
-+ before the coredump. Note: PHP module init is called before
-+ signals are set by Apache and thus apc_set_signals should
-+ be called in request init (RINIT)
-+ */
-+
-+#include "apc.h"
-+
-+#if HAVE_SIGACTION
-+#include <signal.h>
-+#include "apc_globals.h"
-+#include "apc_sma.h"
-+#include "apc_signal.h"
-+
-+static apc_signal_info_t apc_signal_info = {0};
-+
-+static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*) TSRMLS_DC);
-+static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context);
-+static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context);
-+
-+/* {{{ apc_core_unmap
-+ * Coredump signal handler, unmaps shm and calls previously installed handlers
-+ */
-+static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context)
-+{
-+ TSRMLS_FETCH();
-+
-+ apc_sma_cleanup(TSRMLS_C);
-+ apc_rehandle_signal(signo, siginfo, context);
-+
-+#if !defined(WIN32) && !defined(NETWARE)
-+ kill(getpid(), signo);
-+#else
-+ raise(signo);
-+#endif
-+} /* }}} */
-+
-+/* {{{ apc_rehandle_signal
-+ * Call the previously registered handler for a signal
-+ */
-+static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context)
-+{
-+ int i;
-+ apc_signal_entry_t p_sig = {0};
-+
-+ for (i=0; (i < apc_signal_info.installed && p_sig.signo != signo); i++) {
-+ p_sig = *apc_signal_info.prev[i];
-+ if (p_sig.signo == signo) {
-+ if (p_sig.siginfo) {
-+ (*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context);
-+ } else {
-+ (*(void (*)(int))p_sig.handler)(signo);
-+ }
-+ }
-+ }
-+
-+} /* }}} */
-+
-+/* {{{ apc_register_signal
-+ * Set a handler for a previously installed signal and save so we can
-+ * callback when handled
-+ */
-+static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*) TSRMLS_DC)
-+{
-+ struct sigaction sa = {{0}};
-+ apc_signal_entry_t p_sig = {0};
-+
-+ if (sigaction(signo, NULL, &sa) == 0) {
-+ if ((void*)sa.sa_handler == (void*)handler) {
-+ return SUCCESS;
-+ }
-+
-+ if (sa.sa_handler != SIG_ERR && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) {
-+ p_sig.signo = signo;
-+ p_sig.siginfo = ((sa.sa_flags & SA_SIGINFO) == SA_SIGINFO);
-+ p_sig.handler = (void *)sa.sa_handler;
-+
-+ apc_signal_info.prev = (apc_signal_entry_t **)apc_erealloc(apc_signal_info.prev, (apc_signal_info.installed+1)*sizeof(apc_signal_entry_t *) TSRMLS_CC);
-+ apc_signal_info.prev[apc_signal_info.installed] = (apc_signal_entry_t *)apc_emalloc(sizeof(apc_signal_entry_t) TSRMLS_CC);
-+ *apc_signal_info.prev[apc_signal_info.installed++] = p_sig;
-+ } else {
-+ /* inherit flags and mask if already set */
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ sa.sa_flags |= SA_SIGINFO; /* we'll use a siginfo handler */
-+#if defined(SA_ONESHOT)
-+ sa.sa_flags = SA_ONESHOT;
-+#elif defined(SA_RESETHAND)
-+ sa.sa_flags = SA_RESETHAND;
-+#endif
-+ }
-+ sa.sa_handler = (void*)handler;
-+
-+ if (sigaction(signo, &sa, NULL) < 0) {
-+ apc_warning("Error installing apc signal handler for %d" TSRMLS_CC, signo);
-+ }
-+
-+ return SUCCESS;
-+ }
-+ return FAILURE;
-+} /* }}} */
-+
-+/* {{{ apc_set_signals
-+ * Install our signal handlers */
-+void apc_set_signals(TSRMLS_D)
-+{
-+ if (APCG(coredump_unmap) && apc_signal_info.installed == 0) {
-+ /* ISO C standard signals that coredump */
-+ apc_register_signal(SIGSEGV, apc_core_unmap TSRMLS_CC);
-+ apc_register_signal(SIGABRT, apc_core_unmap TSRMLS_CC);
-+ apc_register_signal(SIGFPE, apc_core_unmap TSRMLS_CC);
-+ apc_register_signal(SIGILL, apc_core_unmap TSRMLS_CC);
-+ /* extended signals that coredump */
-+#ifdef SIGBUS
-+ apc_register_signal(SIGBUS, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGABORT
-+ apc_register_signal(SIGABORT, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGEMT
-+ apc_register_signal(SIGEMT, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGIOT
-+ apc_register_signal(SIGIOT, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGQUIT
-+ apc_register_signal(SIGQUIT, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGSYS
-+ apc_register_signal(SIGSYS, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGTRAP
-+ apc_register_signal(SIGTRAP, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGXCPU
-+ apc_register_signal(SIGXCPU, apc_core_unmap TSRMLS_CC);
-+#endif
-+#ifdef SIGXFSZ
-+ apc_register_signal(SIGXFSZ, apc_core_unmap TSRMLS_CC);
-+#endif
-+ }
-+} /* }}} */
-+
-+/* {{{ apc_set_signals
-+ * cleanup signals for shutdown */
-+void apc_shutdown_signals(TSRMLS_D)
-+{
-+ int i=0;
-+ if (apc_signal_info.installed > 0) {
-+ for (i=0; (i < apc_signal_info.installed); i++) {
-+ apc_efree(apc_signal_info.prev[i] TSRMLS_CC);
-+ }
-+ apc_efree(apc_signal_info.prev TSRMLS_CC);
-+ apc_signal_info.installed = 0; /* just in case */
-+ }
-+}
-+
-+#endif /* HAVE_SIGACTION */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_signal.h b/ext/apc/apc_signal.h
---- a/ext/apc/apc_signal.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_signal.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,51 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Lucas Nealan <lucas@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_signal.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_SIGNAL_H
-+#define APC_SIGNAL_H
-+
-+#include "apc.h"
-+#include "apc_php.h"
-+
-+typedef struct apc_signal_entry_t {
-+ int signo; /* signal number */
-+ int siginfo; /* siginfo style handler calling */
-+ void* handler; /* signal handler */
-+} apc_signal_entry_t;
-+
-+typedef struct apc_signal_info_t {
-+ int installed; /* How many signals we've installed handles for */
-+ apc_signal_entry_t **prev; /* Previous signal handlers */
-+} apc_signal_info_t;
-+
-+void apc_set_signals(TSRMLS_D);
-+void apc_shutdown_signals(TSRMLS_D);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_sma.c b/ext/apc/apc_sma.c
---- a/ext/apc/apc_sma.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_sma.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,765 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_sma.c 309489 2011-03-21 00:00:54Z pajoye $ */
-+
-+#include "apc_sma.h"
-+#include "apc.h"
-+#include "apc_globals.h"
-+#include "apc_lock.h"
-+#include "apc_shm.h"
-+#include "apc_cache.h"
-+
-+#include <limits.h>
-+#include "apc_mmap.h"
-+
-+#ifdef HAVE_VALGRIND_MEMCHECK_H
-+#include <valgrind/memcheck.h>
-+#endif
-+
-+enum { DEFAULT_NUMSEG=1, DEFAULT_SEGSIZE=30*1024*1024 };
-+
-+static int sma_initialized = 0; /* true if the sma has been initialized */
-+static uint sma_numseg; /* number of shm segments to allow */
-+static size_t sma_segsize; /* size of each shm segment */
-+static apc_segment_t* sma_segments; /* array of shm segments */
-+static int sma_lastseg = 0; /* index of MRU segment */
-+
-+typedef struct sma_header_t sma_header_t;
-+struct sma_header_t {
-+ apc_lck_t sma_lock; /* segment lock, MUST BE ALIGNED for futex locks */
-+ size_t segsize; /* size of entire segment */
-+ size_t avail; /* bytes available (not necessarily contiguous) */
-+#if ALLOC_DISTRIBUTION
-+ size_t adist[30];
-+#endif
-+};
-+
-+#define SMA_HDR(i) ((sma_header_t*)((sma_segments[i]).shmaddr))
-+#define SMA_ADDR(i) ((char*)(SMA_HDR(i)))
-+#define SMA_RO(i) ((char*)(sma_segments[i]).roaddr)
-+#define SMA_LCK(i) ((SMA_HDR(i))->sma_lock)
-+
-+
-+/* do not enable for threaded http servers */
-+/* #define __APC_SMA_DEBUG__ 1 */
-+
-+#ifdef __APC_SMA_DEBUG__
-+/* global counter for identifying blocks
-+ * Technically it is possible to do the same
-+ * using offsets, but double allocations of the
-+ * same offset can happen. */
-+static volatile size_t block_id = 0;
-+#endif
-+
-+#define APC_SMA_CANARIES 1
-+
-+typedef struct block_t block_t;
-+struct block_t {
-+ size_t size; /* size of this block */
-+ size_t prev_size; /* size of sequentially previous block, 0 if prev is allocated */
-+ size_t fnext; /* offset in segment of next free block */
-+ size_t fprev; /* offset in segment of prev free block */
-+#ifdef APC_SMA_CANARIES
-+ size_t canary; /* canary to check for memory overwrites */
-+#endif
-+#ifdef __APC_SMA_DEBUG__
-+ size_t id; /* identifier for the memory block */
-+#endif
-+};
-+
-+/* The macros BLOCKAT and OFFSET are used for convenience throughout this
-+ * module. Both assume the presence of a variable shmaddr that points to the
-+ * beginning of the shared memory segment in question. */
-+
-+#define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset))
-+#define OFFSET(block) ((size_t)(((char*)block) - (char*)shmaddr))
-+
-+/* macros for getting the next or previous sequential block */
-+#define NEXT_SBLOCK(block) ((block_t*)((char*)block + block->size))
-+#define PREV_SBLOCK(block) (block->prev_size ? ((block_t*)((char*)block - block->prev_size)) : NULL)
-+
-+/* Canary macros for setting, checking and resetting memory canaries */
-+#ifdef APC_SMA_CANARIES
-+ #define SET_CANARY(v) (v)->canary = 0x42424242
-+ #define CHECK_CANARY(v) assert((v)->canary == 0x42424242)
-+ #define RESET_CANARY(v) (v)->canary = -42
-+#else
-+ #define SET_CANARY(v)
-+ #define CHECK_CANARY(v)
-+ #define RESET_CANARY(v)
-+#endif
-+
-+
-+/* {{{ MINBLOCKSIZE */
-+#define MINBLOCKSIZE (ALIGNWORD(1) + ALIGNWORD(sizeof(block_t)))
-+/* }}} */
-+
-+#if 0
-+/* {{{ sma_debug_state(apc_sma_segment_t *segment, int canary_check, int verbose)
-+ * useful for debuging state of memory blocks and free list, and sanity checking
-+ */
-+static void sma_debug_state(void* shmaddr, int canary_check, int verbose TSRMLS_DC) {
-+ sma_header_t *header = (sma_header_t*)shmaddr;
-+ block_t *cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+ block_t *prv = NULL;
-+ size_t avail;
-+
-+ /* Verify free list */
-+ if (verbose) apc_warning("Free List: " TSRMLS_CC);
-+ while(1) {
-+ if (verbose) apc_warning(" 0x%x[%d] (s%d)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
-+ if (canary_check) CHECK_CANARY(cur);
-+ if (!cur->fnext) break;
-+ cur = BLOCKAT(cur->fnext);
-+ avail += cur->size;
-+ if (prv == cur) {
-+ apc_warning("Circular list detected!" TSRMLS_CC);
-+ assert(0);
-+ }
-+ if (prv && cur->fprev != OFFSET(prv)) {
-+ apc_warning("Previous pointer does not point to previous!" TSRMLS_CC);
-+ assert(0);
-+ }
-+ prv = cur;
-+ }
-+ assert(avail == header->avail);
-+
-+ /* Verify each block */
-+ if (verbose) apc_warning("Block List: " TSRMLS_CC);
-+ cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+ while(1) {
-+ if(!cur->fnext) {
-+ if (verbose) apc_warning(" 0x%x[%d] (s%d) (u)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
-+ } else {
-+ if (verbose) apc_warning(" 0x%x[%d] (s%d) (f)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
-+ }
-+ if (canary_check) CHECK_CANARY(cur);
-+ if (!cur->size && !cur->fnext) break;
-+ if (!cur->size) {
-+ cur = BLOCKAT(OFFSET(cur) + ALIGNWORD(sizeof(block_t)));
-+ } else {
-+ cur = NEXT_SBLOCK(cur);
-+ }
-+ if (prv == cur) {
-+ apc_warning("Circular list detected!" TSRMLS_CC);
-+ assert(0);
-+ }
-+ prv = cur;
-+ }
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ sma_allocate: tries to allocate at least size bytes in a segment */
-+static APC_HOTSPOT size_t sma_allocate(sma_header_t* header, size_t size, size_t fragment, size_t *allocated)
-+{
-+ void* shmaddr; /* header of shared memory segment */
-+ block_t* prv; /* block prior to working block */
-+ block_t* cur; /* working block in list */
-+ block_t* prvnextfit; /* block before next fit */
-+ size_t realsize; /* actual size of block needed, including header */
-+ const size_t block_size = ALIGNWORD(sizeof(struct block_t));
-+
-+ realsize = ALIGNWORD(size + block_size);
-+
-+ /*
-+ * First, insure that the segment contains at least realsize free bytes,
-+ * even if they are not contiguous.
-+ */
-+ shmaddr = header;
-+
-+ if (header->avail < realsize) {
-+ return -1;
-+ }
-+
-+ prvnextfit = 0; /* initially null (no fit) */
-+ prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+ CHECK_CANARY(prv);
-+
-+ while (prv->fnext != 0) {
-+ cur = BLOCKAT(prv->fnext);
-+#ifdef __APC_SMA_DEBUG__
-+ CHECK_CANARY(cur);
-+#endif
-+ /* If it can fit realsize bytes in cur block, stop searching */
-+ if (cur->size >= realsize) {
-+ prvnextfit = prv;
-+ break;
-+ }
-+ prv = cur;
-+ }
-+
-+ if (prvnextfit == 0) {
-+ return -1;
-+ }
-+
-+ prv = prvnextfit;
-+ cur = BLOCKAT(prv->fnext);
-+
-+ CHECK_CANARY(prv);
-+ CHECK_CANARY(cur);
-+
-+ if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE + fragment)))) {
-+ /* cur is big enough for realsize, but too small to split - unlink it */
-+ *(allocated) = cur->size - block_size;
-+ prv->fnext = cur->fnext;
-+ BLOCKAT(cur->fnext)->fprev = OFFSET(prv);
-+ NEXT_SBLOCK(cur)->prev_size = 0; /* block is alloc'd */
-+ } else {
-+ /* nextfit is too big; split it into two smaller blocks */
-+ block_t* nxt; /* the new block (chopped part of cur) */
-+ size_t oldsize; /* size of cur before split */
-+
-+ oldsize = cur->size;
-+ cur->size = realsize;
-+ *(allocated) = cur->size - block_size;
-+ nxt = NEXT_SBLOCK(cur);
-+ nxt->prev_size = 0; /* block is alloc'd */
-+ nxt->size = oldsize - realsize; /* and fix the size */
-+ NEXT_SBLOCK(nxt)->prev_size = nxt->size; /* adjust size */
-+ SET_CANARY(nxt);
-+
-+ /* replace cur with next in free list */
-+ nxt->fnext = cur->fnext;
-+ nxt->fprev = cur->fprev;
-+ BLOCKAT(nxt->fnext)->fprev = OFFSET(nxt);
-+ BLOCKAT(nxt->fprev)->fnext = OFFSET(nxt);
-+#ifdef __APC_SMA_DEBUG__
-+ nxt->id = -1;
-+#endif
-+ }
-+
-+ cur->fnext = 0;
-+
-+ /* update the block header */
-+ header->avail -= cur->size;
-+#if ALLOC_DISTRIBUTION
-+ header->adist[(int)(log(size)/log(2))]++;
-+#endif
-+
-+ SET_CANARY(cur);
-+#ifdef __APC_SMA_DEBUG__
-+ cur->id = ++block_id;
-+ fprintf(stderr, "allocate(realsize=%d,size=%d,id=%d)\n", (int)(size), (int)(cur->size), cur->id);
-+#endif
-+
-+ return OFFSET(cur) + block_size;
-+}
-+/* }}} */
-+
-+/* {{{ sma_deallocate: deallocates the block at the given offset */
-+static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset)
-+{
-+ sma_header_t* header; /* header of shared memory segment */
-+ block_t* cur; /* the new block to insert */
-+ block_t* prv; /* the block before cur */
-+ block_t* nxt; /* the block after cur */
-+ size_t size; /* size of deallocated block */
-+
-+ offset -= ALIGNWORD(sizeof(struct block_t));
-+ assert(offset >= 0);
-+
-+ /* find position of new block in free list */
-+ cur = BLOCKAT(offset);
-+
-+ /* update the block header */
-+ header = (sma_header_t*) shmaddr;
-+ header->avail += cur->size;
-+ size = cur->size;
-+
-+ if (cur->prev_size != 0) {
-+ /* remove prv from list */
-+ prv = PREV_SBLOCK(cur);
-+ BLOCKAT(prv->fnext)->fprev = prv->fprev;
-+ BLOCKAT(prv->fprev)->fnext = prv->fnext;
-+ /* cur and prv share an edge, combine them */
-+ prv->size +=cur->size;
-+ RESET_CANARY(cur);
-+ cur = prv;
-+ }
-+
-+ nxt = NEXT_SBLOCK(cur);
-+ if (nxt->fnext != 0) {
-+ assert(NEXT_SBLOCK(NEXT_SBLOCK(cur))->prev_size == nxt->size);
-+ /* cur and nxt shared an edge, combine them */
-+ BLOCKAT(nxt->fnext)->fprev = nxt->fprev;
-+ BLOCKAT(nxt->fprev)->fnext = nxt->fnext;
-+ cur->size += nxt->size;
-+#ifdef __APC_SMA_DEBUG__
-+ CHECK_CANARY(nxt);
-+ nxt->id = -1; /* assert this or set it ? */
-+#endif
-+ RESET_CANARY(nxt);
-+ }
-+
-+ NEXT_SBLOCK(cur)->prev_size = cur->size;
-+
-+ /* insert new block after prv */
-+ prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+ cur->fnext = prv->fnext;
-+ prv->fnext = OFFSET(cur);
-+ cur->fprev = OFFSET(prv);
-+ BLOCKAT(cur->fnext)->fprev = OFFSET(cur);
-+
-+ return size;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_init */
-+
-+void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask TSRMLS_DC)
-+{
-+ uint i;
-+
-+ if (sma_initialized) {
-+ return;
-+ }
-+ sma_initialized = 1;
-+
-+#if APC_MMAP
-+ /*
-+ * I don't think multiple anonymous mmaps makes any sense
-+ * so force sma_numseg to 1 in this case
-+ */
-+ if(!mmap_file_mask ||
-+ (mmap_file_mask && !strlen(mmap_file_mask)) ||
-+ (mmap_file_mask && !strcmp(mmap_file_mask, "/dev/zero"))) {
-+ sma_numseg = 1;
-+ } else {
-+ sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG;
-+ }
-+#else
-+ sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG;
-+#endif
-+
-+ sma_segsize = segsize > 0 ? segsize : DEFAULT_SEGSIZE;
-+
-+ sma_segments = (apc_segment_t*) apc_emalloc((sma_numseg * sizeof(apc_segment_t)) TSRMLS_CC);
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ sma_header_t* header;
-+ block_t *first, *empty, *last;
-+ void* shmaddr;
-+
-+#if APC_MMAP
-+ sma_segments[i] = apc_mmap(mmap_file_mask, sma_segsize TSRMLS_CC);
-+ if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6);
-+#else
-+ sma_segments[i] = apc_shm_attach(apc_shm_create(i, sma_segsize TSRMLS_CC), sma_segsize TSRMLS_CC);
-+#endif
-+
-+ sma_segments[i].size = sma_segsize;
-+
-+ shmaddr = sma_segments[i].shmaddr;
-+
-+ header = (sma_header_t*) shmaddr;
-+ apc_lck_create(NULL, 0, 1, header->sma_lock);
-+ header->segsize = sma_segsize;
-+ header->avail = sma_segsize - ALIGNWORD(sizeof(sma_header_t)) - ALIGNWORD(sizeof(block_t)) - ALIGNWORD(sizeof(block_t));
-+#if ALLOC_DISTRIBUTION
-+ {
-+ int j;
-+ for(j=0; j<30; j++) header->adist[j] = 0;
-+ }
-+#endif
-+ first = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+ first->size = 0;
-+ first->fnext = ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t));
-+ first->fprev = 0;
-+ first->prev_size = 0;
-+ SET_CANARY(first);
-+#ifdef __APC_SMA_DEBUG__
-+ block->id = -1;
-+#endif
-+ empty = BLOCKAT(first->fnext);
-+ empty->size = header->avail - ALIGNWORD(sizeof(block_t));
-+ empty->fnext = OFFSET(empty) + empty->size;
-+ empty->fprev = ALIGNWORD(sizeof(sma_header_t));
-+ empty->prev_size = 0;
-+ SET_CANARY(empty);
-+#ifdef __APC_SMA_DEBUG__
-+ empty->id = -1;
-+#endif
-+ last = BLOCKAT(empty->fnext);
-+ last->size = 0;
-+ last->fnext = 0;
-+ last->fprev = OFFSET(empty);
-+ last->prev_size = empty->size;
-+ SET_CANARY(last);
-+#ifdef __APC_SMA_DEBUG__
-+ last->id = -1;
-+#endif
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_cleanup */
-+void apc_sma_cleanup(TSRMLS_D)
-+{
-+ uint i;
-+
-+ assert(sma_initialized);
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ apc_lck_destroy(SMA_LCK(i));
-+#if APC_MMAP
-+ apc_unmap(&sma_segments[i] TSRMLS_CC);
-+#else
-+ apc_shm_detach(&sma_segments[i] TSRMLS_CC);
-+#endif
-+ }
-+ sma_initialized = 0;
-+ apc_efree(sma_segments TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_malloc_ex */
-+void* apc_sma_malloc_ex(size_t n, size_t fragment, size_t* allocated TSRMLS_DC)
-+{
-+ size_t off;
-+ uint i;
-+ int nuked = 0;
-+
-+restart:
-+ assert(sma_initialized);
-+ LOCK(SMA_LCK(sma_lastseg));
-+
-+ off = sma_allocate(SMA_HDR(sma_lastseg), n, fragment, allocated);
-+
-+ if(off == -1 && APCG(current_cache)) {
-+ /* retry failed allocation after we expunge */
-+ UNLOCK(SMA_LCK(sma_lastseg));
-+ APCG(current_cache)->expunge_cb(APCG(current_cache), (n+fragment) TSRMLS_CC);
-+ LOCK(SMA_LCK(sma_lastseg));
-+ off = sma_allocate(SMA_HDR(sma_lastseg), n, fragment, allocated);
-+ }
-+
-+ if (off != -1) {
-+ void* p = (void *)(SMA_ADDR(sma_lastseg) + off);
-+ UNLOCK(SMA_LCK(sma_lastseg));
-+#ifdef VALGRIND_MALLOCLIKE_BLOCK
-+ VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0);
-+#endif
-+ return p;
-+ }
-+
-+ UNLOCK(SMA_LCK(sma_lastseg));
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ if (i == sma_lastseg) {
-+ continue;
-+ }
-+ LOCK(SMA_LCK(i));
-+ off = sma_allocate(SMA_HDR(i), n, fragment, allocated);
-+ if(off == -1 && APCG(current_cache)) {
-+ /* retry failed allocation after we expunge */
-+ UNLOCK(SMA_LCK(i));
-+ APCG(current_cache)->expunge_cb(APCG(current_cache), (n+fragment) TSRMLS_CC);
-+ LOCK(SMA_LCK(i));
-+ off = sma_allocate(SMA_HDR(i), n, fragment, allocated);
-+ }
-+ if (off != -1) {
-+ void* p = (void *)(SMA_ADDR(i) + off);
-+ UNLOCK(SMA_LCK(i));
-+ sma_lastseg = i;
-+#ifdef VALGRIND_MALLOCLIKE_BLOCK
-+ VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0);
-+#endif
-+ return p;
-+ }
-+ UNLOCK(SMA_LCK(i));
-+ }
-+
-+ /* I've tried being nice, but now you're just asking for it */
-+ if(!nuked) {
-+ apc_cache->expunge_cb(apc_cache, (n+fragment) TSRMLS_CC);
-+ apc_user_cache->expunge_cb(apc_user_cache, (n+fragment) TSRMLS_CC);
-+ nuked = 1;
-+ goto restart;
-+ }
-+
-+ /* now, I've truly and well given up */
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_malloc */
-+void* apc_sma_malloc(size_t n TSRMLS_DC)
-+{
-+ size_t allocated;
-+ void *p = apc_sma_malloc_ex(n, MINBLOCKSIZE, &allocated TSRMLS_CC);
-+
-+ return p;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_realloc */
-+void* apc_sma_realloc(void *p, size_t n TSRMLS_DC)
-+{
-+ apc_sma_free(p TSRMLS_CC);
-+ return apc_sma_malloc(n TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_strdup */
-+char* apc_sma_strdup(const char* s TSRMLS_DC)
-+{
-+ void* q;
-+ int len;
-+
-+ if(!s) return NULL;
-+
-+ len = strlen(s)+1;
-+ q = apc_sma_malloc(len TSRMLS_CC);
-+ if(!q) return NULL;
-+ memcpy(q, s, len);
-+ return q;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_free */
-+void apc_sma_free(void* p TSRMLS_DC)
-+{
-+ uint i;
-+ size_t offset;
-+ size_t d_size;
-+
-+ if (p == NULL) {
-+ return;
-+ }
-+
-+ assert(sma_initialized);
-+
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ offset = (size_t)((char *)p - SMA_ADDR(i));
-+ if (p >= (void*)SMA_ADDR(i) && offset < sma_segsize) {
-+ LOCK(SMA_LCK(i));
-+ d_size = sma_deallocate(SMA_HDR(i), offset);
-+ UNLOCK(SMA_LCK(i));
-+#ifdef VALGRIND_FREELIKE_BLOCK
-+ VALGRIND_FREELIKE_BLOCK(p, 0);
-+#endif
-+ return;
-+ }
-+ }
-+
-+ apc_error("apc_sma_free: could not locate address %p" TSRMLS_CC, p);
-+}
-+/* }}} */
-+
-+#ifdef APC_MEMPROTECT
-+/* {{{ */
-+void* apc_sma_protect(void *p)
-+{
-+ unsigned int i = 0;
-+ size_t offset;
-+
-+ if (p == NULL) {
-+ return NULL;
-+ }
-+
-+ if(SMA_RO(sma_lastseg) == NULL) return p;
-+
-+ offset = (size_t)((char *)p - SMA_ADDR(sma_lastseg));
-+
-+ if(p >= (void*)SMA_ADDR(sma_lastseg) && offset < sma_segsize) {
-+ return SMA_RO(sma_lastseg) + offset;
-+ }
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ offset = (size_t)((char *)p - SMA_ADDR(i));
-+ if (p >= (void*)SMA_ADDR(i) && offset < sma_segsize) {
-+ return SMA_RO(i) + offset;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ */
-+void* apc_sma_unprotect(void *p)
-+{
-+ unsigned int i = 0;
-+ size_t offset;
-+
-+ if (p == NULL) {
-+ return NULL;
-+ }
-+
-+ if(SMA_RO(sma_lastseg) == NULL) return p;
-+
-+ offset = (size_t)((char *)p - SMA_RO(sma_lastseg));
-+
-+ if(p >= (void*)SMA_RO(sma_lastseg) && offset < sma_segsize) {
-+ return SMA_ADDR(sma_lastseg) + offset;
-+ }
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ offset = (size_t)((char *)p - SMA_RO(i));
-+ if (p >= (void*)SMA_RO(i) && offset < sma_segsize) {
-+ return SMA_ADDR(i) + offset;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+/* }}} */
-+#else
-+/* {{{ */
-+void* apc_sma_protect(void *p) { return p; }
-+void* apc_sma_unprotect(void *p) { return p; }
-+/* }}} */
-+#endif
-+
-+/* {{{ apc_sma_info */
-+apc_sma_info_t* apc_sma_info(zend_bool limited TSRMLS_DC)
-+{
-+ apc_sma_info_t* info;
-+ apc_sma_link_t** link;
-+ uint i;
-+ char* shmaddr;
-+ block_t* prv;
-+
-+ if (!sma_initialized) {
-+ return NULL;
-+ }
-+
-+ info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t) TSRMLS_CC);
-+ info->num_seg = sma_numseg;
-+ info->seg_size = sma_segsize - (ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)) + ALIGNWORD(sizeof(block_t)));
-+
-+ info->list = apc_emalloc(info->num_seg * sizeof(apc_sma_link_t*) TSRMLS_CC);
-+ for (i = 0; i < sma_numseg; i++) {
-+ info->list[i] = NULL;
-+ }
-+
-+ if(limited) return info;
-+
-+ /* For each segment */
-+ for (i = 0; i < sma_numseg; i++) {
-+ RDLOCK(SMA_LCK(i));
-+ shmaddr = SMA_ADDR(i);
-+ prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
-+
-+ link = &info->list[i];
-+
-+ /* For each block in this segment */
-+ while (BLOCKAT(prv->fnext)->fnext != 0) {
-+ block_t* cur = BLOCKAT(prv->fnext);
-+#ifdef __APC_SMA_DEBUG__
-+ CHECK_CANARY(cur);
-+#endif
-+
-+ *link = apc_emalloc(sizeof(apc_sma_link_t) TSRMLS_CC);
-+ (*link)->size = cur->size;
-+ (*link)->offset = prv->fnext;
-+ (*link)->next = NULL;
-+ link = &(*link)->next;
-+
-+ prv = cur;
-+
-+#if ALLOC_DISTRIBUTION
-+ sma_header_t* header = (sma_header_t*) segment->shmaddr;
-+ memcpy(info->seginfo[i].adist, header->adist, sizeof(size_t) * 30);
-+#endif
-+
-+ }
-+ RDUNLOCK(SMA_LCK(i));
-+ }
-+
-+ return info;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_free_info */
-+void apc_sma_free_info(apc_sma_info_t* info TSRMLS_DC)
-+{
-+ int i;
-+
-+ for (i = 0; i < info->num_seg; i++) {
-+ apc_sma_link_t* p = info->list[i];
-+ while (p) {
-+ apc_sma_link_t* q = p;
-+ p = p->next;
-+ apc_efree(q TSRMLS_CC);
-+ }
-+ }
-+ apc_efree(info->list TSRMLS_CC);
-+ apc_efree(info TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_get_avail_mem */
-+size_t apc_sma_get_avail_mem()
-+{
-+ size_t avail_mem = 0;
-+ uint i;
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ sma_header_t* header = SMA_HDR(i);
-+ avail_mem += header->avail;
-+ }
-+ return avail_mem;
-+}
-+/* }}} */
-+
-+/* {{{ apc_sma_get_avail_size */
-+zend_bool apc_sma_get_avail_size(size_t size)
-+{
-+ uint i;
-+
-+ for (i = 0; i < sma_numseg; i++) {
-+ sma_header_t* header = SMA_HDR(i);
-+ if (header->avail > size) {
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+/* }}} */
-+
-+
-+#if ALLOC_DISTRIBUTION
-+size_t *apc_sma_get_alloc_distribution(void) {
-+ sma_header_t* header = (sma_header_t*) segment->sma_shmaddr;
-+ return header->adist;
-+}
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_sma.h b/ext/apc/apc_sma.h
---- a/ext/apc/apc_sma.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_sma.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,103 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_sma.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_SMA_H
-+#define APC_SMA_H
-+
-+#define ALLOC_DISTRIBUTION 0
-+
-+#include "apc.h"
-+
-+/* Simple shared memory allocator */
-+
-+typedef struct _apc_segment_t apc_segment_t;
-+
-+struct _apc_segment_t {
-+ size_t size;
-+ void* shmaddr;
-+#ifdef APC_MEMPROTECT
-+ void* roaddr;
-+#endif
-+};
-+
-+extern void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask TSRMLS_DC);
-+extern void apc_sma_cleanup(TSRMLS_D);
-+extern void* apc_sma_malloc(size_t size TSRMLS_DC);
-+extern void* apc_sma_malloc_ex(size_t size, size_t fragment, size_t* allocated TSRMLS_DC);
-+extern void* apc_sma_realloc(void* p, size_t size TSRMLS_DC);
-+extern char* apc_sma_strdup(const char *s TSRMLS_DC);
-+extern void apc_sma_free(void* p TSRMLS_DC);
-+#if ALLOC_DISTRIBUTION
-+extern size_t *apc_sma_get_alloc_distribution();
-+#endif
-+
-+extern void* apc_sma_protect(void *p);
-+extern void* apc_sma_unprotect(void *p);
-+
-+/* {{{ struct definition: apc_sma_link_t */
-+typedef struct apc_sma_link_t apc_sma_link_t;
-+struct apc_sma_link_t {
-+ long size; /* size of this free block */
-+ long offset; /* offset in segment of this block */
-+ apc_sma_link_t* next; /* link to next free block */
-+};
-+/* }}} */
-+
-+/* {{{ struct definition: apc_sma_info_t */
-+typedef struct apc_sma_info_t apc_sma_info_t;
-+struct apc_sma_info_t {
-+ int num_seg; /* number of shared memory segments */
-+ size_t seg_size; /* size of each shared memory segment */
-+ apc_sma_link_t** list; /* there is one list per segment */
-+};
-+/* }}} */
-+
-+extern apc_sma_info_t* apc_sma_info(zend_bool limited TSRMLS_DC);
-+extern void apc_sma_free_info(apc_sma_info_t* info TSRMLS_DC);
-+
-+extern size_t apc_sma_get_avail_mem();
-+extern zend_bool apc_sma_get_avail_size(size_t size);
-+extern void apc_sma_check_integrity();
-+
-+/* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */
-+typedef union { void* p; int i; long l; double d; void (*f)(); } apc_word_t;
-+#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size))))
-+#define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t))
-+/* }}} */
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_spin.c b/ext/apc/apc_spin.c
---- a/ext/apc/apc_spin.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_spin.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,66 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_spin.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc_spin.h"
-+
-+#ifdef APC_SPIN_LOCKS
-+
-+slock_t *apc_slock_create(slock_t *lock)
-+{
-+ S_INIT_LOCK(lock);
-+ return lock;
-+}
-+
-+void apc_slock_destroy(slock_t *lock)
-+{
-+ return;
-+}
-+
-+void apc_slock_lock(slock_t *lock TSRMLS_DC)
-+{
-+ S_LOCK(lock);
-+}
-+
-+void apc_slock_unlock(slock_t *lock)
-+{
-+ S_UNLOCK(lock);
-+}
-+
-+zend_bool apc_slock_nonblocking_lock(slock_t *lock)
-+{
-+ /* Technically we aren't supposed to call this directly, but the original
-+ * code provides no method for absolute non-blocking locks, so we'll call into
-+ * the TAS (test and set) functionality directly
-+ */
-+ return !(TAS(lock)); /* if TAS returns 0 we obtained the lock, otherwise we failed */
-+}
-+
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_spin.h b/ext/apc/apc_spin.h
---- a/ext/apc/apc_spin.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_spin.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: apc_spin.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_SPIN_H
-+#define APC_SPIN_H
-+
-+#include "apc.h"
-+
-+#ifdef APC_SPIN_LOCKS
-+
-+#include "pgsql_s_lock.h"
-+
-+slock_t *apc_slock_create(slock_t *lock);
-+void apc_slock_destroy(slock_t *lock);
-+void apc_slock_lock(slock_t *lock TSRMLS_DC);
-+zend_bool apc_slock_nonblocking_lock(slock_t *lock);
-+void apc_slock_unlock(slock_t *lock);
-+
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_stack.c b/ext/apc/apc_stack.c
---- a/ext/apc/apc_stack.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_stack.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,106 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_stack.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc.h"
-+#include "apc_stack.h"
-+
-+struct apc_stack_t {
-+ void** data;
-+ int capacity;
-+ int size;
-+};
-+
-+apc_stack_t* apc_stack_create(int size_hint TSRMLS_DC)
-+{
-+ apc_stack_t* stack = (apc_stack_t*) apc_emalloc(sizeof(apc_stack_t) TSRMLS_CC);
-+
-+ stack->capacity = (size_hint > 0) ? size_hint : 10;
-+ stack->size = 0;
-+ stack->data = (void**) apc_emalloc(sizeof(void*) * stack->capacity TSRMLS_CC);
-+
-+ return stack;
-+}
-+
-+void apc_stack_destroy(apc_stack_t* stack TSRMLS_DC)
-+{
-+ if (stack != NULL) {
-+ apc_efree(stack->data TSRMLS_CC);
-+ apc_efree(stack TSRMLS_CC);
-+ }
-+}
-+
-+void apc_stack_clear(apc_stack_t* stack)
-+{
-+ assert(stack != NULL);
-+ stack->size = 0;
-+}
-+
-+void apc_stack_push(apc_stack_t* stack, void* item TSRMLS_DC)
-+{
-+ assert(stack != NULL);
-+ if (stack->size == stack->capacity) {
-+ stack->capacity *= 2;
-+ stack->data = apc_erealloc(stack->data, sizeof(void*)*stack->capacity TSRMLS_CC);
-+ }
-+ stack->data[stack->size++] = item;
-+}
-+
-+void* apc_stack_pop(apc_stack_t* stack)
-+{
-+ assert(stack != NULL && stack->size > 0);
-+ return stack->data[--stack->size];
-+}
-+
-+void* apc_stack_top(apc_stack_t* stack)
-+{
-+ assert(stack != NULL && stack->size > 0);
-+ return stack->data[stack->size-1];
-+}
-+
-+void* apc_stack_get(apc_stack_t* stack, int n)
-+{
-+ assert(stack != NULL && stack->size > n);
-+ return stack->data[n];
-+}
-+
-+int apc_stack_size(apc_stack_t* stack)
-+{
-+ assert(stack != NULL);
-+ return stack->size;
-+}
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_stack.h b/ext/apc/apc_stack.h
---- a/ext/apc/apc_stack.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_stack.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,58 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_stack.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#ifndef APC_STACK_H
-+#define APC_STACK_H
-+
-+/* Basic stack datatype */
-+
-+#define T apc_stack_t*
-+typedef struct apc_stack_t apc_stack_t; /* opaque stack type */
-+
-+extern T apc_stack_create(int size_hint TSRMLS_DC);
-+extern void apc_stack_destroy(T stack TSRMLS_DC);
-+extern void apc_stack_clear(T stack);
-+extern void apc_stack_push(T stack, void* item TSRMLS_DC);
-+extern void* apc_stack_pop(T stack);
-+extern void* apc_stack_top(T stack);
-+extern void* apc_stack_get(T stack, int n);
-+extern int apc_stack_size(T stack);
-+
-+#undef T
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_string.c b/ext/apc/apc_string.c
---- a/ext/apc/apc_string.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_string.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,261 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Dmitry Stogov <dmitry@zend.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_string.c 326089 2012-06-11 04:29:57Z rasmus $ */
-+
-+#include "apc.h"
-+#include "apc_globals.h"
-+#include "apc_php.h"
-+#include "apc_lock.h"
-+
-+#ifdef ZEND_ENGINE_2_4
-+
-+#ifndef ZTS
-+typedef struct _apc_interned_strings_data_t {
-+ char *interned_strings_start;
-+ char *interned_strings_end;
-+ char *interned_strings_top;
-+ apc_lck_t lock;
-+ HashTable interned_strings;
-+} apc_interned_strings_data_t;
-+
-+apc_interned_strings_data_t *apc_interned_strings_data = NULL;
-+
-+#define APCSG(v) (apc_interned_strings_data->v)
-+
-+static char *old_interned_strings_start;
-+static char *old_interned_strings_end;
-+static const char *(*old_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
-+static void (*old_interned_strings_snapshot)(TSRMLS_D);
-+static void (*old_interned_strings_restore)(TSRMLS_D);
-+
-+static const char *apc_dummy_new_interned_string_for_php(const char *str, int len, int free_src TSRMLS_DC)
-+{
-+ return str;
-+}
-+
-+static void apc_dummy_interned_strings_snapshot_for_php(TSRMLS_D)
-+{
-+}
-+
-+static void apc_dummy_interned_strings_restore_for_php(TSRMLS_D)
-+{
-+}
-+#endif
-+
-+const char *apc_new_interned_string(const char *arKey, int nKeyLength TSRMLS_DC)
-+{
-+#ifndef ZTS
-+ ulong h;
-+ uint nIndex;
-+ Bucket *p;
-+
-+ if (arKey >= APCSG(interned_strings_start) && arKey < APCSG(interned_strings_end)) {
-+ return arKey;
-+ }
-+
-+ h = zend_inline_hash_func(arKey, nKeyLength);
-+ nIndex = h & APCSG(interned_strings).nTableMask;
-+
-+ p = APCSG(interned_strings).arBuckets[nIndex];
-+ while (p != NULL) {
-+ if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
-+ if (!memcmp(p->arKey, arKey, nKeyLength)) {
-+ return p->arKey;
-+ }
-+ }
-+ p = p->pNext;
-+ }
-+
-+ if (APCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength + 1) >=
-+ APCSG(interned_strings_end)) {
-+ /* no memory */
-+ return NULL;
-+ }
-+
-+ p = (Bucket *) APCSG(interned_strings_top);
-+ APCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength + 1);
-+
-+ p->arKey = (char*)(p+1);
-+ memcpy(p->arKey, arKey, nKeyLength);
-+ ((char *)p->arKey)[nKeyLength] = '\0';
-+ p->nKeyLength = nKeyLength;
-+ p->h = h;
-+ p->pData = &p->pDataPtr;
-+ p->pDataPtr = p;
-+
-+ p->pNext = APCSG(interned_strings).arBuckets[nIndex];
-+ p->pLast = NULL;
-+ if (p->pNext) {
-+ p->pNext->pLast = p;
-+ }
-+ APCSG(interned_strings).arBuckets[nIndex] = p;
-+
-+ p->pListLast = APCSG(interned_strings).pListTail;
-+ APCSG(interned_strings).pListTail = p;
-+ p->pListNext = NULL;
-+ if (p->pListLast != NULL) {
-+ p->pListLast->pListNext = p;
-+ }
-+ if (!APCSG(interned_strings).pListHead) {
-+ APCSG(interned_strings).pListHead = p;
-+ }
-+
-+ APCSG(interned_strings).nNumOfElements++;
-+
-+ return p->arKey;
-+#else
-+ return zend_new_interned_string(arKey, nKeyLength, 0 TSRMLS_CC);
-+#endif
-+}
-+
-+#ifndef ZTS
-+static void apc_copy_internal_strings(TSRMLS_D)
-+{
-+ Bucket *p, *q;
-+
-+ p = CG(function_table)->pListHead;
-+ while (p) {
-+ if (p->nKeyLength) {
-+ p->arKey = apc_new_interned_string(p->arKey, p->nKeyLength TSRMLS_CC);
-+ }
-+ p = p->pListNext;
-+ }
-+
-+ p = CG(class_table)->pListHead;
-+ while (p) {
-+ zend_class_entry *ce = (zend_class_entry*)(p->pDataPtr);
-+
-+ if (p->nKeyLength) {
-+ p->arKey = apc_new_interned_string(p->arKey, p->nKeyLength TSRMLS_CC);
-+ }
-+
-+ if (ce->name) {
-+ ce->name = apc_new_interned_string(ce->name, ce->name_length+1 TSRMLS_CC);
-+ }
-+
-+ q = ce->properties_info.pListHead;
-+ while (q) {
-+ zend_property_info *info = (zend_property_info*)(q->pData);
-+
-+ if (q->nKeyLength) {
-+ q->arKey = apc_new_interned_string(q->arKey, q->nKeyLength TSRMLS_CC);
-+ }
-+
-+ if (info->name) {
-+ info->name = apc_new_interned_string(info->name, info->name_length+1 TSRMLS_CC);
-+ }
-+
-+ q = q->pListNext;
-+ }
-+
-+ q = ce->function_table.pListHead;
-+ while (q) {
-+ if (q->nKeyLength) {
-+ q->arKey = apc_new_interned_string(q->arKey, q->nKeyLength TSRMLS_CC);
-+ }
-+ q = q->pListNext;
-+ }
-+
-+ q = ce->constants_table.pListHead;
-+ while (q) {
-+ if (q->nKeyLength) {
-+ q->arKey = apc_new_interned_string(q->arKey, q->nKeyLength TSRMLS_CC);
-+ }
-+ q = q->pListNext;
-+ }
-+
-+ p = p->pListNext;
-+ }
-+
-+ p = EG(zend_constants)->pListHead;
-+ while (p) {
-+ if (p->nKeyLength) {
-+ p->arKey = apc_new_interned_string(p->arKey, p->nKeyLength TSRMLS_CC);
-+ }
-+ p = p->pListNext;
-+ }
-+}
-+
-+void apc_interned_strings_init(TSRMLS_D)
-+{
-+ int count = APCG(shm_strings_buffer) / (sizeof(Bucket) + sizeof(Bucket*) * 2);
-+
-+ apc_interned_strings_data = (apc_interned_strings_data_t*) apc_sma_malloc(APCG(shm_strings_buffer) TSRMLS_CC);
-+ memset((void *)apc_interned_strings_data, 0, APCG(shm_strings_buffer));
-+
-+ CREATE_LOCK(APCSG(lock));
-+
-+ zend_hash_init(&APCSG(interned_strings), count, NULL, NULL, 1);
-+ APCSG(interned_strings).nTableMask = APCSG(interned_strings).nTableSize - 1;
-+ APCSG(interned_strings).arBuckets = (Bucket**)((char*)apc_interned_strings_data + sizeof(apc_interned_strings_data_t));
-+
-+ APCSG(interned_strings_start) = (char*)APCSG(interned_strings).arBuckets + APCSG(interned_strings).nTableSize * sizeof(Bucket *);
-+ APCSG(interned_strings_end) = (char*)apc_interned_strings_data + APCG(shm_strings_buffer);
-+ APCSG(interned_strings_top) = APCSG(interned_strings_start);
-+
-+ old_interned_strings_start = CG(interned_strings_start);
-+ old_interned_strings_end = CG(interned_strings_end);
-+ old_new_interned_string = zend_new_interned_string;
-+ old_interned_strings_snapshot = zend_interned_strings_snapshot;
-+ old_interned_strings_restore = zend_interned_strings_restore;
-+
-+ CG(interned_strings_start) = APCSG(interned_strings_start);
-+ CG(interned_strings_end) = APCSG(interned_strings_end);
-+ zend_new_interned_string = apc_dummy_new_interned_string_for_php;
-+ zend_interned_strings_snapshot = apc_dummy_interned_strings_snapshot_for_php;
-+ zend_interned_strings_restore = apc_dummy_interned_strings_restore_for_php;
-+
-+ apc_copy_internal_strings(TSRMLS_C);
-+}
-+
-+void apc_interned_strings_shutdown(TSRMLS_D)
-+{
-+ zend_hash_clean(CG(function_table));
-+ zend_hash_clean(CG(class_table));
-+ zend_hash_clean(EG(zend_constants));
-+
-+ CG(interned_strings_start) = old_interned_strings_start;
-+ CG(interned_strings_end) = old_interned_strings_end;
-+ zend_new_interned_string = old_new_interned_string;
-+ zend_interned_strings_snapshot = old_interned_strings_snapshot;
-+ zend_interned_strings_restore = old_interned_strings_restore;
-+
-+ DESTROY_LOCK(APCSG(lock));
-+}
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_string.h b/ext/apc/apc_string.h
---- a/ext/apc/apc_string.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_string.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,51 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Dmitry Stogov <dmitry@zend.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_string.h 324145 2012-03-12 11:38:28Z pajoye $ */
-+
-+#ifndef APC_STRING
-+#define APC_STRING
-+
-+#include "apc.h"
-+
-+#ifndef ZTS
-+void apc_interned_strings_init(TSRMLS_D);
-+void apc_interned_strings_shutdown(TSRMLS_D);
-+#endif
-+
-+const char *apc_new_interned_string(const char *arKey, int nKeyLength TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_windows_srwlock_kernel.c b/ext/apc/apc_windows_srwlock_kernel.c
---- a/ext/apc/apc_windows_srwlock_kernel.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_windows_srwlock_kernel.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,133 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Pierre Joye <pierre@php.net> |
-+ +----------------------------------------------------------------------+
-+ */
-+/* $Id$ */
-+/*
-+ These APIs are not actually exposed nor documented. But should work fine
-+ from a binary as available since XP without signature changes.
-+*/
-+/*
-+TODOs:
-+non blocking could be possible using the fWait argument (to 0). However
-+I'm not sure whether the wait handlers is actually implemented in all
-+supported platforms (xp+). could be enabled later once really tested.
-+ */
-+/* $Id: $ */
-+
-+#include <php.h>
-+
-+#ifdef APC_SRWLOCK_KERNEL
-+#include "apc_windows_srwlock_kernel.h"
-+
-+/*
-+For references:
-+void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl);
-+void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl);
-+BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait);
-+BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait);
-+void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl);
-+*/
-+typedef void (WINAPI *tRtlInitializeResource)(LPRTL_RWLOCK rwl);
-+typedef void (WINAPI *tRtlDeleteResource)(LPRTL_RWLOCK rwl);
-+typedef BYTE (WINAPI *tRtlAcquireResourceExclusive)(LPRTL_RWLOCK rwl, BYTE fWait);
-+typedef BYTE (WINAPI *tRtlAcquireResourceShared)(LPRTL_RWLOCK rwl, BYTE fWait);
-+typedef void (WINAPI *tRtlReleaseResource)(LPRTL_RWLOCK rwl);
-+typedef void (WINAPI *tRtlDumpResource)(LPRTL_RWLOCK rwl);
-+
-+tRtlInitializeResource pRtlInitializeResource = 0;
-+tRtlDeleteResource pRtlDeleteResource = 0;
-+tRtlAcquireResourceExclusive pRtlAcquireResourceExclusive = 0;
-+tRtlAcquireResourceShared pRtlAcquireResourceShared = 0;
-+tRtlReleaseResource pRtlReleaseResource = 0;
-+tRtlDumpResource pRtlDumpResource = 0;
-+
-+HINSTANCE ntdll;
-+
-+void apc_windows_cs_status(apc_windows_cs_rwlock_t *lock );
-+apc_windows_cs_rwlock_t *apc_windows_cs_create(apc_windows_cs_rwlock_t *lock TSRMLS_DC)
-+{
-+ ntdll = LoadLibrary("ntdll.dll");
-+ if (ntdll == 0) {
-+ return NULL;
-+ }
-+
-+ pRtlInitializeResource = (tRtlInitializeResource) GetProcAddress(ntdll, "RtlInitializeResource");
-+ pRtlDeleteResource = (tRtlDeleteResource) GetProcAddress(ntdll, "RtlDeleteResource");
-+ pRtlAcquireResourceExclusive = (tRtlAcquireResourceExclusive) GetProcAddress(ntdll, "RtlAcquireResourceExclusive");
-+ pRtlAcquireResourceShared = (tRtlAcquireResourceShared) GetProcAddress(ntdll, "RtlAcquireResourceShared");
-+ pRtlReleaseResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlReleaseResource");
-+ pRtlDumpResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlDumpResource");
-+ if (pRtlInitializeResource == 0 || pRtlDeleteResource == 0 || pRtlAcquireResourceExclusive == 0 ||
-+ pRtlAcquireResourceShared == 0 || pRtlReleaseResource == 0 || pRtlDumpResource == 0) {
-+ return NULL;
-+ }
-+ pRtlInitializeResource(lock);
-+ return lock;
-+}
-+
-+void apc_windows_cs_destroy(apc_windows_cs_rwlock_t *lock)
-+{
-+ __try
-+ {
-+ pRtlDeleteResource(lock);
-+ }
-+ __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
-+ EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
-+ {
-+ /* Ignore exception (resource was freed during shutdown of another thread) */
-+ }
-+ FreeLibrary(ntdll);
-+ return;
-+}
-+
-+void apc_windows_cs_lock(apc_windows_cs_rwlock_t *lock TSRMLS_DC)
-+{
-+ pRtlAcquireResourceExclusive(lock, 1);
-+}
-+
-+void apc_windows_cs_rdlock(apc_windows_cs_rwlock_t *lock TSRMLS_DC)
-+{
-+ pRtlAcquireResourceShared(lock, 1);
-+}
-+
-+void apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t *lock TSRMLS_DC)
-+{
-+ pRtlReleaseResource(lock);
-+}
-+
-+void apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t *lock TSRMLS_DC)
-+{
-+ pRtlReleaseResource(lock);
-+}
-+
-+/* debugging purposes, output using trace msgs */
-+void apc_windows_cs_status(apc_windows_cs_rwlock_t *lock)
-+{
-+ pRtlDumpResource(lock);
-+ return;
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_windows_srwlock_kernel.h b/ext/apc/apc_windows_srwlock_kernel.h
---- a/ext/apc/apc_windows_srwlock_kernel.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_windows_srwlock_kernel.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,74 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Pierre Joye <pierre@php.net> |
-+ +----------------------------------------------------------------------+
-+ */
-+/* $Id$ */
-+
-+#ifndef APC_WINDOWS_CS_RWLOCK_H
-+#define APC_WINDOWS_CS_RWLOCK_H
-+
-+#include "apc.h"
-+
-+#ifdef APC_SRWLOCK_KERNEL
-+
-+typedef struct _RTL_RWLOCK {
-+ RTL_CRITICAL_SECTION rtlCS;
-+
-+ HANDLE hSharedReleaseSemaphore;
-+ UINT uSharedWaiters;
-+
-+ HANDLE hExclusiveReleaseSemaphore;
-+ UINT uExclusiveWaiters;
-+
-+ INT iNumberActive;
-+ HANDLE hOwningThreadId;
-+ DWORD dwTimeoutBoost;
-+ PVOID pDebugInfo;
-+} RTL_RWLOCK, *LPRTL_RWLOCK;
-+
-+#define apc_windows_cs_rwlock_t RTL_RWLOCK
-+
-+struct apc_windows_cs_rwlock_t {
-+ CRITICAL_SECTION cs;
-+ LONG writers_waiting_count;
-+ LONG readers_waiting_count;
-+ DWORD active_writers_readers_flag;
-+ HANDLE ready_to_read;
-+ HANDLE ready_to_write;
-+ DWORD reader_races_lost;
-+};
-+
-+apc_windows_cs_rwlock_t *apc_windows_cs_create(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+void apc_windows_cs_destroy(apc_windows_cs_rwlock_t *lock);
-+void apc_windows_cs_lock(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+void apc_windows_cs_rdlock(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+void apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+void apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+# if NONBLOCKING_LOCK_AVAILABLE==1 /* Only in win7/2008 */
-+zend_bool apc_pthreadrwlock_nonblocking_lock(apc_windows_cs_rwlock_t *lock TSRMLS_DC);
-+# endif
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_zend.c b/ext/apc/apc_zend.c
---- a/ext/apc/apc_zend.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_zend.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,271 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_zend.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+#include "apc_zend.h"
-+#include "apc_globals.h"
-+
-+/* true global */
-+int apc_reserved_offset;
-+
-+void* apc_php_malloc(size_t n TSRMLS_DC)
-+{
-+ return emalloc(n);
-+}
-+
-+void apc_php_free(void* p TSRMLS_DC)
-+{
-+ efree(p);
-+}
-+
-+#ifdef APC_OPCODE_OVERRIDE
-+
-+static opcode_handler_t *apc_original_opcode_handlers;
-+static opcode_handler_t apc_opcode_handlers[APC_OPCODE_HANDLER_COUNT];
-+
-+#define APC_EX_T(offset) (*(temp_variable *)((char*)execute_data->Ts + offset))
-+
-+#ifdef ZEND_ENGINE_2_4
-+static zval *apc_get_zval_ptr(zend_uchar op_type, znode_op *node, zval **freeval, zend_execute_data *execute_data TSRMLS_DC)
-+{
-+ *freeval = NULL;
-+
-+ switch (op_type) {
-+ case IS_CONST:
-+ return node->zv;
-+ case IS_VAR:
-+ return APC_EX_T(node->var).var.ptr;
-+ case IS_TMP_VAR:
-+ return (*freeval = &APC_EX_T(node->var).tmp_var);
-+ case IS_CV:
-+ {
-+ zval ***ret = &execute_data->CVs[node->var];
-+
-+ if (!*ret) {
-+ zend_compiled_variable *cv = &EG(active_op_array)->vars[node->var];
-+
-+ if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void**)ret)==FAILURE) {
-+ apc_notice("Undefined variable: %s" TSRMLS_CC, cv->name);
-+ return &EG(uninitialized_zval);
-+ }
-+ }
-+ return **ret;
-+ }
-+ case IS_UNUSED:
-+ default:
-+ return NULL;
-+ }
-+}
-+#else
-+static zval *apc_get_zval_ptr(znode *node, zval **freeval, zend_execute_data *execute_data TSRMLS_DC)
-+{
-+ *freeval = NULL;
-+
-+ switch (node->op_type) {
-+ case IS_CONST:
-+ return &(node->u.constant);
-+ case IS_VAR:
-+ return APC_EX_T(node->u.var).var.ptr;
-+ case IS_TMP_VAR:
-+ return (*freeval = &APC_EX_T(node->u.var).tmp_var);
-+#ifdef ZEND_ENGINE_2_1
-+ case IS_CV:
-+ {
-+ zval ***ret = &execute_data->CVs[node->u.var];
-+
-+ if (!*ret) {
-+ zend_compiled_variable *cv = &EG(active_op_array)->vars[node->u.var];
-+
-+ if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void**)ret)==FAILURE) {
-+ apc_notice("Undefined variable: %s" TSRMLS_CC, cv->name);
-+ return &EG(uninitialized_zval);
-+ }
-+ }
-+ return **ret;
-+ }
-+#endif
-+ case IS_UNUSED:
-+ default:
-+ return NULL;
-+ }
-+}
-+#endif
-+
-+static int ZEND_FASTCALL apc_op_ZEND_INCLUDE_OR_EVAL(ZEND_OPCODE_HANDLER_ARGS)
-+{
-+ APC_ZEND_OPLINE
-+ zval *freeop1 = NULL;
-+ zval *inc_filename = NULL, tmp_inc_filename;
-+ char realpath[MAXPATHLEN];
-+ php_stream_wrapper *wrapper;
-+ char *path_for_open;
-+ char *full_path = NULL;
-+ int ret = 0;
-+ apc_opflags_t* flags = NULL;
-+
-+#ifdef ZEND_ENGINE_2_4
-+ if (opline->extended_value != ZEND_INCLUDE_ONCE &&
-+ opline->extended_value != ZEND_REQUIRE_ONCE) {
-+ return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ }
-+
-+ inc_filename = apc_get_zval_ptr(opline->op1_type, &opline->op1, &freeop1, execute_data TSRMLS_CC);
-+#else
-+ if (Z_LVAL(opline->op2.u.constant) != ZEND_INCLUDE_ONCE &&
-+ Z_LVAL(opline->op2.u.constant) != ZEND_REQUIRE_ONCE) {
-+ return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ }
-+
-+ inc_filename = apc_get_zval_ptr(&opline->op1, &freeop1, execute_data TSRMLS_CC);
-+#endif
-+
-+ if (Z_TYPE_P(inc_filename) != IS_STRING) {
-+ tmp_inc_filename = *inc_filename;
-+ zval_copy_ctor(&tmp_inc_filename);
-+ convert_to_string(&tmp_inc_filename);
-+ inc_filename = &tmp_inc_filename;
-+ }
-+
-+ wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(inc_filename), &path_for_open, 0 TSRMLS_CC);
-+
-+ if (wrapper != &php_plain_files_wrapper || !(IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) || (full_path = expand_filepath(path_for_open, realpath TSRMLS_CC)))) {
-+ /* Fallback to original handler */
-+ if (inc_filename == &tmp_inc_filename) {
-+ zval_dtor(&tmp_inc_filename);
-+ }
-+ return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ }
-+
-+ if (!full_path) {
-+ full_path = path_for_open;
-+ }
-+ if (zend_hash_exists(&EG(included_files), realpath, strlen(realpath) + 1)) {
-+#ifdef ZEND_ENGINE_2_4
-+ if (!(opline->result_type & EXT_TYPE_UNUSED)) {
-+ ALLOC_INIT_ZVAL(APC_EX_T(opline->result.var).var.ptr);
-+ ZVAL_TRUE(APC_EX_T(opline->result.var).var.ptr);
-+ }
-+#else
-+ if (!(opline->result.u.EA.type & EXT_TYPE_UNUSED)) {
-+ ALLOC_INIT_ZVAL(APC_EX_T(opline->result.u.var).var.ptr);
-+ ZVAL_TRUE(APC_EX_T(opline->result.u.var).var.ptr);
-+ }
-+#endif
-+ if (inc_filename == &tmp_inc_filename) {
-+ zval_dtor(&tmp_inc_filename);
-+ }
-+ if (freeop1) {
-+ zval_dtor(freeop1);
-+ }
-+ execute_data->opline++;
-+ return 0;
-+ }
-+
-+ if (inc_filename == &tmp_inc_filename) {
-+ zval_dtor(&tmp_inc_filename);
-+ }
-+
-+ if(apc_reserved_offset != -1) {
-+ /* Insanity alert: look into apc_compile.c for why a void** is cast to a apc_opflags_t* */
-+ flags = (apc_opflags_t*) & (execute_data->op_array->reserved[apc_reserved_offset]);
-+ }
-+
-+ if(flags && flags->deep_copy == 1) {
-+ /* Since the op array is a local copy, we can cheat our way through the file inclusion by temporarily
-+ * changing the op to a plain require/include, calling its handler and finally restoring the opcode.
-+ */
-+#ifdef ZEND_ENGINE_2_4
-+ opline->extended_value = (opline->extended_value == ZEND_INCLUDE_ONCE) ? ZEND_INCLUDE : ZEND_REQUIRE;
-+ ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ opline->extended_value = (opline->extended_value == ZEND_INCLUDE) ? ZEND_INCLUDE_ONCE : ZEND_REQUIRE_ONCE;
-+#else
-+ Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE_ONCE) ? ZEND_INCLUDE : ZEND_REQUIRE;
-+ ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE) ? ZEND_INCLUDE_ONCE : ZEND_REQUIRE_ONCE;
-+#endif
-+ } else {
-+ ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-+ }
-+
-+ return ret;
-+}
-+
-+void apc_zend_init(TSRMLS_D)
-+{
-+ zend_extension dummy_ext;
-+ apc_reserved_offset = zend_get_resource_handle(&dummy_ext);
-+ assert(apc_reserved_offset == dummy_ext.resource_number);
-+ assert(apc_reserved_offset != -1);
-+ assert(sizeof(apc_opflags_t) <= sizeof(void*));
-+ if (!APCG(include_once)) {
-+ /* If we're not overriding the INCLUDE_OR_EVAL handler, then just skip this malarkey */
-+ return;
-+ }
-+
-+ memcpy(apc_opcode_handlers, zend_opcode_handlers, sizeof(apc_opcode_handlers));
-+
-+ /* 5.0 exposes zend_opcode_handlers differently than 5.1 and later */
-+#ifdef ZEND_ENGINE_2_1
-+ apc_original_opcode_handlers = zend_opcode_handlers;
-+ zend_opcode_handlers = apc_opcode_handlers;
-+#else
-+ apc_original_opcode_handlers = apc_opcode_handlers;
-+#endif
-+
-+ APC_REPLACE_OPCODE(ZEND_INCLUDE_OR_EVAL);
-+}
-+
-+void apc_zend_shutdown(TSRMLS_D)
-+{
-+ if (!APCG(include_once)) {
-+ /* Nothing changed, nothing to restore */
-+ return;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_1
-+ zend_opcode_handlers = apc_original_opcode_handlers;
-+#else
-+ memcpy(zend_opcode_handlers, apc_original_opcode_handlers, sizeof(apc_opcode_handlers));
-+#endif
-+}
-+
-+#else /* Opcode Overrides unavailable */
-+
-+void apc_zend_init(TSRMLS_D) { }
-+void apc_zend_shutdown(TSRMLS_D) { }
-+
-+#endif /* APC_OPCODE_OVERRIDE */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/apc_zend.h b/ext/apc/apc_zend.h
---- a/ext/apc/apc_zend.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/apc_zend.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,191 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: apc_zend.h 326712 2012-07-19 21:33:27Z rasmus $ */
-+
-+#ifndef APC_ZEND_H
-+#define APC_ZEND_H
-+
-+/* Utilities for interfacing with the zend engine */
-+
-+#include "apc.h"
-+#include "apc_php.h"
-+
-+#ifndef Z_REFCOUNT_P
-+#define Z_REFCOUNT_P(pz) (pz)->refcount
-+#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))
-+#endif
-+
-+#ifndef Z_SET_REFCOUNT_P
-+#define Z_SET_REFCOUNT_P(pz, rc) (pz)->refcount = rc
-+#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc)
-+#endif
-+
-+#ifndef Z_ADDREF_P
-+#define Z_ADDREF_P(pz) (pz)->refcount++
-+#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz))
-+#endif
-+
-+#ifndef Z_DELREF_P
-+#define Z_DELREF_P(pz) (pz)->refcount--
-+#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
-+#endif
-+
-+#ifndef Z_ISREF_P
-+#define Z_ISREF_P(pz) (pz)->is_ref
-+#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz))
-+#endif
-+
-+#ifndef Z_SET_ISREF_P
-+#define Z_SET_ISREF_P(pz) (pz)->is_ref = 1
-+#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz))
-+#endif
-+
-+#ifndef Z_UNSET_ISREF_P
-+#define Z_UNSET_ISREF_P(pz) (pz)->is_ref = 0
-+#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz))
-+#endif
-+
-+#ifndef Z_SET_ISREF_TO_P
-+#define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = isref
-+#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref)
-+#endif
-+
-+
-+extern void* apc_php_malloc(size_t n TSRMLS_DC);
-+extern void apc_php_free(void* p TSRMLS_DC);
-+
-+extern void apc_zend_init(TSRMLS_D);
-+extern void apc_zend_shutdown(TSRMLS_D);
-+
-+
-+/* offset for apc info in op_array->reserved */
-+extern int apc_reserved_offset;
-+
-+#ifndef ZEND_VM_KIND_CALL /* Not currently defined by any ZE version */
-+# define ZEND_VM_KIND_CALL 1
-+#endif
-+
-+#ifndef ZEND_VM_KIND /* Indicates PHP < 5.1 */
-+# define ZEND_VM_KIND ZEND_VM_KIND_CALL
-+#endif
-+
-+#if defined(ZEND_ENGINE_2) && (ZEND_VM_KIND == ZEND_VM_KIND_CALL)
-+# define APC_OPCODE_OVERRIDE
-+#endif
-+
-+#ifdef APC_OPCODE_OVERRIDE
-+
-+#ifdef ZEND_ENGINE_2_1
-+/* Taken from Zend/zend_vm_execute.h */
-+#define _CONST_CODE 0
-+#define _TMP_CODE 1
-+#define _VAR_CODE 2
-+#define _UNUSED_CODE 3
-+#define _CV_CODE 4
-+static inline int _apc_opcode_handler_decode(zend_op *opline)
-+{
-+ static const int apc_vm_decode[] = {
-+ _UNUSED_CODE, /* 0 */
-+ _CONST_CODE, /* 1 = IS_CONST */
-+ _TMP_CODE, /* 2 = IS_TMP_VAR */
-+ _UNUSED_CODE, /* 3 */
-+ _VAR_CODE, /* 4 = IS_VAR */
-+ _UNUSED_CODE, /* 5 */
-+ _UNUSED_CODE, /* 6 */
-+ _UNUSED_CODE, /* 7 */
-+ _UNUSED_CODE, /* 8 = IS_UNUSED */
-+ _UNUSED_CODE, /* 9 */
-+ _UNUSED_CODE, /* 10 */
-+ _UNUSED_CODE, /* 11 */
-+ _UNUSED_CODE, /* 12 */
-+ _UNUSED_CODE, /* 13 */
-+ _UNUSED_CODE, /* 14 */
-+ _UNUSED_CODE, /* 15 */
-+ _CV_CODE /* 16 = IS_CV */
-+ };
-+#ifdef ZEND_ENGINE_2_4
-+ return (opline->opcode * 25) + (apc_vm_decode[opline->op1_type] * 5) + apc_vm_decode[opline->op2_type];
-+#else
-+ return (opline->opcode * 25) + (apc_vm_decode[opline->op1.op_type] * 5) + apc_vm_decode[opline->op2.op_type];
-+#endif
-+}
-+
-+# define APC_ZEND_OPLINE zend_op *opline = execute_data->opline;
-+# define APC_OPCODE_HANDLER_DECODE(opline) _apc_opcode_handler_decode(opline)
-+# if PHP_MAJOR_VERSION >= 6
-+# define APC_OPCODE_HANDLER_COUNT ((25 * 152) + 1)
-+# elif defined(ZEND_ENGINE_2_4)
-+# define APC_OPCODE_HANDLER_COUNT ((25 * 159) + 1) /* 5 new opcodes in 5.4 - qm_assign_var, jmp_set_var, separate, bind_trais, add_trait */
-+# elif PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3
-+# define APC_OPCODE_HANDLER_COUNT ((25 * 154) + 1) /* 3 new opcodes in 5.3 - unused, lambda, jmp_set */
-+# else
-+# define APC_OPCODE_HANDLER_COUNT ((25 * 151) + 1)
-+# endif
-+# define APC_REPLACE_OPCODE(opname) { int i; for(i = 0; i < 25; i++) if (zend_opcode_handlers[(opname*25) + i]) zend_opcode_handlers[(opname*25) + i] = apc_op_##opname; }
-+
-+#else /* ZE2.0 */
-+# define APC_ZEND_ONLINE
-+# define APC_OPCODE_HANDLER_DECODE(opline) (opline->opcode)
-+# define APC_OPCODE_HANDLER_COUNT 512
-+# define APC_REPLACE_OPCODE(opname) zend_opcode_handlers[opname] = apc_op_##opname;
-+#endif
-+
-+#ifndef ZEND_FASTCALL /* Added in ZE2.3.0 */
-+#define ZEND_FASTCALL
-+#endif
-+
-+/* Added in ZE2.3.0 */
-+#ifndef zend_parse_parameters_none
-+# define zend_parse_parameters_none() zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")
-+#endif
-+
-+
-+#endif /* APC_OPCODE_OVERRIDE */
-+
-+#ifdef ZEND_ENGINE_2_4
-+# define ZEND_CE_FILENAME(ce) (ce)->info.user.filename
-+# define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment
-+# define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->info.user.doc_comment_len
-+# define ZEND_CE_BUILTIN_FUNCTIONS(ce) (ce)->info.internal.builtin_functions
-+#else
-+# define ZEND_CE_FILENAME(ce) (ce)->filename
-+# define ZEND_CE_DOC_COMMENT(ce) (ce)->doc_comment
-+# define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->doc_comment_len
-+# define ZEND_CE_BUILTIN_FUNCTIONS(ce) (ce)->builtin_functions
-+#endif
-+
-+#endif /* APC_ZEND_H */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/CHANGELOG b/ext/apc/CHANGELOG
---- a/ext/apc/CHANGELOG 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/CHANGELOG 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,249 @@
-+
-+3.1.2 : 2008-12-12
-+
-+- pecl package.xml/build fixes (bjori)
-+
-+3.1.1 : 2008-12-12
-+
-+- PHP4 compatibilty break
-+- apc_pool allocator (Gopal)
-+- doubly-linked sma allocator (Shire)
-+- php 5.3 gc compatibility (Gopal)
-+- APCIterator for easy access (Shire)
-+- apc_delete_file (Shire)
-+- apc_inc/apc_dec/apc_cas functions (Shire)
-+- apc.canonicalize (Gopal)
-+- apc.preload_path (Gopal)
-+- apc.rfc1867_ttl (Shire)
-+- apc.file_md5 (Shire)
-+- consolidate locking macros (Shire)
-+- remove futex/TSRM locks (Shire)
-+- non-blocking semaphore locks (Shire)
-+- zval* object rework (Gopal)
-+
-+3.0.19: 2008-05-14
-+- Safe-mode and fast-cgi fixes
-+- Fix double-free of builtin_functions
-+- php 5.3 fixes
-+
-+3.0.18: 2008-03-29
-+- Revert apc_expunge_cb bug-fix
-+- Misc memleaks
-+
-+3.0.17: 2008-03-26
-+- Crash fixes
-+- Fix apc_add() cache expunge bug (Rasmus)
-+- Added parameter to apc_fetch to determine success/failure when fetching booleans (shire)
-+- Fix misc. memleaks (shire)
-+
-+3.0.16: 2007-12-26
-+- Fix for longstanding cache-full crash (Christian Seiler)
-+ http://news.php.net/php.pecl.dev/4951 for the details
-+- Added optional shm unmap on a fatal signal feature (Lucas Nealan)
-+- Added PTHREAD_MUTEX_ADAPTIVE_NP option pthread locks (Paul Saab)
-+- Minor cleanups (Lucas Nealan)
-+- Added configure option to enable apc_cache_info('filehits') (Shire)
-+
-+3.0.15: 2007-10-18
-+- Eliminate a per-request time() syscall (Rasmus)
-+- Added rfc1867 prefix, name, and freq ini options (Shire)
-+- Allow deletion of individual user cache entries via apc.php (Sara)
-+- Fix overzealous cleanup during RSHUTDOWN (Gopal)
-+- Fix memory alignment and locking issues (Gopal)
-+- Make apc_compile insert/replace entries (Shire)
-+- Make mixed inheritance recompile & cache afresh (Gopal)
-+- Make nostat mode search include_path for canonicalization (Gopal)
-+- ZTS & other compile fixes (Gopal, Edin, Shire)
-+
-+3.0.14: 2007-03-21
-+- Build fix (Shire)
-+- Don't hook the upload hook if APC is disabled (Rasmus)
-+- Local shadow cache support (Gopal)
-+- Avoid uneccessary loops over op_arrays for "known" auto-globals (Gopal)
-+- Fix apc_add() to overwrite timed out user entries (Rasmus)
-+- Fix double inclusion of files with conditional classes in php4 (Gopal)
-+- Allocator fixes to reduce fragmentation (Gopal)
-+
-+3.0.13: 2007-02-24
-+- File upload progress (Rasmus)
-+- Pthread mutex and spin locks (Shire)
-+- Recursive zval support for apc_fetch/_store (Shire, Gopal)
-+- apc.stat_ctime flag for ctime checks (Rasmus)
-+- Multiple key fetches with apc_fetch (Shire)
-+- Canary checks for shm memory deallocation (Gopal)
-+- Add hooks for external optimizer (Shire)
-+- Obsolete and remove apc optimizer (Gopal)
-+- APC info changes - cache insert rate, hit and miss rates (Shire)
-+- Fix apc_load_constants (Gopal)
-+- Rewrite dump opcode code to use vld (Gopal)
-+- Use apc_[ewn]print functions for error reporting (Shire)
-+- Auto global fixes and refactoring (Gopal, Shire)
-+- Fix memory leaks in object serialization (Ilia)
-+- Memory cleanup code for destructor order (Gopal)
-+- Win32 build fixes (Ilia, Wez)
-+- ZTS and Php 4 build fixes (Bjori)
-+- Add apc_add() function (Rasmus)
-+- Add optional limited flag to apc_sma_info() (Rasmus)
-+
-+3.0.12p2: 2006-09-05
-+- Package version up
-+
-+3.0,12p1: 2006-09-05
-+- PHP4 build fixes
-+
-+3.0.12: 2006-09-05
-+- PHP 5.2 compatibility (Gopal)
-+- TSRM fixes (Gopal)
-+- Add extra flags to op_array->reserved to improve op array
-+ processing code (Gopal)
-+- Fix crashes in optimizer and cli mode (Ilia)
-+- Optimizer fixes for PHP5 (Ilia, Gopal)
-+- Allow multiple inclusions of a file with a dynamic class (Gopal)
-+- Php 4 function table and properties fixes (Gopal)
-+- Fix memory leaks in apc_cache_info (Gopal)
-+
-+3.0.11: 2006-08-16
-+- Made --enable-apc-mmap the default compile option (for real this time)
-+- Add an optional flag to apc_cache_info() and some apc.php tweaks to make it
-+ only fetch header information to make it useful when you have tens of
-+ thousands of entries. (Brian Shire)
-+- 64-bit fixes (George)
-+- Don't mix Full Path and Inode keys (George)
-+- Override ZEND_INCLUDE_OR_EVAL opcode (when possible) to speed up use of
-+ require_once() and include_once() statements. (Sara)
-+- Add a non-blocking write_lock for cache inserts. This is a better approach
-+ to prevent cache slams and deprecates the slam_defense setting. (Rasmus)
-+- A bit of work on the optimizer. (Sara)
-+- Various memory issues resolved. (Gopal)
-+
-+3.0.10: 2006-03-11
-+- Add apc.stat ini flag which defaults to 1. If set to 0, the main script and any fullpath
-+ includes will not be stat'ed for any changes. You will have to restart the server if you
-+ change anything. This mode increases performance quite a bit, especially if you have a
-+ lot of includes.
-+
-+- Get rid of the lock safety net hack I added in 3.0.9. It seems to cause more problems
-+ than it solves. I'll need to revisit locking and signal handling at some point soon.
-+
-+3.0.9: 2006-03-04
-+- Eliminate rand() call when slam_defense is not set (Rasmus)
-+- Fix for __isset problem (Gopal)
-+- Rewrite allocator from a "best fit" to a "next fit" algorithm (Rasmus)
-+- Added a Cache Full counter so we have an idea how many times the segment has filled up causing an expunge (Rasmus)
-+- Report back the correct number of available bytes in the segment instead of the allocated bytes. (Rasmus)
-+- Add cache busy flag which is set when an expunge is underway (Rasmus)
-+- Add automatic serialization of objects in apc_store() (Marcus)
-+- 64-bit .ini flag fix (Rasmus)
-+- Static members fix (Gopal)
-+- sma_cleanup() mem leak fix (Rasmus)
-+- Fix for http://pecl.php.net/bugs/5311 (Rasmus)
-+- Fix autoglobals JIT bug (Gopal)
-+- Fix instance bug (Gopal)
-+- Add a lock cleanup safety net to request shutdown (Rasmus)
-+- Fix apc.slam_defense edge-case bug (Rasmus)
-+- User entry memory usage tracking support (Ilia)
-+- Allow keys used in apc_store/apc_fetch/apc_delete to be binary safe and prevent conflicts between keys that are found at the start of other keys. (Ilia)
-+
-+3.0.8: 2005-08-24
-+Fix invalid free in globals destructor introduced in 3.0.7 (Rasmus)
-+Cache corruption fix in cache-full cleanup code (Gopal)
-+
-+3.0.7: 2005-08-16
-+- Fix to apc.php to show final segment in frag chart. (Ilia)
-+- A couple of win32 fixes. (Frank)
-+- Add apc.enable_cli ini directive. (Rasmus)
-+- Add test cases. (Marcus)
-+- Fix apc_define_constants() bug - http://pecl.php.net/bugs/5084 (Rasmus)
-+- Simplify user cache handling by removing the user_cache_stack (Rasmus)
-+- Fix apc_fetch() memory corruption (Andrei,Rasmus)
-+- Added apc.max_file_size INI setting that allows exclusion of large files from being cached. Default file size limit, 1 megabyte. (Ilia)
-+
-+3.0.6: 2005-07-30
-+- Added apc.php to package.xml file.
-+- Track per-entry memory usage. (Val)
-+- Various apc.php fixes and enhancements. (Ralf, Ilia, Rasmus)
-+- fcntl locking robustness fixes. (Rasmus)
-+- Shared read-locks where possible. (Rasmus)
-+- Added file_update_protection configuration parameter. (Rasmus)
-+- Windows ZTS fixes (Frank)
-+
-+3.0.5: 2005-07-27
-+- Make it easier for sapis that only populate file_handle->filename to use APC. (Rasmus)
-+- Support extensions such as bcompiler that need to hook into compile_file. (Val)
-+- Ralf Becker's apcgui code has now become the default apc.php status page. (Ralf, Rasmus, Ilia)
-+- Segfault in cache cleanup code (Ilia, Rasmus)
-+
-+3.0.4: 2005-07-18
-+- Add win32 support (Edin )
-+- Add --with-apxs switch to work around problem when loading APC into Apache binary compiled with LFS switches (Rasmus)
-+- A couple of other minor fixes
-+
-+3.0.3: 2005-07-05
-+- Fix compile problem against PHP 5.0.x
-+
-+3.0.2: 2005-07-05
-+- Better shm error message
-+
-+3.0.1: 2005-07-05
-+- PHP4 build fix
-+
-+3.0: 2005-06-23
-+- PHP 5.1 support (Arun, Gopal, Rasmus)
-+- Major Inheritance bug fix (Arun, Gopal)
-+
-+2.0: 2003-02-10
-+- ground-up rewrite sharing none of the original source code (djc)
-+
-+1.0.10:
-+- merge mmap / shm code to be in one file, module supports both modes now [mpb 2001-05-15]
-+- added apc.mode config parameter [mpb 2001-05-15] NOTE: You'll have to add
-+ this parameter to your php.ini file to activate apc shm or mmap caching
-+- generic source cleanup (missing includes, PATH_MAX usage etc) [mpb
-+ 2001-05-15]
-+- fixed: realpath return result checking in generate_key [mpb 2001-05-15]
-+- updated: gui updated (extras/apc_gui-1.0.2.tar.gz)
-+- experminental 'fast' cache-retrieval [djc 2001-05-20]
-+- fixed regex support [gws 2001-05-16]
-+- enhanced reader-writer lock support [rg 2001-05-07]
-+
-+1.0.9:
-+- fixed (?) memory alignment bug on 64 bit archiecures
-+- added many cache visibiliy functions
-+- added opional fcntl locks under shm version
-+- numerous bug fixes
-+
-+1.0.8:
-+- added ability to detect and decompile compiled files placed as 'source'
-+ [gws,dw 2001-01-30]
-+- fixed apc_rstat bug [gws 2001-01-29]
-+- added hack to support included urls [gws 2001-01-30]
-+- fixed apc_cache_index [mb 2001-01-31]
-+- added multiple regex support [gs 2001-02-03]
-+- added apc_cache_info [mb,gs 2001-02-03]
-+
-+1.0.7:
-+- partially fixed for Solaris [gws 2001-01-29]
-+- fixed mtime support for relative includes [gws 2001-01-29]
-+- code cleanup [yg,ta,gws 2001-01-29]
-+
-+1.0.6:
-+- support for mtime in mmap [yg,gws 2001-01-27]
-+- fixed indexed-array initialization bug [djc,gws 2001-01-27]
-+
-+1.0.5:
-+- support for relative include paths [djc,gws 2001-01-19]
-+- class member array support fixed [djc 2001-01-18]
-+- added apc_cache_index [gws 2001-01-18]
-+
-+1.0.4:
-+- support for class hierarchies greater than two levels deep [djc 2001-01-17]
-+
-+1.0.3:
-+- fixed support for class inheritance [djc 2001-01-16]
-+
-+1.0.2:
-+- support for inherited classes [gws 2001-01-15]
-+- support for intialization of class variables and objects [gws 2001-01-13]
-+
-+1.0.1:
-+- added optional file modification time check [djc 2001-01-12]
-diff -Naur a/ext/apc/config.m4 b/ext/apc/config.m4
---- a/ext/apc/config.m4 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/config.m4 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,404 @@
-+dnl
-+dnl $Id: config.m4 326700 2012-07-19 11:56:57Z ab $
-+dnl
-+
-+PHP_ARG_ENABLE(apc, whether to enable APC support,
-+[ --enable-apc Enable APC support])
-+
-+AC_ARG_ENABLE(apc-debug,
-+[ --enable-apc-debug Enable APC debugging],
-+[
-+ PHP_APC_DEBUG=$enableval
-+],
-+[
-+ PHP_APC_DEBUG=no
-+])
-+
-+AC_MSG_CHECKING(whether we should enable cache request file info)
-+AC_ARG_ENABLE(apc-filehits,
-+[ --enable-apc-filehits Enable per request file info about files used from the APC cache (ie: apc_cache_info('filehits')) ],
-+[
-+ PHP_APC_FILEHITS=$enableval
-+ AC_MSG_RESULT($enableval)
-+],
-+[
-+ PHP_APC_FILEHITS=no
-+ AC_MSG_RESULT(no)
-+])
-+
-+AC_MSG_CHECKING(whether we should use mmap)
-+AC_ARG_ENABLE(apc-mmap,
-+[ --disable-apc-mmap
-+ Disable mmap support and use IPC shm instead],
-+[
-+ PHP_APC_MMAP=$enableval
-+ AC_MSG_RESULT($enableval)
-+], [
-+ PHP_APC_MMAP=yes
-+ AC_MSG_RESULT(yes)
-+])
-+
-+AC_MSG_CHECKING(whether we should use semaphore locking instead of fcntl)
-+AC_ARG_ENABLE(apc-sem,
-+[ --enable-apc-sem
-+ Enable semaphore locks instead of fcntl],
-+[
-+ PHP_APC_SEM=$enableval
-+ AC_MSG_RESULT($enableval)
-+], [
-+ PHP_APC_SEM=no
-+ AC_MSG_RESULT(no)
-+])
-+
-+AC_MSG_CHECKING(whether we should use pthread mutex locking)
-+AC_ARG_ENABLE(apc-pthreadmutex,
-+[ --disable-apc-pthreadmutex
-+ Disable pthread mutex locking ],
-+[
-+ PHP_APC_PTHREADMUTEX=$enableval
-+ AC_MSG_RESULT($enableval)
-+],
-+[
-+ PHP_APC_PTHREADMUTEX=yes
-+ AC_MSG_RESULT(yes)
-+])
-+
-+if test "$PHP_APC_PTHREADMUTEX" != "no"; then
-+ orig_LIBS="$LIBS"
-+ LIBS="$LIBS -lpthread"
-+ AC_TRY_RUN(
-+ [
-+ #include <sys/types.h>
-+ #include <pthread.h>
-+ main() {
-+ pthread_mutex_t mutex;
-+ pthread_mutexattr_t attr;
-+
-+ if(pthread_mutexattr_init(&attr)) {
-+ puts("Unable to initialize pthread attributes (pthread_mutexattr_init).");
-+ return -1;
-+ }
-+ if(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
-+ puts("Unable to set PTHREAD_PROCESS_SHARED (pthread_mutexattr_setpshared), your system may not support shared mutex's.");
-+ return -1;
-+ }
-+ if(pthread_mutex_init(&mutex, &attr)) {
-+ puts("Unable to initialize the mutex (pthread_mutex_init).");
-+ return -1;
-+ }
-+ if(pthread_mutexattr_destroy(&attr)) {
-+ puts("Unable to destroy mutex attributes (pthread_mutexattr_destroy).");
-+ return -1;
-+ }
-+ if(pthread_mutex_destroy(&mutex)) {
-+ puts("Unable to destroy mutex (pthread_mutex_destroy).");
-+ return -1;
-+ }
-+
-+ puts("pthread mutexs are supported!");
-+ return 0;
-+ }
-+ ],
-+ [ dnl -Success-
-+ PHP_ADD_LIBRARY(pthread)
-+ ],
-+ [ dnl -Failure-
-+ AC_MSG_WARN([It doesn't appear that pthread mutexes are supported on your system])
-+ PHP_APC_PTHREADMUTEX=no
-+ ],
-+ [
-+ PHP_ADD_LIBRARY(pthread)
-+ ]
-+ )
-+ LIBS="$orig_LIBS"
-+fi
-+
-+AC_MSG_CHECKING(whether we should use pthread read/write locking)
-+AC_ARG_ENABLE(apc-pthreadrwlocks,
-+[ --enable-apc-pthreadrwlocks
-+ Enable pthread read/write locking ],
-+[
-+ PHP_APC_PTHREADRWLOCK=$enableval
-+ AC_MSG_RESULT($enableval)
-+],
-+[
-+ PHP_APC_PTHREADRWLOCK=no
-+ AC_MSG_RESULT(no)
-+])
-+
-+if test "$PHP_APC_PTHREADRWLOCK" != "no"; then
-+ orig_LIBS="$LIBS"
-+ LIBS="$LIBS -lpthread"
-+ AC_TRY_RUN(
-+ [
-+ #include <sys/types.h>
-+ #include <pthread.h>
-+ main() {
-+ pthread_rwlock_t rwlock;
-+ pthread_rwlockattr_t attr;
-+
-+ if(pthread_rwlockattr_init(&attr)) {
-+ puts("Unable to initialize pthread attributes (pthread_rwlockattr_init).");
-+ return -1;
-+ }
-+ if(pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
-+ puts("Unable to set PTHREAD_PROCESS_SHARED (pthread_rwlockattr_setpshared), your system may not support shared rwlock's.");
-+ return -1;
-+ }
-+ if(pthread_rwlock_init(&rwlock, &attr)) {
-+ puts("Unable to initialize the rwlock (pthread_rwlock_init).");
-+ return -1;
-+ }
-+ if(pthread_rwlockattr_destroy(&attr)) {
-+ puts("Unable to destroy rwlock attributes (pthread_rwlockattr_destroy).");
-+ return -1;
-+ }
-+ if(pthread_rwlock_destroy(&rwlock)) {
-+ puts("Unable to destroy rwlock (pthread_rwlock_destroy).");
-+ return -1;
-+ }
-+
-+ puts("pthread rwlocks are supported!");
-+ return 0;
-+ }
-+ ],
-+ [ dnl -Success-
-+ PHP_ADD_LIBRARY(pthread)
-+ APC_CFLAGS="-D_GNU_SOURCE"
-+ ],
-+ [ dnl -Failure-
-+ AC_MSG_WARN([It doesn't appear that pthread rwlocks are supported on your system])
-+ PHP_APC_PTHREADRWLOCK=no
-+ ],
-+ [
-+ PHP_ADD_LIBRARY(pthread)
-+ ]
-+ )
-+ LIBS="$orig_LIBS"
-+fi
-+
-+ AC_CACHE_CHECK([whether the target compiler supports builtin atomics], PHP_cv_APC_GCC_ATOMICS, [
-+
-+ AC_TRY_LINK([],[
-+ int foo = 0;
-+ __sync_fetch_and_add(&foo, 1);
-+ __sync_bool_compare_and_swap(&foo, 0, 1);
-+ return __sync_fetch_and_add(&foo, 1);
-+ ],
-+ [PHP_cv_APC_GCC_ATOMICS=yes],
-+ [PHP_cv_APC_GCC_ATOMICS=no])
-+ ])
-+
-+ if test "x${PHP_cv_APC_GCC_ATOMICS}" != "xno"; then
-+ AC_DEFINE(HAVE_ATOMIC_OPERATIONS, 1,
-+ [Define this if your target compiler supports builtin atomics])
-+ else
-+ if test "$PHP_APC_PTHREADRWLOCK" != "no"; then
-+ AC_MSG_WARN([Disabling pthread rwlocks, because of missing atomic operations])
-+ dnl - fall back would most likely be pthread mutexes
-+ PHP_APC_PTHREADRWLOCK=no
-+ fi
-+ fi
-+
-+AC_MSG_CHECKING(whether we should use spin locks)
-+AC_ARG_ENABLE(apc-spinlocks,
-+[ --enable-apc-spinlocks
-+ Enable spin locks EXPERIMENTAL ],
-+[
-+ PHP_APC_SPINLOCKS=$enableval
-+ AC_MSG_RESULT($enableval)
-+],
-+[
-+ PHP_APC_SPINLOCKS=no
-+ AC_MSG_RESULT(no)
-+])
-+
-+
-+AC_MSG_CHECKING(whether we should enable memory protection)
-+AC_ARG_ENABLE(apc-memprotect,
-+[ --enable-apc-memprotect
-+ Enable mmap/shm memory protection],
-+[
-+ PHP_APC_MEMPROTECT=$enableval
-+ AC_MSG_RESULT($enableval)
-+], [
-+ PHP_APC_MEMPROTECT=no
-+ AC_MSG_RESULT(no)
-+])
-+
-+if test "$PHP_APC" != "no"; then
-+ test "$PHP_APC_MMAP" != "no" && AC_DEFINE(APC_MMAP, 1, [ ])
-+ test "$PHP_APC_FILEHITS" != "no" && AC_DEFINE(APC_FILEHITS, 1, [ ])
-+
-+ if test "$PHP_APC_DEBUG" != "no"; then
-+ AC_DEFINE(__DEBUG_APC__, 1, [ ])
-+ fi
-+
-+ if test "$PHP_APC_SEM" != "no"; then
-+ AC_DEFINE(APC_SEM_LOCKS, 1, [ ])
-+ elif test "$PHP_APC_SPINLOCKS" != "no"; then
-+ AC_DEFINE(APC_SPIN_LOCKS, 1, [ ])
-+ elif test "$PHP_APC_PTHREADRWLOCK" != "no"; then
-+ AC_DEFINE(APC_PTHREADRW_LOCKS, 1, [ ])
-+ elif test "$PHP_APC_PTHREADMUTEX" != "no"; then
-+ AC_DEFINE(APC_PTHREADMUTEX_LOCKS, 1, [ ])
-+ else
-+ AC_DEFINE(APC_FCNTL_LOCKS, 1, [ ])
-+ fi
-+
-+ if test "$PHP_APC_MEMPROTECT" != "no"; then
-+ AC_DEFINE(APC_MEMPROTECT, 1, [ shm/mmap memory protection ])
-+ fi
-+
-+ AC_CACHE_CHECK(for zend_set_lookup_function_hook, php_cv_zend_set_lookup_function_hook,
-+ [
-+ orig_cflags=$CFLAGS
-+ CFLAGS="$INCLUDES $EXTRA_INCLUDES"
-+ AC_TRY_COMPILE([
-+#include "main/php.h"
-+#include "Zend/zend_API.h"
-+ ], [#ifndef zend_set_lookup_function_hook
-+ (void) zend_set_lookup_function_hook;
-+#endif], [
-+ php_cv_zend_set_lookup_function_hook=yes
-+ ],[
-+ php_cv_zend_set_lookup_function_hook=no
-+ ])
-+ CFLAGS=$orig_cflags
-+ ])
-+ if test "$php_cv_zend_set_lookup_function_hook" = "yes"; then
-+ AC_DEFINE(APC_HAVE_LOOKUP_HOOKS, 1, [ ])
-+ else
-+ AC_DEFINE(APC_HAVE_LOOKUP_HOOKS, 0, [ ])
-+ fi
-+
-+ AC_CHECK_FUNCS(sigaction)
-+ AC_CACHE_CHECK(for union semun, php_cv_semun,
-+ [
-+ AC_TRY_COMPILE([
-+#include <sys/types.h>
-+#include <sys/ipc.h>
-+#include <sys/sem.h>
-+ ], [union semun x; x.val=1], [
-+ php_cv_semun=yes
-+ ],[
-+ php_cv_semun=no
-+ ])
-+ ])
-+ if test "$php_cv_semun" = "yes"; then
-+ AC_DEFINE(HAVE_SEMUN, 1, [ ])
-+ else
-+ AC_DEFINE(HAVE_SEMUN, 0, [ ])
-+ fi
-+
-+ AC_MSG_CHECKING(whether we should enable valgrind support)
-+ AC_ARG_ENABLE(valgrind-checks,
-+ [ --disable-valgrind-checks
-+ Disable valgrind based memory checks],
-+ [
-+ PHP_APC_VALGRIND=$enableval
-+ AC_MSG_RESULT($enableval)
-+ ], [
-+ PHP_APC_VALGRIND=yes
-+ AC_MSG_RESULT(yes)
-+ AC_CHECK_HEADER(valgrind/memcheck.h,
-+ [AC_DEFINE([HAVE_VALGRIND_MEMCHECK_H],1, [enable valgrind memchecks])])
-+ ])
-+
-+ apc_sources="apc.c php_apc.c \
-+ apc_cache.c \
-+ apc_compile.c \
-+ apc_debug.c \
-+ apc_fcntl.c \
-+ apc_main.c \
-+ apc_mmap.c \
-+ apc_sem.c \
-+ apc_shm.c \
-+ apc_pthreadmutex.c \
-+ apc_pthreadrwlock.c \
-+ apc_spin.c \
-+ pgsql_s_lock.c \
-+ apc_sma.c \
-+ apc_stack.c \
-+ apc_zend.c \
-+ apc_rfc1867.c \
-+ apc_signal.c \
-+ apc_pool.c \
-+ apc_iterator.c \
-+ apc_bin.c \
-+ apc_string.c "
-+
-+ PHP_CHECK_LIBRARY(rt, shm_open, [PHP_ADD_LIBRARY(rt,,APC_SHARED_LIBADD)])
-+ PHP_NEW_EXTENSION(apc, $apc_sources, $ext_shared,, \\$(APC_CFLAGS))
-+ PHP_SUBST(APC_SHARED_LIBADD)
-+ PHP_SUBST(APC_CFLAGS)
-+ PHP_INSTALL_HEADERS(ext/apc, [apc_serializer.h])
-+ AC_DEFINE(HAVE_APC, 1, [ ])
-+fi
-+
-+PHP_ARG_ENABLE(coverage, whether to include code coverage symbols,
-+[ --enable-coverage DEVELOPERS ONLY!!], no, no)
-+
-+if test "$PHP_COVERAGE" = "yes"; then
-+
-+ if test "$GCC" != "yes"; then
-+ AC_MSG_ERROR([GCC is required for --enable-coverage])
-+ fi
-+
-+ dnl Check if ccache is being used
-+ case `$php_shtool path $CC` in
-+ *ccache*[)] gcc_ccache=yes;;
-+ *[)] gcc_ccache=no;;
-+ esac
-+
-+ if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
-+ AC_MSG_ERROR([ccache must be disabled when --enable-coverage option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
-+ fi
-+
-+ lcov_version_list="1.5 1.6 1.7 1.9"
-+
-+ AC_CHECK_PROG(LCOV, lcov, lcov)
-+ AC_CHECK_PROG(GENHTML, genhtml, genhtml)
-+ PHP_SUBST(LCOV)
-+ PHP_SUBST(GENHTML)
-+
-+ if test "$LCOV"; then
-+ AC_CACHE_CHECK([for lcov version], php_cv_lcov_version, [
-+ php_cv_lcov_version=invalid
-+ lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` #'
-+ for lcov_check_version in $lcov_version_list; do
-+ if test "$lcov_version" = "$lcov_check_version"; then
-+ php_cv_lcov_version="$lcov_check_version (ok)"
-+ fi
-+ done
-+ ])
-+ else
-+ lcov_msg="To enable code coverage reporting you must have one of the following LCOV versions installed: $lcov_version_list"
-+ AC_MSG_ERROR([$lcov_msg])
-+ fi
-+
-+ case $php_cv_lcov_version in
-+ ""|invalid[)]
-+ lcov_msg="You must have one of the following versions of LCOV: $lcov_version_list (found: $lcov_version)."
-+ AC_MSG_ERROR([$lcov_msg])
-+ LCOV="exit 0;"
-+ ;;
-+ esac
-+
-+ if test -z "$GENHTML"; then
-+ AC_MSG_ERROR([Could not find genhtml from the LCOV package])
-+ fi
-+
-+ PHP_ADD_MAKEFILE_FRAGMENT
-+
-+ dnl Remove all optimization flags from CFLAGS
-+ changequote({,})
-+ CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9s]*//g'`
-+ CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-O[0-9s]*//g'`
-+ changequote([,])
-+
-+ dnl Add the special gcc flags
-+ CFLAGS="$CFLAGS -O0 -ggdb -fprofile-arcs -ftest-coverage"
-+ CXXFLAGS="$CXXFLAGS -ggdb -O0 -fprofile-arcs -ftest-coverage"
-+fi
-+dnl vim: set ts=2
-diff -Naur a/ext/apc/config.w32 b/ext/apc/config.w32
---- a/ext/apc/config.w32 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/config.w32 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,60 @@
-+// $Id: config.w32 309203 2011-03-14 06:47:16Z pajoye $
-+// vim:ft=javascript
-+
-+ARG_ENABLE('apc', 'Whether to enable APC support', 'no');
-+ARG_ENABLE('apc-debug', 'Whether to enable APC debugging', 'no');
-+ARG_ENABLE('apc-filehits', 'Whether to enable cache request file info', 'no');
-+ARG_ENABLE('apc-spinlocks', 'Whether to use spin locks (experimental)', 'no');
-+ARG_ENABLE('apc-memprotect', 'Whether to enable memory protection (experimental)', 'no');
-+ARG_ENABLE('apc-srwlock-native', 'Whether to use SRWLOCK locks native (win7/2008 only)', 'no');
-+ARG_ENABLE('apc-srwlock-kernel', 'Whether to use SRWLOCK locks (loaded at runtime)', 'no');
-+
-+if(PHP_APC != 'no')
-+{
-+ var apc_sources = 'apc.c php_apc.c apc_cache.c apc_compile.c apc_debug.c ' +
-+ 'apc_fcntl_win32.c apc_iterator.c apc_main.c apc_shm.c ' +
-+ 'apc_sma.c apc_stack.c apc_rfc1867.c apc_zend.c apc_pool.c ' +
-+ 'apc_bin.c apc_string.c';
-+
-+ if(PHP_APC_DEBUG != 'no')
-+ {
-+ ADD_FLAG('CFLAGS_APC', '/D __DEBUG_APC__=1');
-+ }
-+
-+ if(PHP_APC_FILEHITS != 'no')
-+ {
-+ AC_DEFINE('APC_FILEHITS', 1);
-+ }
-+
-+ if(PHP_APC_MEMPROTECT != 'no')
-+ {
-+ AC_DEFINE('APC_MEMPROTECT', 1);
-+ }
-+
-+ if(PHP_APC_SRWLOCK_NATIVE != 'no') {
-+ AC_DEFINE('APC_SRWLOCK_NATIVE', 1);
-+ } else {
-+ if(PHP_APC_SRWLOCK_KERNEL != 'no') {
-+ AC_DEFINE('APC_SRWLOCK_KERNEL', 1);
-+ ADD_FLAG('CFLAGS_APC', '/D WIN32_ONLY_COMPILER=1');
-+
-+ apc_sources += ' apc_windows_srwlock_kernel.c';
-+ } else {
-+ if(PHP_APC_SPINLOCKS != 'no') {
-+ AC_DEFINE('APC_SPIN_LOCKS', 1);
-+ ADD_FLAG('CFLAGS_APC', '/D WIN32_ONLY_COMPILER=1');
-+
-+ apc_sources += ' apc_spin.c pgsql_s_lock.c';
-+ } else {
-+ AC_DEFINE('APC_FCNTL_LOCKS', 1);
-+ }
-+ }
-+ }
-+
-+ AC_DEFINE('HAVE_APC', 1);
-+ AC_DEFINE('HAVE_ATOMIC_OPERATIONS', 1);
-+
-+ PHP_INSTALL_HEADERS("ext/apc", "apc_serializer.h");
-+
-+ EXTENSION('apc', apc_sources);
-+}
-diff -Naur a/ext/apc/INSTALL b/ext/apc/INSTALL
---- a/ext/apc/INSTALL 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/INSTALL 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,407 @@
-+Installation Instructions for APC
-+---------------------------------
-+
-+This version of APC should work on PHP 4.3.0 - 4.4.x and
-+5.1.0 - 5.2.x. Yes, that means PHP 5.0.x is no longer
-+supported. Upgrade to PHP 5.1.x or 5.2.x and you will
-+notice all sorts of performance increases.
-+
-+CVS Instructions
-+----------------
-+Building from CVS can be done like this:
-+
-+ svn co http://svn.php.net/repository/pecl/apc/trunk apc
-+ cd apc
-+ phpize
-+ ./configure --with-php-config=/usr/local/php/bin/php-config
-+ make
-+ export TEST_PHP_ARGS='-n'
-+ make test
-+ make install
-+
-+Suggested Configuration (in your php.ini file)
-+----------------------------------------------
-+ extension=apc.so
-+ apc.enabled=1
-+ apc.shm_size=128M
-+ apc.ttl=7200
-+ apc.user_ttl=7200
-+ apc.enable_cli=1
-+
-+These are fully described at the bottom of this file.
-+
-++---------------------+
-+| QUICK INSTALL (DSO) |
-++---------------------+
-+
-+These instructions assume your PHP installation is located in /usr/local/php and you
-+want Apache optimizations (--with-apxs).
-+
-+$ gunzip -c apc_x.y.tar.gz | tar xf -
-+$ cd apc_x.y
-+$ /usr/local/php/bin/phpize
-+$ ./configure --with-php-config=/usr/local/php/bin/php-config
-+$ make
-+$ make install
-+
-+You will probably need to run the final command (make install) as root.
-+
-+The above sequence of commands will install a .so file in your PHP
-+installation extension directory. The output of make install should display
-+that path to the screen.
-+
-+Next you must edit your php.ini file, which is normally located in
-+/usr/local/php/lib/php.ini, and add the following line:
-+
-+ extension="apc.so"
-+
-+Replace "/path/to/php/extensions" with whatever path was displayed when you
-+ran make install above.
-+
-+Then restart your web server and consult the output of phpinfo(). If there is
-+an informational section for APC, the installation was successful.
-+
-++------------------------+
-+| QUICK INSTALL (Static) |
-++------------------------+
-+
-+APC will not successfully compile on all systems as a DSO. If you run into
-+problems using the DSO quick install, you can try to compile it statically
-+into PHP. (The DSO install is recommended, though.)
-+
-+These instructions assume the current directory is the root of the PHP source
-+tree, and that you have already configured PHP by running its bundled
-+configure script.
-+
-+$ cd ext
-+$ gunzip -c apc_x.y.tar.gz | tar xf -
-+$ cd ..
-+$ ./buildconf
-+$ ./config.nice
-+$ make
-+$ make install
-+
-+Once this is complete, simply restart your web server. You do not need to
-+modify your php.ini file to enable APC.
-+
-++-----------------+
-+| VERBOSE INSTALL |
-++-----------------+
-+
-+These instructions assume your PHP installation is located in /usr/local/php.
-+
-+1. Unpack your distribution file.
-+
-+ You will have downloaded a file named something like apc_x.y.tar.gz.
-+ Unzip this file with a command like
-+
-+ gunzip apc_x.y.tar.gz
-+
-+ Next you have to untar it with
-+
-+ tar xvf apc_x.y.tar
-+
-+ This will create an apc_x.y directory. cd into this new directory:
-+
-+ cd apc_x.y
-+
-+2. Run phpize.
-+
-+ phpize is a script that should have been installed with PHP, and is
-+ normally located in /usr/local/php/bin assuming you installed PHP in
-+ /usr/local/php. (If you do not have the phpize script, you must reinstall
-+ PHP and be sure not to disable PEAR.)
-+
-+ Run the phpize command:
-+
-+ /usr/local/php/bin/phpize
-+
-+ Its output should resemble this:
-+
-+ autoheader: `config.h.in' is created
-+ You should update your `aclocal.m4' by running aclocal.
-+ Configuring for:
-+ PHP Api Version: 20020918
-+ Zend Module Api No: 20020429
-+ Zend Extension Api No: 20021010
-+
-+ phpize should create a configure script in the current directory. If you
-+ get errors instead, you might be missing some required development tools,
-+ such as autoconf or libtool. You can try downloading the latest versions
-+ of those tools and running phpize again.
-+
-+3. Run the configure script.
-+
-+ phpize creates a configure script. The only option you need to specify is
-+ the location of your php-config script:
-+
-+ ./configure --enable-apc
-+
-+ php-config should be located in the same directory as phpize.
-+
-+ If you prefer to use mmap instead of the default IPC shared memory support,
-+ add --enable-apc-mmap to your configure line.
-+
-+ If you prefer to use sysv IPC semaphores over the safer fcntl() locks, add
-+ --enable-sem to your configure line. If you don't have a problem
-+ with your server segaulting, or any other unnatural accumulation of
-+ semaphores on your system, the semaphore based locking is slightly faster.
-+
-+4. Compile and install the files. Simply type: make install
-+
-+ (You may need to be root in order to install)
-+
-+ If you encounter errors from libtool or gcc during this step, please
-+ contact the project maintainer (dcowgill@php.net).
-+
-+5. Edit your php.ini
-+
-+ make install should have printed a line resembling the following:
-+
-+ Installing shared extensions: /path/to/extension/
-+
-+ Copy the path /path/to/extension/ and add the following line to your
-+ php.ini file (normally located in /usr/local/php/lib/php.ini):
-+
-+ extension="apc.so"
-+
-+ If you don't have a php.ini file in that location, you can create it now.
-+
-+6. Restart the web server and test the installation.
-+
-+ Restart your web server now (for apache, it's apachectl restart) and
-+ create a small test PHP file in your document root. The file should
-+ contain just the following line:
-+
-+ <?php phpinfo() ?>
-+
-+ Request that file in a web browser. If there is an entry for APC in the
-+ list of installed modules, the installation was successful.
-+
-+ If APC is not listed, consult your web server error log. If it contains an
-+ error message saying that it can't load the APC extension, your system
-+ might not be able to load shared libraries created with PHP's build
-+ system. One alternative would be to compile APC statically into PHP. See
-+ the Quick Install (Static) instructions above.
-+
-+ You should consult your error log anyway to see if APC generated any
-+ errors. On BSD-based platforms, it is typical for APC to be unable to
-+ allocate the default-sized shared memory segment. See below for hints on
-+ raising your system's shared memory limitations.
-+
-++-----------------+
-+| CONFIGURING APC |
-++-----------------+
-+
-+Although the default APC settings are fine for many installations, serious
-+users should consider tuning the following parameters:
-+
-+ OPTION DESCRIPTION
-+ ------------------ --------------------------------------------------
-+ apc.enabled This can be set to 0 to disable APC. This is
-+ primarily useful when APC is statically compiled
-+ into PHP, since there is no other way to disable
-+ it (when compiled as a DSO, the zend_extension
-+ line can just be commented-out).
-+ (Default: 1)
-+
-+ apc.shm_segments The number of shared memory segments to allocate
-+ for the compiler cache. If APC is running out of
-+ shared memory but you have already set
-+ apc.shm_size as high as your system allows, you
-+ can try raising this value. Setting this to a
-+ value other than 1 has no effect in mmap mode
-+ since mmap'ed shm segments don't have size limits.
-+ (Default: 1)
-+
-+ apc.shm_size The size of each shared memory segment in MB.
-+ By default, some systems (including most BSD
-+ variants) have very low limits on the size of a
-+ shared memory segment. M/G suffixes must be used.
-+ (Default: 30)
-+
-+
-+ apc.optimization This option has been deprecated.
-+ (Default: 0)
-+
-+ apc.num_files_hint A "hint" about the number of distinct source files
-+ that will be included or requested on your web
-+ server. Set to zero or omit if you're not sure;
-+ this setting is mainly useful for sites that have
-+ many thousands of source files.
-+ (Default: 1000)
-+
-+ apc.user_entries_hint Just like num_files_hint, a "hint" about the number
-+ of distinct user cache variables to store.
-+ Set to zero or omit if you're not sure;
-+ (Default: 4096)
-+
-+ apc.ttl The number of seconds a cache entry is allowed to
-+ idle in a slot in case this cache entry slot is
-+ needed by another entry. Leaving this at zero
-+ means that your cache could potentially fill up
-+ with stale entries while newer entries won't be
-+ cached.
-+ (Default: 0)
-+
-+ apc.user_ttl The number of seconds a user cache entry is allowed
-+ to idle in a slot in case this cache entry slot is
-+ needed by another entry. Leaving this at zero
-+ means that your cache could potentially fill up
-+ with stale entries while newer entries won't be
-+ cached.
-+ (Default: 0)
-+
-+
-+ apc.gc_ttl The number of seconds that a cache entry may
-+ remain on the garbage-collection list. This value
-+ provides a failsafe in the event that a server
-+ process dies while executing a cached source file;
-+ if that source file is modified, the memory
-+ allocated for the old version will not be
-+ reclaimed until this TTL reached. Set to zero to
-+ disable this feature.
-+ (Default: 3600)
-+
-+ apc.cache_by_default On by default, but can be set to off and used in
-+ conjunction with positive apc.filters so that files
-+ are only cached if matched by a positive filter.
-+ (Default: On)
-+
-+ apc.filters A comma-separated list of POSIX extended regular
-+ expressions. If any pattern matches the source
-+ filename, the file will not be cached. Note that
-+ the filename used for matching is the one passed
-+ to include/require, not the absolute path. If the
-+ first character of the expression is a + then the
-+ expression will be additive in the sense that any
-+ files matched by the expression will be cached, and
-+ if the first character is a - then anything matched
-+ will not be cached. The - case is the default, so
-+ it can be left off.
-+ (Default: "")
-+
-+ apc.mmap_file_mask If compiled with MMAP support by using --enable-mmap
-+ this is the mktemp-style file_mask to pass to the
-+ mmap module for determing whether your mmap'ed memory
-+ region is going to be file-backed or shared memory
-+ backed. For straight file-backed mmap, set it to
-+ something like /tmp/apc.XXXXXX (exactly 6 X's).
-+ To use POSIX-style shm_open/mmap put a ".shm"
-+ somewhere in your mask. eg. "/apc.shm.XXXXXX"
-+ You can also set it to "/dev/zero" to use your
-+ kernel's /dev/zero interface to anonymous mmap'ed
-+ memory. Leaving it undefined will force an
-+ anonymous mmap.
-+ (Default: "")
-+
-+ apc.slam_defense ** DEPRECATED - Use apc.write_lock instead **
-+ On very busy servers whenever you start the server or
-+ modify files you can create a race of many processes
-+ all trying to cache the same file at the same time.
-+ This option sets the percentage of processes that will
-+ skip trying to cache an uncached file. Or think of it
-+ as the probability of a single process to skip caching.
-+ For example, setting this to 75 would mean that there is
-+ a 75% chance that the process will not cache an uncached
-+ file. So the higher the setting the greater the defense
-+ against cache slams. Setting this to 0 disables this
-+ feature.
-+ (Default: 0)
-+
-+ apc.file_update_protection
-+ When you modify a file on a live web server you really
-+ should do so in an atomic manner. That is, write to a
-+ temporary file and rename (mv) the file into its permanent
-+ position when it is ready. Many text editors, cp, tar and
-+ other such programs don't do this. This means that there
-+ is a chance that a file is accessed (and cached) while it
-+ is still being written to. This file_update_protection
-+ setting puts a delay on caching brand new files. The
-+ default is 2 seconds which means that if the modification
-+ timestamp (mtime) on a file shows that it is less than 2
-+ seconds old when it is accessed, it will not be cached.
-+ The unfortunate person who accessed this half-written file
-+ will still see weirdness, but at least it won't persist.
-+ If you are certain you always atomically update your files
-+ by using something like rsync which does this correctly, you
-+ can turn this protection off by setting it to 0. If you
-+ have a system that is flooded with io causing some update
-+ procedure to take longer than 2 seconds, you may want to
-+ increase this a bit.
-+ (Default: 2)
-+
-+ apc.enable_cli Mostly for testing and debugging. Setting this enables APC
-+ for the CLI version of PHP. Normally you wouldn't want to
-+ create, populate and tear down the APC cache on every CLI
-+ request, but for various test scenarios it is handy to be
-+ able to enable APC for the CLI version of APC easily.
-+ (Default: 0)
-+
-+ apc.max_file_size Prevents large files from being cached.
-+ (Default: 1M)
-+
-+ apc.stat Whether to stat the main script file and the fullpath
-+ includes. If you turn this off you will need to restart
-+ your server in order to update scripts.
-+ (Default: 1)
-+
-+ apc.canonicalize Whether to canonicalize paths in stat=0 mode or
-+ fall back to stat behaviour if set to 0
-+ (Default: 0)
-+
-+ apc.write_lock On busy servers when you first start up the server, or when
-+ many files are modified, you can end up with all your processes
-+ trying to compile and cache the same files. With write_lock
-+ enabled, only one process at a time will try to compile an
-+ uncached script while the other processes will run uncached
-+ instead of sitting around waiting on a lock.
-+ (Default: 1)
-+
-+ apc.report_autofilter Logs any scripts that were automatically excluded from being
-+ cached due to early/late binding issues.
-+ (Default: 0)
-+
-+ apc.rfc1867 RFC1867 File Upload Progress hook handler is only available
-+ if you compiled APC against PHP 5.2.0 or later. When enabled
-+ any file uploads which includes a field called
-+ APC_UPLOAD_PROGRESS before the file field in an upload form
-+ will cause APC to automatically create an upload_<key>
-+ user cache entry where <key> is the value of the
-+ APC_UPLOAD_PROGRESS form entry.
-+
-+ Note that the file upload tracking is not threadsafe at this
-+ point, so new uploads that happen while a previous one is
-+ still going will disable the tracking for the previous.
-+ (Default: 0)
-+
-+ apc.rfc1867_prefix Key prefix to use for the user cache entry generated by
-+ rfc1867 upload progress functionality.
-+ (Default: "upload_")
-+
-+ apc.rfc1867_name Specify the hidden form entry name that activates APC upload
-+ progress and specifies the user cache key suffix.
-+ (Default: "APC_UPLOAD_PROGRESS")
-+
-+ apc.rfc1867_freq The frequency that updates should be made to the user cache
-+ entry for upload progress. This can take the form of a
-+ percentage of the total file size or a size in bytes
-+ optionally suffixed with 'k', 'm', or 'g' for kilobytes,
-+ megabytes, or gigabytes respectively (case insensitive).
-+ A setting of 0 updates as often as possible, which may cause
-+ slower uploads.
-+ (Default: 0)
-+
-+ apc.localcache ** REMOVED
-+ apc.localcache.size ** REMOVED
-+
-+ apc.include_once_override
-+ Optimize include_once and require_once calls and avoid the
-+ expensive system calls used.
-+ (Default: 0)
-+
-+ apc.serializer
-+ Defines which serializer should be used. Default is the
-+ standard PHP serializer. Other can be used without having
-+ to re compile apc, like igbinary for example.
-+ (apc.serializer=igbinary)
-diff -Naur a/ext/apc/LICENSE b/ext/apc/LICENSE
---- a/ext/apc/LICENSE 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/LICENSE 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,68 @@
-+--------------------------------------------------------------------
-+ The PHP License, version 3.01
-+Copyright (c) 1999 - 2011 The PHP Group. All rights reserved.
-+--------------------------------------------------------------------
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, is permitted provided that the following conditions
-+are met:
-+
-+ 1. Redistributions of source code must retain the above copyright
-+ notice, this list of conditions and the following disclaimer.
-+
-+ 2. Redistributions in binary form must reproduce the above copyright
-+ notice, this list of conditions and the following disclaimer in
-+ the documentation and/or other materials provided with the
-+ distribution.
-+
-+ 3. The name "PHP" must not be used to endorse or promote products
-+ derived from this software without prior written permission. For
-+ written permission, please contact group@php.net.
-+
-+ 4. Products derived from this software may not be called "PHP", nor
-+ may "PHP" appear in their name, without prior written permission
-+ from group@php.net. You may indicate that your software works in
-+ conjunction with PHP by saying "Foo for PHP" instead of calling
-+ it "PHP Foo" or "phpfoo"
-+
-+ 5. The PHP Group may publish revised and/or new versions of the
-+ license from time to time. Each version will be given a
-+ distinguishing version number.
-+ Once covered code has been published under a particular version
-+ of the license, you may always continue to use it under the terms
-+ of that version. You may also choose to use such covered code
-+ under the terms of any subsequent version of the license
-+ published by the PHP Group. No one other than the PHP Group has
-+ the right to modify the terms applicable to covered code created
-+ under this License.
-+
-+ 6. Redistributions of any form whatsoever must retain the following
-+ acknowledgment:
-+ "This product includes PHP software, freely available from
-+ <http://www.php.net/software/>".
-+
-+THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
-+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
-+DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+OF THE POSSIBILITY OF SUCH DAMAGE.
-+
-+--------------------------------------------------------------------
-+
-+This software consists of voluntary contributions made by many
-+individuals on behalf of the PHP Group.
-+
-+The PHP Group can be contacted via Email at group@php.net.
-+
-+For more information on the PHP Group and the PHP project,
-+please see <http://www.php.net>.
-+
-+PHP includes the Zend Engine, freely available at
-+<http://www.zend.com>.
-diff -Naur a/ext/apc/NOTICE b/ext/apc/NOTICE
---- a/ext/apc/NOTICE 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/NOTICE 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,43 @@
-+This is the NOTICE file that holds acknowledgements and stuff.
-+
-+The Alternative PHP Cache (APC) is a free and open opcode cache for PHP.
-+This extension is being released under the PHP License for complete compliance
-+with PHP and to encourage wide-spread use. It is our intention that this
-+project be kept open source and that all commercial spin-offs contribute their
-+modifications back into the public source-tree.
-+
-+Creators:
-+ Daniel Cowgill
-+ George Schlossnagle
-+
-+PHP5 support and major features by:
-+ Arun C. Murthy
-+ Gopal Vijayaraghavan
-+ Rasmus Lerdorf
-+
-+This software was contributed to PHP by Community Connect Inc. in 2002
-+and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+Future revisions and derivatives of this source code must acknowledge
-+Community Connect Inc. as the original contributor of this module by
-+leaving this note intact in the source code.
-+
-+All other licensing and usage conditions are those of the PHP Group.
-+
-+We would like to thank Community Connect Inc. and Yahoo! Inc. for supporting
-+this project and providing a challenging and stimulating environment in
-+which exciting projects can happen.
-+
-+Contributors:
-+ Mike Bretz bug fixes, GUI, and lots of work
-+ Ricardo Galli changed read-write locks to prefer readers
-+ Yann Grossel bug fixes
-+ Thies Arntzen bug fixes
-+ Sara Golemon optimizer work
-+
-+Special Thanks:
-+ Florian Baumert help debugging phplib problems
-+ Thomas Duffey help debugging inheritance issues
-+ Vibol Hou help debugging phplib problems
-+ Angel Li diffs for ANSI comment compliance
-+ Christian Rishøj help debugging phplib problems
-+ Sascha Schumann memory error bug fix
-diff -Naur a/ext/apc/pgsql_s_lock.c b/ext/apc/pgsql_s_lock.c
---- a/ext/apc/pgsql_s_lock.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/pgsql_s_lock.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,391 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | The following code was ported from the PostgreSQL project, please |
-+ | see appropriate copyright notices that follow. |
-+ | Initial conversion by Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: pgsql_s_lock.c 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+/*-------------------------------------------------------------------------
-+ *
-+ * s_lock.c
-+ * Hardware-dependent implementation of spinlocks.
-+ *
-+ *
-+ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
-+ * Portions Copyright (c) 1994, Regents of the University of California
-+ *
-+ *
-+ * IDENTIFICATION
-+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.47 2006/10/04 00:29:58 momjian Exp $
-+ *
-+ *-------------------------------------------------------------------------
-+ */
-+/* #include "postgres.h" -- Removed for APC */
-+
-+/* -- Added for APC -- */
-+#include "apc.h"
-+#ifdef APC_SPIN_LOCKS
-+
-+#ifdef S_LOCK_TEST
-+#include <stdio.h>
-+#endif
-+#ifndef WIN32
-+#include <sys/select.h>
-+#endif
-+/* ---- */
-+
-+#include <time.h>
-+#ifdef WIN32
-+#include "win32/unistd.h"
-+#else
-+#include <unistd.h>
-+#endif
-+
-+/* #include "storage/s_lock.h" -- Removed for APC */
-+#include "pgsql_s_lock.h"
-+
-+static int spins_per_delay = DEFAULT_SPINS_PER_DELAY;
-+
-+
-+/* -- APC specific additions ------------------------------*/
-+/* The following dependencies have been copied from
-+ * other pgsql source files. The original locations
-+ * have been noted.
-+ */
-+
-+/* -- from include/c.h -- */
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
-+
-+/* -- from include/pg_config_manual.h -- */
-+#define MAX_RANDOM_VALUE (0x7FFFFFFF)
-+
-+/*
-+ * Max
-+ * Return the maximum of two numbers.
-+ */
-+#define Max(x, y) ((x) > (y) ? (x) : (y))
-+
-+/* -- from include/c.h -- */
-+/*
-+ * Min
-+ * Return the minimum of two numbers.
-+ */
-+#define Min(x, y) ((x) < (y) ? (x) : (y))
-+
-+
-+/* -- from backend/port/win32/signal.c -- */
-+/*
-+ * pg_usleep --- delay the specified number of microseconds.
-+ *
-+ * NOTE: although the delay is specified in microseconds, the effective
-+ * resolution is only 1/HZ, or 10 milliseconds, on most Unixen. Expect
-+ * the requested delay to be rounded up to the next resolution boundary.
-+ *
-+ * On machines where "long" is 32 bits, the maximum delay is ~2000 seconds.
-+ */
-+void
-+pg_usleep(long microsec)
-+{
-+ if (microsec > 0)
-+ {
-+#ifndef WIN32
-+ struct timeval delay;
-+
-+ delay.tv_sec = microsec / 1000000L;
-+ delay.tv_usec = microsec % 1000000L;
-+ (void) select(0, NULL, NULL, NULL, &delay);
-+#else
-+ SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
-+#endif
-+ }
-+}
-+
-+/* -- End APC specific additions ------------------------------*/
-+
-+
-+/*
-+ * s_lock_stuck() - complain about a stuck spinlock
-+ */
-+static void
-+s_lock_stuck(volatile slock_t *lock, const char *file, int line TSRMLS_DC)
-+{
-+#if defined(S_LOCK_TEST)
-+ fprintf(stderr,
-+ "\nStuck spinlock (%p) detected at %s:%d.\n",
-+ lock, file, line);
-+ exit(1);
-+#else
-+ /* -- Removed for APC
-+ elog(PANIC, "stuck spinlock (%p) detected at %s:%d",
-+ lock, file, line);
-+ */
-+ apc_error("Stuck spinlock (%p) detected" TSRMLS_CC, lock);
-+#endif
-+}
-+
-+
-+/*
-+ * s_lock(lock) - platform-independent portion of waiting for a spinlock.
-+ */
-+void
-+s_lock(volatile slock_t *lock, const char *file, int line TSRMLS_DC)
-+{
-+ /*
-+ * We loop tightly for awhile, then delay using pg_usleep() and try again.
-+ * Preferably, "awhile" should be a small multiple of the maximum time we
-+ * expect a spinlock to be held. 100 iterations seems about right as an
-+ * initial guess. However, on a uniprocessor the loop is a waste of
-+ * cycles, while in a multi-CPU scenario it's usually better to spin a bit
-+ * longer than to call the kernel, so we try to adapt the spin loop count
-+ * depending on whether we seem to be in a uniprocessor or multiprocessor.
-+ *
-+ * Note: you might think MIN_SPINS_PER_DELAY should be just 1, but you'd
-+ * be wrong; there are platforms where that can result in a "stuck
-+ * spinlock" failure. This has been seen particularly on Alphas; it seems
-+ * that the first TAS after returning from kernel space will always fail
-+ * on that hardware.
-+ *
-+ * Once we do decide to block, we use randomly increasing pg_usleep()
-+ * delays. The first delay is 1 msec, then the delay randomly increases to
-+ * about one second, after which we reset to 1 msec and start again. The
-+ * idea here is that in the presence of heavy contention we need to
-+ * increase the delay, else the spinlock holder may never get to run and
-+ * release the lock. (Consider situation where spinlock holder has been
-+ * nice'd down in priority by the scheduler --- it will not get scheduled
-+ * until all would-be acquirers are sleeping, so if we always use a 1-msec
-+ * sleep, there is a real possibility of starvation.) But we can't just
-+ * clamp the delay to an upper bound, else it would take a long time to
-+ * make a reasonable number of tries.
-+ *
-+ * We time out and declare error after NUM_DELAYS delays (thus, exactly
-+ * that many tries). With the given settings, this will usually take 2 or
-+ * so minutes. It seems better to fix the total number of tries (and thus
-+ * the probability of unintended failure) than to fix the total time
-+ * spent.
-+ *
-+ * The pg_usleep() delays are measured in milliseconds because 1 msec is a
-+ * common resolution limit at the OS level for newer platforms. On older
-+ * platforms the resolution limit is usually 10 msec, in which case the
-+ * total delay before timeout will be a bit more.
-+ */
-+#define MIN_SPINS_PER_DELAY 10
-+#define MAX_SPINS_PER_DELAY 1000
-+#define NUM_DELAYS 1000
-+#define MIN_DELAY_MSEC 1
-+#define MAX_DELAY_MSEC 1000
-+
-+ int spins = 0;
-+ int delays = 0;
-+ int cur_delay = 0;
-+
-+ while (TAS(lock))
-+ {
-+ /* CPU-specific delay each time through the loop */
-+ SPIN_DELAY();
-+
-+ /* Block the process every spins_per_delay tries */
-+ if (++spins >= spins_per_delay)
-+ {
-+ if (++delays > NUM_DELAYS)
-+ s_lock_stuck(lock, file, line TSRMLS_CC);
-+
-+ if (cur_delay == 0) /* first time to delay? */
-+ cur_delay = MIN_DELAY_MSEC;
-+
-+ pg_usleep(cur_delay * 1000L);
-+
-+#if defined(S_LOCK_TEST)
-+ fprintf(stdout, "*");
-+ fflush(stdout);
-+#endif
-+
-+ /* increase delay by a random fraction between 1X and 2X */
-+ cur_delay += (int) (cur_delay *
-+ ((double) rand() / (double) MAX_RANDOM_VALUE) + 0.5);
-+ /* wrap back to minimum delay when max is exceeded */
-+ if (cur_delay > MAX_DELAY_MSEC)
-+ cur_delay = MIN_DELAY_MSEC;
-+
-+ spins = 0;
-+ }
-+ }
-+
-+ /*
-+ * If we were able to acquire the lock without delaying, it's a good
-+ * indication we are in a multiprocessor. If we had to delay, it's a sign
-+ * (but not a sure thing) that we are in a uniprocessor. Hence, we
-+ * decrement spins_per_delay slowly when we had to delay, and increase it
-+ * rapidly when we didn't. It's expected that spins_per_delay will
-+ * converge to the minimum value on a uniprocessor and to the maximum
-+ * value on a multiprocessor.
-+ *
-+ * Note: spins_per_delay is local within our current process. We want to
-+ * average these observations across multiple backends, since it's
-+ * relatively rare for this function to even get entered, and so a single
-+ * backend might not live long enough to converge on a good value. That
-+ * is handled by the two routines below.
-+ */
-+ if (cur_delay == 0)
-+ {
-+ /* we never had to delay */
-+ if (spins_per_delay < MAX_SPINS_PER_DELAY)
-+ spins_per_delay = Min(spins_per_delay + 100, MAX_SPINS_PER_DELAY);
-+ }
-+ else
-+ {
-+ if (spins_per_delay > MIN_SPINS_PER_DELAY)
-+ spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY);
-+ }
-+}
-+
-+
-+#if 0 /* -- APC doesn't use the set_spins_per_delay or update_spins_per_delay -- */
-+/*
-+ * Set local copy of spins_per_delay during backend startup.
-+ *
-+ * NB: this has to be pretty fast as it is called while holding a spinlock
-+ */
-+void
-+set_spins_per_delay(int shared_spins_per_delay)
-+{
-+ spins_per_delay = shared_spins_per_delay;
-+}
-+
-+/*
-+ * Update shared estimate of spins_per_delay during backend exit.
-+ *
-+ * NB: this has to be pretty fast as it is called while holding a spinlock
-+ */
-+int
-+update_spins_per_delay(int shared_spins_per_delay)
-+{
-+ /*
-+ * We use an exponential moving average with a relatively slow adaption
-+ * rate, so that noise in any one backend's result won't affect the shared
-+ * value too much. As long as both inputs are within the allowed range,
-+ * the result must be too, so we need not worry about clamping the result.
-+ *
-+ * We deliberately truncate rather than rounding; this is so that single
-+ * adjustments inside a backend can affect the shared estimate (see the
-+ * asymmetric adjustment rules above).
-+ */
-+ return (shared_spins_per_delay * 15 + spins_per_delay) / 16;
-+}
-+#endif
-+
-+/*
-+ * Various TAS implementations that cannot live in s_lock.h as no inline
-+ * definition exists (yet).
-+ * In the future, get rid of tas.[cso] and fold it into this file.
-+ *
-+ * If you change something here, you will likely need to modify s_lock.h too,
-+ * because the definitions for these are split between this file and s_lock.h.
-+ */
-+
-+
-+#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
-+
-+
-+#if defined(__GNUC__)
-+
-+/*
-+ * All the gcc flavors that are not inlined
-+ */
-+
-+
-+/*
-+ * Note: all the if-tests here probably ought to be testing gcc version
-+ * rather than platform, but I don't have adequate info to know what to
-+ * write. Ideally we'd flush all this in favor of the inline version.
-+ */
-+#if defined(__m68k__) && !defined(__linux__)
-+/* really means: extern int tas(slock_t* **lock); */
-+static void
-+tas_dummy()
-+{
-+ __asm__ __volatile__(
-+#if defined(__NetBSD__) && defined(__ELF__)
-+/* no underscore for label and % for registers */
-+ "\
-+.global tas \n\
-+tas: \n\
-+ movel %sp@(0x4),%a0 \n\
-+ tas %a0@ \n\
-+ beq _success \n\
-+ moveq #-128,%d0 \n\
-+ rts \n\
-+_success: \n\
-+ moveq #0,%d0 \n\
-+ rts \n"
-+#else
-+ "\
-+.global _tas \n\
-+_tas: \n\
-+ movel sp@(0x4),a0 \n\
-+ tas a0@ \n\
-+ beq _success \n\
-+ moveq #-128,d0 \n\
-+ rts \n\
-+_success: \n\
-+ moveq #0,d0 \n\
-+ rts \n"
-+#endif /* __NetBSD__ && __ELF__ */
-+ );
-+}
-+#endif /* __m68k__ && !__linux__ */
-+#else /* not __GNUC__ */
-+
-+/*
-+ * All non gcc
-+ */
-+
-+
-+#if defined(sun3)
-+static void
-+tas_dummy() /* really means: extern int tas(slock_t
-+ * *lock); */
-+{
-+ asm("LLA0:");
-+ asm(" .data");
-+ asm(" .text");
-+ asm("|#PROC# 04");
-+ asm(" .globl _tas");
-+ asm("_tas:");
-+ asm("|#PROLOGUE# 1");
-+ asm(" movel sp@(0x4),a0");
-+ asm(" tas a0@");
-+ asm(" beq LLA1");
-+ asm(" moveq #-128,d0");
-+ asm(" rts");
-+ asm("LLA1:");
-+ asm(" moveq #0,d0");
-+ asm(" rts");
-+ asm(" .data");
-+}
-+#endif /* sun3 */
-+#endif /* not __GNUC__ */
-+#endif /* HAVE_SPINLOCKS */
-+
-+#endif /* APC_SPIN_LOCKS */
-diff -Naur a/ext/apc/pgsql_s_lock.h b/ext/apc/pgsql_s_lock.h
---- a/ext/apc/pgsql_s_lock.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/pgsql_s_lock.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,928 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | The following code was ported from the PostgreSQL project, please |
-+ | see appropriate copyright notices that follow. |
-+ | Initial conversion by Brian Shire <shire@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ */
-+
-+/* $Id: pgsql_s_lock.h 307048 2011-01-03 23:53:17Z kalle $ */
-+
-+/*-------------------------------------------------------------------------
-+ *
-+ * s_lock.h
-+ * Hardware-dependent implementation of spinlocks.
-+ *
-+ * NOTE: none of the macros in this file are intended to be called directly.
-+ * Call them through the hardware-independent macros in spin.h.
-+ *
-+ * The following hardware-dependent macros must be provided for each
-+ * supported platform:
-+ *
-+ * void S_INIT_LOCK(slock_t *lock)
-+ * Initialize a spinlock (to the unlocked state).
-+ *
-+ * void S_LOCK(slock_t *lock)
-+ * Acquire a spinlock, waiting if necessary.
-+ * Time out and abort() if unable to acquire the lock in a
-+ * "reasonable" amount of time --- typically ~ 1 minute.
-+ *
-+ * void S_UNLOCK(slock_t *lock)
-+ * Unlock a previously acquired lock.
-+ *
-+ * bool S_LOCK_FREE(slock_t *lock)
-+ * Tests if the lock is free. Returns TRUE if free, FALSE if locked.
-+ * This does *not* change the state of the lock.
-+ *
-+ * void SPIN_DELAY(void)
-+ * Delay operation to occur inside spinlock wait loop.
-+ *
-+ * Note to implementors: there are default implementations for all these
-+ * macros at the bottom of the file. Check if your platform can use
-+ * these or needs to override them.
-+ *
-+ * Usually, S_LOCK() is implemented in terms of an even lower-level macro
-+ * TAS():
-+ *
-+ * int TAS(slock_t *lock)
-+ * Atomic test-and-set instruction. Attempt to acquire the lock,
-+ * but do *not* wait. Returns 0 if successful, nonzero if unable
-+ * to acquire the lock.
-+ *
-+ * TAS() is NOT part of the API, and should never be called directly.
-+ *
-+ * CAUTION: on some platforms TAS() may sometimes report failure to acquire
-+ * a lock even when the lock is not locked. For example, on Alpha TAS()
-+ * will "fail" if interrupted. Therefore TAS() should always be invoked
-+ * in a retry loop, even if you are certain the lock is free.
-+ *
-+ * ANOTHER CAUTION: be sure that TAS() and S_UNLOCK() represent sequence
-+ * points, ie, loads and stores of other values must not be moved across
-+ * a lock or unlock. In most cases it suffices to make the operation be
-+ * done through a "volatile" pointer.
-+ *
-+ * On most supported platforms, TAS() uses a tas() function written
-+ * in assembly language to execute a hardware atomic-test-and-set
-+ * instruction. Equivalent OS-supplied mutex routines could be used too.
-+ *
-+ * If no system-specific TAS() is available (ie, HAVE_SPINLOCKS is not
-+ * defined), then we fall back on an emulation that uses SysV semaphores
-+ * (see spin.c). This emulation will be MUCH MUCH slower than a proper TAS()
-+ * implementation, because of the cost of a kernel call per lock or unlock.
-+ * An old report is that Postgres spends around 40% of its time in semop(2)
-+ * when using the SysV semaphore code.
-+ *
-+ *
-+ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
-+ * Portions Copyright (c) 1994, Regents of the University of California
-+ *
-+ * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.157 2006/06/07 22:24:45 momjian Exp $
-+ *
-+ *-------------------------------------------------------------------------
-+ */
-+#ifndef S_LOCK_H
-+#define S_LOCK_H
-+
-+/** APC namespace protection ************************************************/
-+/* hack to protect against any possible runtime namespace collisions...*/
-+#define pg_usleep apc_spin_pg_usleep
-+#define s_lock apc_spin_s_lock
-+#define spins_per_delay apc_spin_spins_per_delay
-+/****************************************************************************/
-+
-+
-+/* #include "storage/pg_sema.h" -- Removed for APC */
-+
-+#define HAVE_SPINLOCKS 1 /* -- Added for APC */
-+
-+#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
-+
-+
-+#if defined(__GNUC__) || defined(__ICC)
-+/*************************************************************************
-+ * All the gcc inlines
-+ * Gcc consistently defines the CPU as __cpu__.
-+ * Other compilers use __cpu or __cpu__ so we test for both in those cases.
-+ */
-+
-+/*----------
-+ * Standard gcc asm format (assuming "volatile slock_t *lock"):
-+
-+ __asm__ __volatile__(
-+ " instruction \n"
-+ " instruction \n"
-+ " instruction \n"
-+: "=r"(_res), "+m"(*lock) // return register, in/out lock value
-+: "r"(lock) // lock pointer, in input register
-+: "memory", "cc"); // show clobbered registers here
-+
-+ * The output-operands list (after first colon) should always include
-+ * "+m"(*lock), whether or not the asm code actually refers to this
-+ * operand directly. This ensures that gcc believes the value in the
-+ * lock variable is used and set by the asm code. Also, the clobbers
-+ * list (after third colon) should always include "memory"; this prevents
-+ * gcc from thinking it can cache the values of shared-memory fields
-+ * across the asm code. Add "cc" if your asm code changes the condition
-+ * code register, and also list any temp registers the code uses.
-+ *----------
-+ */
-+
-+
-+#ifdef __i386__ /* 32-bit i386 */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register slock_t _res = 1;
-+
-+ /*
-+ * Use a non-locking test before asserting the bus lock. Note that the
-+ * extra test appears to be a small loss on some x86 platforms and a small
-+ * win on others; it's by no means clear that we should keep it.
-+ */
-+ __asm__ __volatile__(
-+ " cmpb $0,%1 \n"
-+ " jne 1f \n"
-+ " lock \n"
-+ " xchgb %0,%1 \n"
-+ "1: \n"
-+: "+q"(_res), "+m"(*lock)
-+:
-+: "memory", "cc");
-+ return (int) _res;
-+}
-+
-+#define SPIN_DELAY() spin_delay()
-+
-+static __inline__ void
-+spin_delay(void)
-+{
-+ /*
-+ * This sequence is equivalent to the PAUSE instruction ("rep" is
-+ * ignored by old IA32 processors if the following instruction is
-+ * not a string operation); the IA-32 Architecture Software
-+ * Developer's Manual, Vol. 3, Section 7.7.2 describes why using
-+ * PAUSE in the inner loop of a spin lock is necessary for good
-+ * performance:
-+ *
-+ * The PAUSE instruction improves the performance of IA-32
-+ * processors supporting Hyper-Threading Technology when
-+ * executing spin-wait loops and other routines where one
-+ * thread is accessing a shared lock or semaphore in a tight
-+ * polling loop. When executing a spin-wait loop, the
-+ * processor can suffer a severe performance penalty when
-+ * exiting the loop because it detects a possible memory order
-+ * violation and flushes the core processor's pipeline. The
-+ * PAUSE instruction provides a hint to the processor that the
-+ * code sequence is a spin-wait loop. The processor uses this
-+ * hint to avoid the memory order violation and prevent the
-+ * pipeline flush. In addition, the PAUSE instruction
-+ * de-pipelines the spin-wait loop to prevent it from
-+ * consuming execution resources excessively.
-+ */
-+ __asm__ __volatile__(
-+ " rep; nop \n");
-+}
-+
-+#endif /* __i386__ */
-+
-+
-+#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register slock_t _res = 1;
-+
-+ /*
-+ * On Opteron, using a non-locking test before the locking instruction
-+ * is a huge loss. On EM64T, it appears to be a wash or small loss,
-+ * so we needn't bother to try to distinguish the sub-architectures.
-+ */
-+ __asm__ __volatile__(
-+ " lock \n"
-+ " xchgb %0,%1 \n"
-+: "+q"(_res), "+m"(*lock)
-+:
-+: "memory", "cc");
-+ return (int) _res;
-+}
-+
-+#define SPIN_DELAY() spin_delay()
-+
-+static __inline__ void
-+spin_delay(void)
-+{
-+ /*
-+ * Adding a PAUSE in the spin delay loop is demonstrably a no-op on
-+ * Opteron, but it may be of some use on EM64T, so we keep it.
-+ */
-+ __asm__ __volatile__(
-+ " rep; nop \n");
-+}
-+
-+#endif /* __x86_64__ */
-+
-+
-+#if defined(__ia64__) || defined(__ia64) /* Intel Itanium */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned int slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+#ifndef __INTEL_COMPILER
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ long int ret;
-+
-+ __asm__ __volatile__(
-+ " xchg4 %0=%1,%2 \n"
-+: "=r"(ret), "+m"(*lock)
-+: "r"(1)
-+: "memory");
-+ return (int) ret;
-+}
-+
-+#else /* __INTEL_COMPILER */
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ int ret;
-+
-+ ret = _InterlockedExchange(lock,1); /* this is a xchg asm macro */
-+
-+ return ret;
-+}
-+
-+#endif /* __INTEL_COMPILER */
-+#endif /* __ia64__ || __ia64 */
-+
-+
-+#if defined(__arm__) || defined(__arm)
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register slock_t _res = 1;
-+
-+ __asm__ __volatile__(
-+ " swpb %0, %0, [%2] \n"
-+: "+r"(_res), "+m"(*lock)
-+: "r"(lock)
-+: "memory");
-+ return (int) _res;
-+}
-+
-+#endif /* __arm__ */
-+
-+
-+/* S/390 and S/390x Linux (32- and 64-bit zSeries) */
-+#if defined(__s390__) || defined(__s390x__)
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned int slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ int _res = 0;
-+
-+ __asm__ __volatile__(
-+ " cs %0,%3,0(%2) \n"
-+: "+d"(_res), "+m"(*lock)
-+: "a"(lock), "d"(1)
-+: "memory", "cc");
-+ return _res;
-+}
-+
-+#endif /* __s390__ || __s390x__ */
-+
-+
-+#if defined(__sparc__) /* Sparc */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register slock_t _res;
-+
-+ /*
-+ * See comment in /pg/backend/port/tas/solaris_sparc.s for why this
-+ * uses "ldstub", and that file uses "cas". gcc currently generates
-+ * sparcv7-targeted binaries, so "cas" use isn't possible.
-+ */
-+ __asm__ __volatile__(
-+ " ldstub [%2], %0 \n"
-+: "=r"(_res), "+m"(*lock)
-+: "r"(lock)
-+: "memory");
-+ return (int) _res;
-+}
-+
-+#endif /* __sparc__ */
-+
-+
-+/* PowerPC */
-+#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
-+#define HAS_TEST_AND_SET
-+
-+#if defined(__ppc64__) || defined(__powerpc64__)
-+typedef unsigned long slock_t;
-+#else
-+typedef unsigned int slock_t;
-+#endif
-+
-+#define TAS(lock) tas(lock)
-+/*
-+ * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
-+ * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
-+ */
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ slock_t _t;
-+ int _res;
-+
-+ __asm__ __volatile__(
-+" lwarx %0,0,%3 \n"
-+" cmpwi %0,0 \n"
-+" bne 1f \n"
-+" addi %0,%0,1 \n"
-+" stwcx. %0,0,%3 \n"
-+" beq 2f \n"
-+"1: li %1,1 \n"
-+" b 3f \n"
-+"2: \n"
-+" isync \n"
-+" li %1,0 \n"
-+"3: \n"
-+
-+: "=&r"(_t), "=r"(_res), "+m"(*lock)
-+: "r"(lock)
-+: "memory", "cc");
-+ return _res;
-+}
-+
-+/* PowerPC S_UNLOCK is almost standard but requires a "sync" instruction */
-+#define S_UNLOCK(lock) \
-+do \
-+{ \
-+ __asm__ __volatile__ (" sync \n"); \
-+ *((volatile slock_t *) (lock)) = 0; \
-+} while (0)
-+
-+#endif /* powerpc */
-+
-+
-+/* Linux Motorola 68k */
-+#if (defined(__mc68000__) || defined(__m68k__)) && defined(__linux__)
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register int rv;
-+
-+ __asm__ __volatile__(
-+ " clrl %0 \n"
-+ " tas %1 \n"
-+ " sne %0 \n"
-+: "=d"(rv), "+m"(*lock)
-+:
-+: "memory", "cc");
-+ return rv;
-+}
-+
-+#endif /* (__mc68000__ || __m68k__) && __linux__ */
-+
-+
-+/*
-+ * VAXen -- even multiprocessor ones
-+ * (thanks to Tom Ivar Helbekkmo)
-+ */
-+#if defined(__vax__)
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register int _res;
-+
-+ __asm__ __volatile__(
-+ " movl $1, %0 \n"
-+ " bbssi $0, (%2), 1f \n"
-+ " clrl %0 \n"
-+ "1: \n"
-+: "=&r"(_res), "+m"(*lock)
-+: "r"(lock)
-+: "memory");
-+ return _res;
-+}
-+
-+#endif /* __vax__ */
-+
-+
-+#if defined(__ns32k__) /* National Semiconductor 32K */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register int _res;
-+
-+ __asm__ __volatile__(
-+ " sbitb 0, %1 \n"
-+ " sfsd %0 \n"
-+: "=r"(_res), "+m"(*lock)
-+:
-+: "memory");
-+ return _res;
-+}
-+
-+#endif /* __ns32k__ */
-+
-+
-+#if defined(__alpha) || defined(__alpha__) /* Alpha */
-+/*
-+ * Correct multi-processor locking methods are explained in section 5.5.3
-+ * of the Alpha AXP Architecture Handbook, which at this writing can be
-+ * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html.
-+ * For gcc we implement the handbook's code directly with inline assembler.
-+ */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned long slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register slock_t _res;
-+
-+ __asm__ __volatile__(
-+ " ldq $0, %1 \n"
-+ " bne $0, 2f \n"
-+ " ldq_l %0, %1 \n"
-+ " bne %0, 2f \n"
-+ " mov 1, $0 \n"
-+ " stq_c $0, %1 \n"
-+ " beq $0, 2f \n"
-+ " mb \n"
-+ " br 3f \n"
-+ "2: mov 1, %0 \n"
-+ "3: \n"
-+: "=&r"(_res), "+m"(*lock)
-+:
-+: "memory", "0");
-+ return (int) _res;
-+}
-+
-+#define S_UNLOCK(lock) \
-+do \
-+{\
-+ __asm__ __volatile__ (" mb \n"); \
-+ *((volatile slock_t *) (lock)) = 0; \
-+} while (0)
-+
-+#endif /* __alpha || __alpha__ */
-+
-+
-+#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */
-+/* Note: on SGI we use the OS' mutex ABI, see below */
-+/* Note: R10000 processors require a separate SYNC */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned int slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ register volatile slock_t *_l = lock;
-+ register int _res;
-+ register int _tmp;
-+
-+ __asm__ __volatile__(
-+ " .set push \n"
-+ " .set mips2 \n"
-+ " .set noreorder \n"
-+ " .set nomacro \n"
-+ " ll %0, %2 \n"
-+ " or %1, %0, 1 \n"
-+ " sc %1, %2 \n"
-+ " xori %1, 1 \n"
-+ " or %0, %0, %1 \n"
-+ " sync \n"
-+ " .set pop "
-+: "=&r" (_res), "=&r" (_tmp), "+R" (*_l)
-+:
-+: "memory");
-+ return _res;
-+}
-+
-+/* MIPS S_UNLOCK is almost standard but requires a "sync" instruction */
-+#define S_UNLOCK(lock) \
-+do \
-+{ \
-+ __asm__ __volatile__( \
-+ " .set push \n" \
-+ " .set mips2 \n" \
-+ " .set noreorder \n" \
-+ " .set nomacro \n" \
-+ " sync \n" \
-+ " .set pop "); \
-+ *((volatile slock_t *) (lock)) = 0; \
-+} while (0)
-+
-+#endif /* __mips__ && !__sgi */
-+
-+
-+/* These live in s_lock.c, but only for gcc */
-+
-+
-+#if defined(__m68k__) && !defined(__linux__) /* non-Linux Motorola 68k */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+#endif
-+
-+
-+#endif /* __GNUC__ */
-+
-+
-+
-+/*
-+ * ---------------------------------------------------------------------
-+ * Platforms that use non-gcc inline assembly:
-+ * ---------------------------------------------------------------------
-+ */
-+
-+#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */
-+
-+
-+#if defined(USE_UNIVEL_CC) /* Unixware compiler */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+
-+#define TAS(lock) tas(lock)
-+
-+asm int
-+tas(volatile slock_t *s_lock)
-+{
-+/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */
-+%mem s_lock
-+ pushl %ebx
-+ movl s_lock, %ebx
-+ movl $255, %eax
-+ lock
-+ xchgb %al, (%ebx)
-+ popl %ebx
-+}
-+
-+#endif /* defined(USE_UNIVEL_CC) */
-+
-+
-+#if defined(__alpha) || defined(__alpha__) /* Tru64 Unix Alpha compiler */
-+/*
-+ * The Tru64 compiler doesn't support gcc-style inline asm, but it does
-+ * have some builtin functions that accomplish much the same results.
-+ * For simplicity, slock_t is defined as long (ie, quadword) on Alpha
-+ * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only
-+ * operate on an int (ie, longword), but that's OK as long as we define
-+ * S_INIT_LOCK to zero out the whole quadword.
-+ */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned long slock_t;
-+
-+#include <alpha/builtins.h>
-+#define S_INIT_LOCK(lock) (*(lock) = 0)
-+#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0)
-+#define S_UNLOCK(lock) __UNLOCK_LONG(lock)
-+
-+#endif /* __alpha || __alpha__ */
-+
-+
-+#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */
-+/*
-+ * HP's PA-RISC
-+ *
-+ * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because
-+ * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte
-+ * struct. The active word in the struct is whichever has the aligned address;
-+ * the other three words just sit at -1.
-+ *
-+ * When using gcc, we can inline the required assembly code.
-+ */
-+#define HAS_TEST_AND_SET
-+
-+typedef struct
-+{
-+ int sema[4];
-+} slock_t;
-+
-+#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((long) (lock) + 15) & ~15))
-+
-+#if defined(__GNUC__)
-+
-+static __inline__ int
-+tas(volatile slock_t *lock)
-+{
-+ volatile int *lockword = TAS_ACTIVE_WORD(lock);
-+ register int lockval;
-+
-+ __asm__ __volatile__(
-+ " ldcwx 0(0,%2),%0 \n"
-+: "=r"(lockval), "+m"(*lockword)
-+: "r"(lockword)
-+: "memory");
-+ return (lockval == 0);
-+}
-+
-+#endif /* __GNUC__ */
-+
-+#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1)
-+
-+#define S_INIT_LOCK(lock) \
-+ do { \
-+ volatile slock_t *lock_ = (lock); \
-+ lock_->sema[0] = -1; \
-+ lock_->sema[1] = -1; \
-+ lock_->sema[2] = -1; \
-+ lock_->sema[3] = -1; \
-+ } while (0)
-+
-+#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
-+
-+#endif /* __hppa || __hppa__ */
-+
-+
-+#if defined(__hpux) && defined(__ia64) && !defined(__GNUC__)
-+
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned int slock_t;
-+
-+#include <ia64/sys/inline.h>
-+#define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
-+
-+#endif /* HPUX on IA64, non gcc */
-+
-+
-+#if defined(__sgi) /* SGI compiler */
-+/*
-+ * SGI IRIX 5
-+ * slock_t is defined as a unsigned long. We use the standard SGI
-+ * mutex API.
-+ *
-+ * The following comment is left for historical reasons, but is probably
-+ * not a good idea since the mutex ABI is supported.
-+ *
-+ * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II
-+ * assembly from his NECEWS SVR4 port, but we probably ought to retain this
-+ * for the R3000 chips out there.
-+ */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned long slock_t;
-+
-+#include "mutex.h"
-+#define TAS(lock) (test_and_set(lock,1))
-+#define S_UNLOCK(lock) (test_then_and(lock,0))
-+#define S_INIT_LOCK(lock) (test_then_and(lock,0))
-+#define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0)
-+#endif /* __sgi */
-+
-+
-+#if defined(sinix) /* Sinix */
-+/*
-+ * SINIX / Reliant UNIX
-+ * slock_t is defined as a struct abilock_t, which has a single unsigned long
-+ * member. (Basically same as SGI)
-+ */
-+#define HAS_TEST_AND_SET
-+
-+#include "abi_mutex.h"
-+typedef abilock_t slock_t;
-+
-+#define TAS(lock) (!acquire_lock(lock))
-+#define S_UNLOCK(lock) release_lock(lock)
-+#define S_INIT_LOCK(lock) init_lock(lock)
-+#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED)
-+#endif /* sinix */
-+
-+
-+#if defined(_AIX) /* AIX */
-+/*
-+ * AIX (POWER)
-+ */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned int slock_t;
-+
-+#define TAS(lock) _check_lock(lock, 0, 1)
-+#define S_UNLOCK(lock) _clear_lock(lock, 0)
-+#endif /* _AIX */
-+
-+
-+#if defined (nextstep) /* Nextstep */
-+#define HAS_TEST_AND_SET
-+
-+typedef struct mutex slock_t;
-+
-+#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 0 /* -- APC: non-blocking lock not available in this case -- */
-+
-+#define S_LOCK(lock) mutex_lock(lock)
-+#define S_UNLOCK(lock) mutex_unlock(lock)
-+#define S_INIT_LOCK(lock) mutex_init(lock)
-+/* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */
-+#define S_LOCK_FREE(alock) ((alock)->lock == 0)
-+#endif /* nextstep */
-+
-+
-+/* These are in s_lock.c */
-+
-+
-+#if defined(sun3) /* Sun3 */
-+#define HAS_TEST_AND_SET
-+
-+typedef unsigned char slock_t;
-+#endif
-+
-+
-+#if defined(__sun) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
-+#define HAS_TEST_AND_SET
-+
-+#if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
-+typedef unsigned int slock_t;
-+#else
-+typedef unsigned char slock_t;
-+#endif
-+
-+extern slock_t pg_atomic_cas(volatile slock_t *lock, slock_t with,
-+ slock_t cmp);
-+
-+#define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
-+#endif
-+
-+
-+#ifdef WIN32_ONLY_COMPILER
-+typedef LONG slock_t;
-+
-+#define HAS_TEST_AND_SET
-+#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
-+
-+#define SPIN_DELAY() spin_delay()
-+
-+static __forceinline void
-+spin_delay(void)
-+{
-+ /* See comment for gcc code. Same code, MASM syntax */
-+ __asm rep nop;
-+}
-+
-+#endif
-+
-+
-+#endif /* !defined(HAS_TEST_AND_SET) */
-+
-+
-+/* Blow up if we didn't have any way to do spinlocks */
-+#ifndef HAS_TEST_AND_SET
-+/* -- APC: We have better options in APC than this, that should be specified explicitly so just fail out and notify the user -- */
-+#error Spin locking is not available on your platform, please select another locking method (see ./configure --help).
-+/* #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. */
-+#endif
-+
-+
-+#else /* !HAVE_SPINLOCKS */
-+
-+
-+/*
-+ * Fake spinlock implementation using semaphores --- slow and prone
-+ * to fall foul of kernel limits on number of semaphores, so don't use this
-+ * unless you must! The subroutines appear in spin.c.
-+ */
-+
-+/* -- Removed for APC
-+typedef PGSemaphoreData slock_t;
-+
-+extern bool s_lock_free_sema(volatile slock_t *lock);
-+extern void s_unlock_sema(volatile slock_t *lock);
-+extern void s_init_lock_sema(volatile slock_t *lock);
-+extern int tas_sema(volatile slock_t *lock);
-+
-+#define S_LOCK_FREE(lock) s_lock_free_sema(lock)
-+#define S_UNLOCK(lock) s_unlock_sema(lock)
-+#define S_INIT_LOCK(lock) s_init_lock_sema(lock)
-+#define TAS(lock) tas_sema(lock)
-+*/
-+
-+#endif /* HAVE_SPINLOCKS */
-+
-+
-+/*
-+ * Default Definitions - override these above as needed.
-+ */
-+
-+#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 1 /* -- APC: Non-blocking lock available for this case -- */
-+
-+#if !defined(S_LOCK)
-+#define S_LOCK(lock) \
-+ do { \
-+ if (TAS(lock)) \
-+ s_lock((lock), __FILE__, __LINE__ TSRMLS_CC); \
-+ } while (0)
-+#endif /* S_LOCK */
-+
-+#if !defined(S_LOCK_FREE)
-+#define S_LOCK_FREE(lock) (*(lock) == 0)
-+#endif /* S_LOCK_FREE */
-+
-+#if !defined(S_UNLOCK)
-+#define S_UNLOCK(lock) (*((volatile slock_t *) (lock)) = 0)
-+#endif /* S_UNLOCK */
-+
-+#if !defined(S_INIT_LOCK)
-+#define S_INIT_LOCK(lock) S_UNLOCK(lock)
-+#endif /* S_INIT_LOCK */
-+
-+#if !defined(SPIN_DELAY)
-+#define SPIN_DELAY() ((void) 0)
-+#endif /* SPIN_DELAY */
-+
-+#if !defined(TAS)
-+extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
-+ * s_lock.c */
-+
-+#define TAS(lock) tas(lock)
-+#endif /* TAS */
-+
-+
-+/*
-+ * Platform-independent out-of-line support routines
-+ */
-+extern void s_lock(volatile slock_t *lock, const char *file, int line TSRMLS_DC);
-+
-+/* Support for dynamic adjustment of spins_per_delay */
-+#define DEFAULT_SPINS_PER_DELAY 100
-+
-+#if 0 /* -- Removed from APC use -- */
-+extern void set_spins_per_delay(int shared_spins_per_delay);
-+extern int update_spins_per_delay(int shared_spins_per_delay);
-+#endif
-+
-+#endif /* S_LOCK_H */
-diff -Naur a/ext/apc/php_apc.c b/ext/apc/php_apc.c
---- a/ext/apc/php_apc.c 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/php_apc.c 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,1716 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: php_apc.c 325875 2012-05-27 17:15:26Z felipe $ */
-+
-+#include "apc_zend.h"
-+#include "apc_cache.h"
-+#include "apc_iterator.h"
-+#include "apc_main.h"
-+#include "apc_sma.h"
-+#include "apc_lock.h"
-+#include "apc_bin.h"
-+#include "php_globals.h"
-+#include "php_ini.h"
-+#include "ext/standard/info.h"
-+#include "ext/standard/file.h"
-+#include "ext/standard/flock_compat.h"
-+#ifdef HAVE_SYS_FILE_H
-+#include <sys/file.h>
-+#endif
-+#include "SAPI.h"
-+#include "rfc1867.h"
-+#include "php_apc.h"
-+#include "ext/standard/md5.h"
-+
-+#if HAVE_SIGACTION
-+#include "apc_signal.h"
-+#endif
-+
-+/* {{{ PHP_FUNCTION declarations */
-+PHP_FUNCTION(apc_cache_info);
-+PHP_FUNCTION(apc_clear_cache);
-+PHP_FUNCTION(apc_sma_info);
-+PHP_FUNCTION(apc_store);
-+PHP_FUNCTION(apc_fetch);
-+PHP_FUNCTION(apc_delete);
-+PHP_FUNCTION(apc_delete_file);
-+PHP_FUNCTION(apc_compile_file);
-+PHP_FUNCTION(apc_define_constants);
-+PHP_FUNCTION(apc_load_constants);
-+PHP_FUNCTION(apc_add);
-+PHP_FUNCTION(apc_inc);
-+PHP_FUNCTION(apc_dec);
-+PHP_FUNCTION(apc_cas);
-+PHP_FUNCTION(apc_bin_dump);
-+PHP_FUNCTION(apc_bin_load);
-+PHP_FUNCTION(apc_bin_dumpfile);
-+PHP_FUNCTION(apc_bin_loadfile);
-+PHP_FUNCTION(apc_exists);
-+/* }}} */
-+
-+/* {{{ ZEND_DECLARE_MODULE_GLOBALS(apc) */
-+ZEND_DECLARE_MODULE_GLOBALS(apc)
-+
-+/* True globals */
-+apc_cache_t* apc_cache = NULL;
-+apc_cache_t* apc_user_cache = NULL;
-+
-+static void php_apc_init_globals(zend_apc_globals* apc_globals TSRMLS_DC)
-+{
-+ apc_globals->filters = NULL;
-+ apc_globals->compiled_filters = NULL;
-+ apc_globals->initialized = 0;
-+ apc_globals->cache_stack = apc_stack_create(0 TSRMLS_CC);
-+ apc_globals->cache_by_default = 1;
-+ apc_globals->fpstat = 1;
-+ apc_globals->canonicalize = 1;
-+ apc_globals->stat_ctime = 0;
-+ apc_globals->write_lock = 1;
-+ apc_globals->slam_defense = 1;
-+ apc_globals->report_autofilter = 0;
-+ apc_globals->include_once = 0;
-+ apc_globals->apc_optimize_function = NULL;
-+#ifdef MULTIPART_EVENT_FORMDATA
-+ apc_globals->rfc1867 = 0;
-+ memset(&(apc_globals->rfc1867_data), 0, sizeof(apc_rfc1867_data));
-+#endif
-+ memset(&apc_globals->copied_zvals, 0, sizeof(HashTable));
-+ apc_globals->force_file_update = 0;
-+ apc_globals->coredump_unmap = 0;
-+ apc_globals->preload_path = NULL;
-+ apc_globals->use_request_time = 1;
-+ apc_globals->lazy_class_table = NULL;
-+ apc_globals->lazy_function_table = NULL;
-+ apc_globals->serializer_name = NULL;
-+ apc_globals->serializer = NULL;
-+}
-+
-+static void php_apc_shutdown_globals(zend_apc_globals* apc_globals TSRMLS_DC)
-+{
-+ /* deallocate the ignore patterns */
-+ if (apc_globals->filters != NULL) {
-+ int i;
-+ for (i=0; apc_globals->filters[i] != NULL; i++) {
-+ apc_efree(apc_globals->filters[i] TSRMLS_CC);
-+ }
-+ apc_efree(apc_globals->filters TSRMLS_CC);
-+ }
-+
-+ /* the stack should be empty */
-+ assert(apc_stack_size(apc_globals->cache_stack) == 0);
-+
-+ /* apc cleanup */
-+ apc_stack_destroy(apc_globals->cache_stack TSRMLS_CC);
-+
-+ /* the rest of the globals are cleaned up in apc_module_shutdown() */
-+}
-+
-+static long apc_atol(const char *str, int str_len)
-+{
-+#if PHP_MAJOR_VERSION >= 6 || PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
-+ return zend_atol(str, str_len);
-+#else
-+ /* Re-implement zend_atol() for 5.2.x */
-+ long retval;
-+
-+ if (!str_len) {
-+ str_len = strlen(str);
-+ }
-+
-+ retval = strtol(str, NULL, 0);
-+
-+ if (str_len > 0) {
-+ switch (str[str_len - 1]) {
-+ case 'g':
-+ case 'G':
-+ retval *= 1024;
-+ /* break intentionally missing */
-+ case 'm':
-+ case 'M':
-+ retval *= 1024;
-+ /* break intentionally missing */
-+ case 'k':
-+ case 'K':
-+ retval *= 1024;
-+ break;
-+ }
-+ }
-+
-+ return retval;
-+#endif
-+}
-+
-+/* }}} */
-+
-+/* {{{ PHP_INI */
-+
-+static PHP_INI_MH(OnUpdate_filters) /* {{{ */
-+{
-+ APCG(filters) = apc_tokenize(new_value, ',' TSRMLS_CC);
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */
-+{
-+#if APC_MMAP
-+ if(zend_atoi(new_value, new_value_length)!=1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "apc.shm_segments setting ignored in MMAP mode");
-+ }
-+ APCG(shm_segments) = 1;
-+#else
-+ APCG(shm_segments) = zend_atoi(new_value, new_value_length);
-+#endif
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+static PHP_INI_MH(OnUpdateShmSize) /* {{{ */
-+{
-+ long s = apc_atol(new_value, new_value_length);
-+
-+ if(s <= 0) {
-+ return FAILURE;
-+ }
-+
-+ if(s < 1048576L) {
-+ /* if it's less than 1Mb, they are probably using the old syntax */
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "apc.shm_size now uses M/G suffixes, please update your ini files");
-+ s = s * 1048576L;
-+ }
-+
-+ APCG(shm_size) = s;
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+#ifdef MULTIPART_EVENT_FORMDATA
-+static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */
-+{
-+ int tmp;
-+ tmp = zend_atoi(new_value, new_value_length);
-+ if(tmp < 0) {
-+ apc_error("rfc1867_freq must be greater than or equal to zero." TSRMLS_CC);
-+ return FAILURE;
-+ }
-+ if(new_value[new_value_length-1] == '%') {
-+ if(tmp > 100) {
-+ apc_error("rfc1867_freq cannot be over 100%%" TSRMLS_CC);
-+ return FAILURE;
-+ }
-+ APCG(rfc1867_freq) = tmp / 100.0;
-+ } else {
-+ APCG(rfc1867_freq) = tmp;
-+ }
-+ return SUCCESS;
-+}
-+/* }}} */
-+#endif
-+
-+PHP_INI_BEGIN()
-+STD_PHP_INI_BOOLEAN("apc.enabled", "1", PHP_INI_SYSTEM, OnUpdateBool, enabled, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.shm_segments", "1", PHP_INI_SYSTEM, OnUpdateShmSegments, shm_segments, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.shm_size", "32M", PHP_INI_SYSTEM, OnUpdateShmSize, shm_size, zend_apc_globals, apc_globals)
-+#ifdef ZEND_ENGINE_2_4
-+STD_PHP_INI_ENTRY("apc.shm_strings_buffer", "4M", PHP_INI_SYSTEM, OnUpdateLong, shm_strings_buffer, zend_apc_globals, apc_globals)
-+#endif
-+STD_PHP_INI_BOOLEAN("apc.include_once_override", "0", PHP_INI_SYSTEM, OnUpdateBool, include_once, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.num_files_hint", "1000", PHP_INI_SYSTEM, OnUpdateLong, num_files_hint, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.user_entries_hint", "4096", PHP_INI_SYSTEM, OnUpdateLong, user_entries_hint, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.gc_ttl", "3600", PHP_INI_SYSTEM, OnUpdateLong, gc_ttl, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.ttl", "0", PHP_INI_SYSTEM, OnUpdateLong, ttl, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.user_ttl", "0", PHP_INI_SYSTEM, OnUpdateLong, user_ttl, zend_apc_globals, apc_globals)
-+#if APC_MMAP
-+STD_PHP_INI_ENTRY("apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apc_globals, apc_globals)
-+#endif
-+PHP_INI_ENTRY("apc.filters", NULL, PHP_INI_SYSTEM, OnUpdate_filters)
-+STD_PHP_INI_BOOLEAN("apc.cache_by_default", "1", PHP_INI_ALL, OnUpdateBool, cache_by_default, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.file_update_protection", "2", PHP_INI_SYSTEM, OnUpdateLong,file_update_protection, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.max_file_size", "1M", PHP_INI_SYSTEM, OnUpdateLong, max_file_size, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.stat", "1", PHP_INI_SYSTEM, OnUpdateBool, fpstat, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.canonicalize", "1", PHP_INI_SYSTEM, OnUpdateBool, canonicalize, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.stat_ctime", "0", PHP_INI_SYSTEM, OnUpdateBool, stat_ctime, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.write_lock", "1", PHP_INI_SYSTEM, OnUpdateBool, write_lock, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.slam_defense", "1", PHP_INI_SYSTEM, OnUpdateBool, slam_defense, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.report_autofilter", "0", PHP_INI_SYSTEM, OnUpdateBool, report_autofilter,zend_apc_globals, apc_globals)
-+#ifdef MULTIPART_EVENT_FORMDATA
-+STD_PHP_INI_BOOLEAN("apc.rfc1867", "0", PHP_INI_SYSTEM, OnUpdateBool, rfc1867, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.rfc1867_prefix", "upload_", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_prefix, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.rfc1867_name", "APC_UPLOAD_PROGRESS", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_name, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.rfc1867_freq", "0", PHP_INI_SYSTEM, OnUpdateRfc1867Freq, rfc1867_freq, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.rfc1867_ttl", "3600", PHP_INI_SYSTEM, OnUpdateLong, rfc1867_ttl, zend_apc_globals, apc_globals)
-+#endif
-+STD_PHP_INI_BOOLEAN("apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.preload_path", (char*)NULL, PHP_INI_SYSTEM, OnUpdateString, preload_path, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.file_md5", "0", PHP_INI_SYSTEM, OnUpdateBool, file_md5, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.use_request_time", "1", PHP_INI_ALL, OnUpdateBool, use_request_time, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.lazy_functions", "0", PHP_INI_SYSTEM, OnUpdateBool, lazy_functions, zend_apc_globals, apc_globals)
-+STD_PHP_INI_BOOLEAN("apc.lazy_classes", "0", PHP_INI_SYSTEM, OnUpdateBool, lazy_classes, zend_apc_globals, apc_globals)
-+STD_PHP_INI_ENTRY("apc.serializer", "default", PHP_INI_SYSTEM, OnUpdateStringUnempty, serializer_name, zend_apc_globals, apc_globals)
-+PHP_INI_END()
-+
-+/* }}} */
-+
-+/* {{{ PHP_MINFO_FUNCTION(apc) */
-+static PHP_MINFO_FUNCTION(apc)
-+{
-+ apc_serializer_t *serializer = NULL;
-+ smart_str names = {0,};
-+ int i;
-+
-+ php_info_print_table_start();
-+ php_info_print_table_header(2, "APC Support", APCG(enabled) ? "enabled" : "disabled");
-+ php_info_print_table_row(2, "Version", PHP_APC_VERSION);
-+#ifdef __DEBUG_APC__
-+ php_info_print_table_row(2, "APC Debugging", "Enabled");
-+#else
-+ php_info_print_table_row(2, "APC Debugging", "Disabled");
-+#endif
-+#if APC_MMAP
-+ php_info_print_table_row(2, "MMAP Support", "Enabled");
-+ php_info_print_table_row(2, "MMAP File Mask", APCG(mmap_file_mask));
-+#else
-+ php_info_print_table_row(2, "MMAP Support", "Disabled");
-+#endif
-+ php_info_print_table_row(2, "Locking type", APC_LOCK_TYPE);
-+
-+ for( i = 0, serializer = apc_get_serializers(TSRMLS_C);
-+ serializer->name != NULL;
-+ serializer++, i++) {
-+ if(i != 0) smart_str_appends(&names, ", ");
-+ smart_str_appends(&names, serializer->name);
-+ }
-+
-+ if(names.c) {
-+ smart_str_0(&names);
-+ php_info_print_table_row(2, "Serialization Support", names.c);
-+ smart_str_free(&names);
-+ } else {
-+ php_info_print_table_row(2, "Serialization Support", "broken");
-+ }
-+
-+ php_info_print_table_row(2, "Revision", "$Revision: 325875 $");
-+ php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__);
-+ php_info_print_table_end();
-+ DISPLAY_INI_ENTRIES();
-+}
-+/* }}} */
-+
-+#ifdef MULTIPART_EVENT_FORMDATA
-+extern int apc_rfc1867_progress(unsigned int event, void *event_data, void **extra TSRMLS_DC);
-+#endif
-+
-+/* {{{ PHP_MINIT_FUNCTION(apc) */
-+static PHP_MINIT_FUNCTION(apc)
-+{
-+ ZEND_INIT_MODULE_GLOBALS(apc, php_apc_init_globals, php_apc_shutdown_globals);
-+
-+ REGISTER_INI_ENTRIES();
-+
-+ /* Disable APC in cli mode unless overridden by apc.enable_cli */
-+ if(!APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) {
-+ APCG(enabled) = 0;
-+ }
-+
-+ if (APCG(enabled)) {
-+ if(APCG(initialized)) {
-+ apc_process_init(module_number TSRMLS_CC);
-+ } else {
-+ apc_module_init(module_number TSRMLS_CC);
-+ apc_zend_init(TSRMLS_C);
-+ apc_process_init(module_number TSRMLS_CC);
-+#ifdef MULTIPART_EVENT_FORMDATA
-+ /* File upload progress tracking */
-+ if(APCG(rfc1867)) {
-+ php_rfc1867_callback = apc_rfc1867_progress;
-+ }
-+#endif
-+ apc_iterator_init(module_number TSRMLS_CC);
-+ }
-+
-+ zend_register_long_constant("APC_BIN_VERIFY_MD5", sizeof("APC_BIN_VERIFY_MD5"), APC_BIN_VERIFY_MD5, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
-+ zend_register_long_constant("APC_BIN_VERIFY_CRC32", sizeof("APC_BIN_VERIFY_CRC32"), APC_BIN_VERIFY_CRC32, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_MSHUTDOWN_FUNCTION(apc) */
-+static PHP_MSHUTDOWN_FUNCTION(apc)
-+{
-+ if(APCG(enabled)) {
-+ apc_process_shutdown(TSRMLS_C);
-+ apc_zend_shutdown(TSRMLS_C);
-+ apc_module_shutdown(TSRMLS_C);
-+#ifndef ZTS
-+ php_apc_shutdown_globals(&apc_globals);
-+#endif
-+#if HAVE_SIGACTION
-+ apc_shutdown_signals(TSRMLS_C);
-+#endif
-+ }
-+#ifdef ZTS
-+ ts_free_id(apc_globals_id);
-+#endif
-+ UNREGISTER_INI_ENTRIES();
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_RINIT_FUNCTION(apc) */
-+static PHP_RINIT_FUNCTION(apc)
-+{
-+ if(APCG(enabled)) {
-+ apc_request_init(TSRMLS_C);
-+
-+#if HAVE_SIGACTION
-+ apc_set_signals(TSRMLS_C);
-+#endif
-+ }
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_RSHUTDOWN_FUNCTION(apc) */
-+static PHP_RSHUTDOWN_FUNCTION(apc)
-+{
-+ if(APCG(enabled)) {
-+ apc_request_shutdown(TSRMLS_C);
-+ }
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ proto array apc_cache_info([string type [, bool limited]]) */
-+PHP_FUNCTION(apc_cache_info)
-+{
-+ zval* info;
-+ char *cache_type;
-+ int ct_len;
-+ zend_bool limited = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &cache_type, &ct_len, &limited) == FAILURE) {
-+ return;
-+ }
-+
-+ if(ZEND_NUM_ARGS()) {
-+ if(!strcasecmp(cache_type,"user")) {
-+ info = apc_cache_info(apc_user_cache, limited TSRMLS_CC);
-+ } else if(!strcasecmp(cache_type,"filehits")) {
-+#ifdef APC_FILEHITS
-+ RETVAL_ZVAL(APCG(filehits), 1, 0);
-+ return;
-+#else
-+ RETURN_FALSE;
-+#endif
-+ } else {
-+ info = apc_cache_info(apc_cache, limited TSRMLS_CC);
-+ }
-+ } else {
-+ info = apc_cache_info(apc_cache, limited TSRMLS_CC);
-+ }
-+
-+ if(!info) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC info available. Perhaps APC is not enabled? Check apc.enabled in your ini file");
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_ZVAL(info, 0, 1);
-+
-+}
-+/* }}} */
-+
-+/* {{{ proto void apc_clear_cache([string cache]) */
-+PHP_FUNCTION(apc_clear_cache)
-+{
-+ char *cache_type;
-+ int ct_len = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &cache_type, &ct_len) == FAILURE) {
-+ return;
-+ }
-+
-+ if(ct_len) {
-+ if(!strcasecmp(cache_type, "user")) {
-+ apc_cache_clear(apc_user_cache TSRMLS_CC);
-+ RETURN_TRUE;
-+ }
-+ }
-+ apc_cache_clear(apc_cache TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto array apc_sma_info([bool limited]) */
-+PHP_FUNCTION(apc_sma_info)
-+{
-+ apc_sma_info_t* info;
-+ zval* block_lists;
-+ int i;
-+ zend_bool limited = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &limited) == FAILURE) {
-+ return;
-+ }
-+
-+ info = apc_sma_info(limited TSRMLS_CC);
-+
-+ if(!info) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC SMA info available. Perhaps APC is disabled via apc.enabled?");
-+ RETURN_FALSE;
-+ }
-+
-+ array_init(return_value);
-+ add_assoc_long(return_value, "num_seg", info->num_seg);
-+ add_assoc_double(return_value, "seg_size", (double)info->seg_size);
-+ add_assoc_double(return_value, "avail_mem", (double)apc_sma_get_avail_mem());
-+
-+ if(limited) {
-+ apc_sma_free_info(info TSRMLS_CC);
-+ return;
-+ }
-+
-+#if ALLOC_DISTRIBUTION
-+ {
-+ size_t *adist = apc_sma_get_alloc_distribution();
-+ zval* list;
-+ ALLOC_INIT_ZVAL(list);
-+ array_init(list);
-+ for(i=0; i<30; i++) {
-+ add_next_index_long(list, adist[i]);
-+ }
-+ add_assoc_zval(return_value, "adist", list);
-+ }
-+#endif
-+ ALLOC_INIT_ZVAL(block_lists);
-+ array_init(block_lists);
-+
-+ for (i = 0; i < info->num_seg; i++) {
-+ apc_sma_link_t* p;
-+ zval* list;
-+
-+ ALLOC_INIT_ZVAL(list);
-+ array_init(list);
-+
-+ for (p = info->list[i]; p != NULL; p = p->next) {
-+ zval* link;
-+
-+ ALLOC_INIT_ZVAL(link);
-+ array_init(link);
-+
-+ add_assoc_long(link, "size", p->size);
-+ add_assoc_long(link, "offset", p->offset);
-+ add_next_index_zval(list, link);
-+ }
-+ add_next_index_zval(block_lists, list);
-+ }
-+ add_assoc_zval(return_value, "block_lists", block_lists);
-+ apc_sma_free_info(info TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ */
-+int _apc_update(char *strkey, int strkey_len, apc_cache_updater_t updater, void* data TSRMLS_DC)
-+{
-+ if(!APCG(enabled)) {
-+ return 0;
-+ }
-+
-+ if (!APCG(serializer) && APCG(serializer_name)) {
-+ /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */
-+ APCG(serializer) = apc_find_serializer(APCG(serializer_name) TSRMLS_CC);
-+ }
-+
-+ HANDLE_BLOCK_INTERRUPTIONS();
-+ APCG(current_cache) = apc_user_cache;
-+
-+ if (!_apc_cache_user_update(apc_user_cache, strkey, strkey_len + 1, updater, data TSRMLS_CC)) {
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+ return 0;
-+ }
-+
-+ APCG(current_cache) = NULL;
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+
-+ return 1;
-+}
-+/* }}} */
-+
-+/* {{{ _apc_store */
-+int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC) {
-+ apc_cache_entry_t *entry;
-+ apc_cache_key_t key;
-+ time_t t;
-+ apc_context_t ctxt={0,};
-+ int ret = 1;
-+
-+ t = apc_time();
-+
-+ if(!APCG(enabled)) return 0;
-+
-+ if (!APCG(serializer) && APCG(serializer_name)) {
-+ /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */
-+ APCG(serializer) = apc_find_serializer(APCG(serializer_name) TSRMLS_CC);
-+ }
-+
-+ HANDLE_BLOCK_INTERRUPTIONS();
-+
-+ APCG(current_cache) = apc_user_cache;
-+
-+ ctxt.pool = apc_pool_create(APC_SMALL_POOL, apc_sma_malloc, apc_sma_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
-+ if (!ctxt.pool) {
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ return 0;
-+ }
-+ ctxt.copy = APC_COPY_IN_USER;
-+ ctxt.force_update = 0;
-+
-+ if(!ctxt.pool) {
-+ ret = 0;
-+ goto nocache;
-+ }
-+
-+ if (!apc_cache_make_user_key(&key, strkey, strkey_len, t)) {
-+ goto freepool;
-+ }
-+
-+ if (apc_cache_is_last_key(apc_user_cache, &key, t TSRMLS_CC)) {
-+ goto freepool;
-+ }
-+
-+ if (!(entry = apc_cache_make_user_entry(strkey, strkey_len, val, &ctxt, ttl TSRMLS_CC))) {
-+ goto freepool;
-+ }
-+
-+ if (!apc_cache_user_insert(apc_user_cache, key, entry, &ctxt, t, exclusive TSRMLS_CC)) {
-+freepool:
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ ret = 0;
-+ }
-+
-+nocache:
-+
-+ APCG(current_cache) = NULL;
-+
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+
-+ return ret;
-+}
-+/* }}} */
-+
-+/* {{{ apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const int exclusive)
-+ */
-+static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const int exclusive)
-+{
-+ zval *key = NULL;
-+ zval *val = NULL;
-+ long ttl = 0L;
-+ HashTable *hash;
-+ HashPosition hpos;
-+ zval **hentry;
-+ char *hkey=NULL;
-+ uint hkey_len;
-+ ulong hkey_idx;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zl", &key, &val, &ttl) == FAILURE) {
-+ return;
-+ }
-+
-+ if (!key) RETURN_FALSE;
-+
-+ if (Z_TYPE_P(key) == IS_ARRAY) {
-+ hash = Z_ARRVAL_P(key);
-+ array_init(return_value);
-+ zend_hash_internal_pointer_reset_ex(hash, &hpos);
-+ while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
-+ zend_hash_get_current_key_ex(hash, &hkey, &hkey_len, &hkey_idx, 0, &hpos);
-+ if (hkey) {
-+ if(!_apc_store(hkey, hkey_len, *hentry, (unsigned int)ttl, exclusive TSRMLS_CC)) {
-+ add_assoc_long_ex(return_value, hkey, hkey_len, -1); /* -1: insertion error */
-+ }
-+ hkey = NULL;
-+ } else {
-+ add_index_long(return_value, hkey_idx, -1); /* -1: insertion error */
-+ }
-+ zend_hash_move_forward_ex(hash, &hpos);
-+ }
-+ return;
-+ } else if (Z_TYPE_P(key) == IS_STRING) {
-+ if (!val) RETURN_FALSE;
-+ if(_apc_store(Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, val, (unsigned int)ttl, exclusive TSRMLS_CC))
-+ RETURN_TRUE;
-+ } else {
-+ apc_warning("apc_store expects key parameter to be a string or an array of key/value pairs." TSRMLS_CC);
-+ }
-+
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+/* {{{ proto int apc_store(mixed key, mixed var [, long ttl ])
-+ */
-+PHP_FUNCTION(apc_store) {
-+ apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto int apc_add(mixed key, mixed var [, long ttl ])
-+ */
-+PHP_FUNCTION(apc_add) {
-+ apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
-+}
-+/* }}} */
-+
-+/* {{{ inc_updater */
-+
-+struct _inc_update_args {
-+ long step;
-+ long lval;
-+};
-+
-+static int inc_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
-+
-+ struct _inc_update_args *args = (struct _inc_update_args*) data;
-+
-+ zval* val = entry->data.user.val;
-+
-+ if(Z_TYPE_P(val) == IS_LONG) {
-+ Z_LVAL_P(val) += args->step;
-+ args->lval = Z_LVAL_P(val);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ proto long apc_inc(string key [, long step [, bool& success]])
-+ */
-+PHP_FUNCTION(apc_inc) {
-+ char *strkey;
-+ int strkey_len;
-+ struct _inc_update_args args = {1L, -1};
-+ zval *success = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &strkey, &strkey_len, &(args.step), &success) == FAILURE) {
-+ return;
-+ }
-+
-+ if (success) {
-+ zval_dtor(success);
-+ }
-+
-+ if(_apc_update(strkey, strkey_len, inc_updater, &args TSRMLS_CC)) {
-+ if(success) ZVAL_TRUE(success);
-+ RETURN_LONG(args.lval);
-+ }
-+
-+ if(success) ZVAL_FALSE(success);
-+
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+/* {{{ proto long apc_dec(string key [, long step [, bool &success]])
-+ */
-+PHP_FUNCTION(apc_dec) {
-+ char *strkey;
-+ int strkey_len;
-+ struct _inc_update_args args = {1L, -1};
-+ zval *success = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &strkey, &strkey_len, &(args.step), &success) == FAILURE) {
-+ return;
-+ }
-+
-+ if (success) {
-+ zval_dtor(success);
-+ }
-+
-+ args.step = args.step * -1;
-+
-+ if(_apc_update(strkey, strkey_len, inc_updater, &args TSRMLS_CC)) {
-+ if(success) ZVAL_TRUE(success);
-+ RETURN_LONG(args.lval);
-+ }
-+
-+ if(success) ZVAL_FALSE(success);
-+
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+/* {{{ cas_updater */
-+static int cas_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
-+ long* vals = ((long*)data);
-+ long old = vals[0];
-+ long new = vals[1];
-+ zval* val = entry->data.user.val;
-+
-+ if(Z_TYPE_P(val) == IS_LONG) {
-+ if(Z_LVAL_P(val) == old) {
-+ Z_LVAL_P(val) = new;
-+ return 1;
-+ }
-+ }
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ proto int apc_cas(string key, int old, int new)
-+ */
-+PHP_FUNCTION(apc_cas) {
-+ char *strkey;
-+ int strkey_len;
-+ long vals[2];
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &strkey, &strkey_len, &vals[0], &vals[1]) == FAILURE) {
-+ return;
-+ }
-+
-+ if(_apc_update(strkey, strkey_len, cas_updater, &vals TSRMLS_CC)) RETURN_TRUE;
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+void *apc_erealloc_wrapper(void *ptr, size_t size) {
-+ return _erealloc(ptr, size, 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
-+}
-+
-+/* {{{ proto mixed apc_fetch(mixed key[, bool &success])
-+ */
-+PHP_FUNCTION(apc_fetch) {
-+ zval *key;
-+ zval *success = NULL;
-+ HashTable *hash;
-+ HashPosition hpos;
-+ zval **hentry;
-+ zval *result;
-+ zval *result_entry;
-+ char *strkey;
-+ int strkey_len;
-+ apc_cache_entry_t* entry;
-+ time_t t;
-+ apc_context_t ctxt = {0,};
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &key, &success) == FAILURE) {
-+ return;
-+ }
-+
-+ t = apc_time();
-+
-+ if (success) {
-+ ZVAL_BOOL(success, 0);
-+ }
-+
-+ ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, NULL, NULL TSRMLS_CC);
-+ if (!ctxt.pool) {
-+ apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+ ctxt.copy = APC_COPY_OUT_USER;
-+ ctxt.force_update = 0;
-+
-+ if(Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) {
-+ convert_to_string(key);
-+ }
-+
-+ if(Z_TYPE_P(key) == IS_STRING) {
-+ strkey = Z_STRVAL_P(key);
-+ strkey_len = Z_STRLEN_P(key);
-+ if(!strkey_len) RETURN_FALSE;
-+ entry = apc_cache_user_find(apc_user_cache, strkey, (strkey_len + 1), t TSRMLS_CC);
-+ if(entry) {
-+ /* deep-copy returned shm zval to emalloc'ed return_value */
-+ apc_cache_fetch_zval(return_value, entry->data.user.val, &ctxt TSRMLS_CC);
-+ apc_cache_release(apc_user_cache, entry TSRMLS_CC);
-+ } else {
-+ goto freepool;
-+ }
-+ } else if(Z_TYPE_P(key) == IS_ARRAY) {
-+ hash = Z_ARRVAL_P(key);
-+ MAKE_STD_ZVAL(result);
-+ array_init(result);
-+ zend_hash_internal_pointer_reset_ex(hash, &hpos);
-+ while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
-+ if(Z_TYPE_PP(hentry) != IS_STRING) {
-+ apc_warning("apc_fetch() expects a string or array of strings." TSRMLS_CC);
-+ goto freepool;
-+ }
-+ entry = apc_cache_user_find(apc_user_cache, Z_STRVAL_PP(hentry), (Z_STRLEN_PP(hentry) + 1), t TSRMLS_CC);
-+ if(entry) {
-+ /* deep-copy returned shm zval to emalloc'ed return_value */
-+ MAKE_STD_ZVAL(result_entry);
-+ apc_cache_fetch_zval(result_entry, entry->data.user.val, &ctxt TSRMLS_CC);
-+ apc_cache_release(apc_user_cache, entry TSRMLS_CC);
-+ zend_hash_add(Z_ARRVAL_P(result), Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) +1, &result_entry, sizeof(zval*), NULL);
-+ } /* don't set values we didn't find */
-+ zend_hash_move_forward_ex(hash, &hpos);
-+ }
-+ RETVAL_ZVAL(result, 0, 1);
-+ } else {
-+ apc_warning("apc_fetch() expects a string or array of strings." TSRMLS_CC);
-+freepool:
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ if (success) {
-+ ZVAL_BOOL(success, 1);
-+ }
-+
-+ apc_pool_destroy(ctxt.pool TSRMLS_CC);
-+ return;
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed apc_exists(mixed key)
-+ */
-+PHP_FUNCTION(apc_exists) {
-+ zval *key;
-+ HashTable *hash;
-+ HashPosition hpos;
-+ zval **hentry;
-+ char *strkey;
-+ int strkey_len;
-+ apc_cache_entry_t* entry;
-+ zval *result;
-+ zval *result_entry;
-+ time_t t;
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &key) == FAILURE) {
-+ return;
-+ }
-+
-+ t = apc_time();
-+
-+ if(Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) {
-+ convert_to_string(key);
-+ }
-+
-+ if(Z_TYPE_P(key) == IS_STRING) {
-+ strkey = Z_STRVAL_P(key);
-+ strkey_len = Z_STRLEN_P(key);
-+ if(!strkey_len) RETURN_FALSE;
-+ entry = apc_cache_user_exists(apc_user_cache, strkey, strkey_len + 1, t TSRMLS_CC);
-+ if(entry) {
-+ RETURN_TRUE;
-+ }
-+ } else if(Z_TYPE_P(key) == IS_ARRAY) {
-+ hash = Z_ARRVAL_P(key);
-+ MAKE_STD_ZVAL(result);
-+ array_init(result);
-+ zend_hash_internal_pointer_reset_ex(hash, &hpos);
-+ while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
-+ if(Z_TYPE_PP(hentry) != IS_STRING) {
-+ apc_warning("apc_exists() expects a string or array of strings." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ entry = apc_cache_user_exists(apc_user_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1, t TSRMLS_CC);
-+ if(entry) {
-+ MAKE_STD_ZVAL(result_entry);
-+ ZVAL_BOOL(result_entry, 1);
-+ zend_hash_add(Z_ARRVAL_P(result), Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) +1, &result_entry, sizeof(zval*), NULL);
-+ } /* don't set values we didn't find */
-+ zend_hash_move_forward_ex(hash, &hpos);
-+ }
-+ RETURN_ZVAL(result, 0, 1);
-+ } else {
-+ apc_warning("apc_exists() expects a string or array of strings." TSRMLS_CC);
-+ }
-+
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+
-+/* {{{ proto mixed apc_delete(mixed keys)
-+ */
-+PHP_FUNCTION(apc_delete) {
-+ zval *keys;
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &keys) == FAILURE) {
-+ return;
-+ }
-+
-+ if (Z_TYPE_P(keys) == IS_STRING) {
-+ if (!Z_STRLEN_P(keys)) RETURN_FALSE;
-+ if(apc_cache_user_delete(apc_user_cache, Z_STRVAL_P(keys), (Z_STRLEN_P(keys) + 1) TSRMLS_CC)) {
-+ RETURN_TRUE;
-+ } else {
-+ RETURN_FALSE;
-+ }
-+ } else if (Z_TYPE_P(keys) == IS_ARRAY) {
-+ HashTable *hash = Z_ARRVAL_P(keys);
-+ HashPosition hpos;
-+ zval **hentry;
-+ array_init(return_value);
-+ zend_hash_internal_pointer_reset_ex(hash, &hpos);
-+ while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
-+ if(Z_TYPE_PP(hentry) != IS_STRING) {
-+ apc_warning("apc_delete() expects a string, array of strings, or APCIterator instance." TSRMLS_CC);
-+ add_next_index_zval(return_value, *hentry);
-+ Z_ADDREF_PP(hentry);
-+ } else if(apc_cache_user_delete(apc_user_cache, Z_STRVAL_PP(hentry), (Z_STRLEN_PP(hentry) + 1) TSRMLS_CC) != 1) {
-+ add_next_index_zval(return_value, *hentry);
-+ Z_ADDREF_PP(hentry);
-+ }
-+ zend_hash_move_forward_ex(hash, &hpos);
-+ }
-+ return;
-+ } else if (Z_TYPE_P(keys) == IS_OBJECT) {
-+ if (apc_iterator_delete(keys TSRMLS_CC)) {
-+ RETURN_TRUE;
-+ } else {
-+ RETURN_FALSE;
-+ }
-+ } else {
-+ apc_warning("apc_delete() expects a string, array of strings, or APCIterator instance." TSRMLS_CC);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed apc_delete_file(mixed keys)
-+ * Deletes the given files from the opcode cache.
-+ * Accepts a string, array of strings, or APCIterator object.
-+ * Returns True/False, or for an Array an Array of failed files.
-+ */
-+PHP_FUNCTION(apc_delete_file) {
-+ zval *keys;
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &keys) == FAILURE) {
-+ return;
-+ }
-+
-+ if (Z_TYPE_P(keys) == IS_STRING) {
-+ if (!Z_STRLEN_P(keys)) RETURN_FALSE;
-+ if(apc_cache_delete(apc_cache, Z_STRVAL_P(keys), Z_STRLEN_P(keys) + 1 TSRMLS_CC) != 1) {
-+ RETURN_FALSE;
-+ } else {
-+ RETURN_TRUE;
-+ }
-+ } else if (Z_TYPE_P(keys) == IS_ARRAY) {
-+ HashTable *hash = Z_ARRVAL_P(keys);
-+ HashPosition hpos;
-+ zval **hentry;
-+ array_init(return_value);
-+ zend_hash_internal_pointer_reset_ex(hash, &hpos);
-+ while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
-+ if(Z_TYPE_PP(hentry) != IS_STRING) {
-+ apc_warning("apc_delete_file() expects a string, array of strings, or APCIterator instance." TSRMLS_CC);
-+ add_next_index_zval(return_value, *hentry);
-+ Z_ADDREF_PP(hentry);
-+ } else if(apc_cache_delete(apc_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1 TSRMLS_CC) != 1) {
-+ add_next_index_zval(return_value, *hentry);
-+ Z_ADDREF_PP(hentry);
-+ }
-+ zend_hash_move_forward_ex(hash, &hpos);
-+ }
-+ return;
-+ } else if (Z_TYPE_P(keys) == IS_OBJECT) {
-+ if (apc_iterator_delete(keys TSRMLS_CC)) {
-+ RETURN_TRUE;
-+ } else {
-+ RETURN_FALSE;
-+ }
-+ } else {
-+ apc_warning("apc_delete_file() expects a string, array of strings, or APCIterator instance." TSRMLS_CC);
-+ }
-+}
-+/* }}} */
-+
-+static void _apc_define_constants(zval *constants, zend_bool case_sensitive TSRMLS_DC) {
-+ char *const_key;
-+ unsigned int const_key_len;
-+ zval **entry;
-+ HashPosition pos;
-+
-+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(constants), &pos);
-+ while (zend_hash_get_current_data_ex(Z_ARRVAL_P(constants), (void**)&entry, &pos) == SUCCESS) {
-+ zend_constant c;
-+ int key_type;
-+ ulong num_key;
-+
-+ key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(constants), &const_key, &const_key_len, &num_key, 0, &pos);
-+ if(key_type != HASH_KEY_IS_STRING) {
-+ zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
-+ continue;
-+ }
-+ switch(Z_TYPE_PP(entry)) {
-+ case IS_LONG:
-+ case IS_DOUBLE:
-+ case IS_STRING:
-+ case IS_BOOL:
-+ case IS_RESOURCE:
-+ case IS_NULL:
-+ break;
-+ default:
-+ zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
-+ continue;
-+ }
-+ c.value = **entry;
-+ zval_copy_ctor(&c.value);
-+ c.flags = case_sensitive;
-+ c.name = zend_strndup(const_key, const_key_len);
-+ c.name_len = const_key_len;
-+ c.module_number = PHP_USER_CONSTANT;
-+ zend_register_constant(&c TSRMLS_CC);
-+
-+ zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
-+ }
-+}
-+
-+/* {{{ proto mixed apc_define_constants(string key, array constants [, bool case_sensitive])
-+ */
-+PHP_FUNCTION(apc_define_constants) {
-+ char *strkey;
-+ int strkey_len;
-+ zval *constants = NULL;
-+ zend_bool case_sensitive = 1;
-+ int argc = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(argc TSRMLS_CC, "sa|b", &strkey, &strkey_len, &constants, &case_sensitive) == FAILURE) {
-+ return;
-+ }
-+
-+ if(!strkey_len) RETURN_FALSE;
-+
-+ _apc_define_constants(constants, case_sensitive TSRMLS_CC);
-+ if(_apc_store(strkey, strkey_len + 1, constants, 0, 0 TSRMLS_CC)) RETURN_TRUE;
-+ RETURN_FALSE;
-+} /* }}} */
-+
-+/* {{{ proto mixed apc_load_constants(string key [, bool case_sensitive])
-+ */
-+PHP_FUNCTION(apc_load_constants) {
-+ char *strkey;
-+ int strkey_len;
-+ apc_cache_entry_t* entry;
-+ time_t t;
-+ zend_bool case_sensitive = 1;
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &strkey, &strkey_len, &case_sensitive) == FAILURE) {
-+ return;
-+ }
-+
-+ if(!strkey_len) RETURN_FALSE;
-+
-+ t = apc_time();
-+
-+ entry = apc_cache_user_find(apc_user_cache, strkey, (strkey_len + 1), t TSRMLS_CC);
-+
-+ if(entry) {
-+ _apc_define_constants(entry->data.user.val, case_sensitive TSRMLS_CC);
-+ apc_cache_release(apc_user_cache, entry TSRMLS_CC);
-+ RETURN_TRUE;
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed apc_compile_file(mixed filenames [, bool atomic])
-+ */
-+PHP_FUNCTION(apc_compile_file) {
-+ zval *file;
-+ zend_file_handle file_handle;
-+ zend_op_array *op_array;
-+ char** filters = NULL;
-+ zend_bool cache_by_default = 1;
-+ HashTable cg_function_table, cg_class_table;
-+ HashTable *cg_orig_function_table, *cg_orig_class_table, *eg_orig_function_table, *eg_orig_class_table;
-+ apc_cache_entry_t** cache_entries;
-+ apc_cache_key_t* keys;
-+ zend_op_array **op_arrays;
-+ time_t t;
-+ zval **hentry;
-+ HashPosition hpos;
-+ int i=0, c=0;
-+ int *rval=NULL;
-+ int count=0;
-+ zend_bool atomic=1;
-+ apc_context_t ctxt = {0,};
-+ zend_execute_data *orig_current_execute_data;
-+ int atomic_fail;
-+
-+ if(!APCG(enabled)) RETURN_FALSE;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &file, &atomic) == FAILURE) {
-+ return;
-+ }
-+
-+ if (Z_TYPE_P(file) != IS_ARRAY && Z_TYPE_P(file) != IS_STRING) {
-+ apc_warning("apc_compile_file argument must be a string or an array of strings" TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ HANDLE_BLOCK_INTERRUPTIONS();
-+ APCG(current_cache) = apc_cache;
-+
-+ /* reset filters and cache_by_default */
-+ filters = APCG(filters);
-+ APCG(filters) = NULL;
-+
-+ cache_by_default = APCG(cache_by_default);
-+ APCG(cache_by_default) = 1;
-+
-+ /* Replace function/class tables to avoid namespace conflicts */
-+ zend_hash_init_ex(&cg_function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
-+ cg_orig_function_table = CG(function_table);
-+ CG(function_table) = &cg_function_table;
-+ zend_hash_init_ex(&cg_class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
-+ cg_orig_class_table = CG(class_table);
-+ CG(class_table) = &cg_class_table;
-+ eg_orig_function_table = EG(function_table);
-+ EG(function_table) = CG(function_table);
-+ eg_orig_class_table = EG(class_table);
-+ EG(class_table) = CG(class_table);
-+ APCG(force_file_update) = 1;
-+
-+ /* Compile the file(s), loading it into the cache */
-+ if (Z_TYPE_P(file) == IS_STRING) {
-+ file_handle.type = ZEND_HANDLE_FILENAME;
-+ file_handle.filename = Z_STRVAL_P(file);
-+ file_handle.free_filename = 0;
-+ file_handle.opened_path = NULL;
-+
-+ orig_current_execute_data = EG(current_execute_data);
-+ zend_try {
-+ op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC);
-+ } zend_catch {
-+ EG(current_execute_data) = orig_current_execute_data;
-+ EG(in_execution) = 1;
-+ CG(unclean_shutdown) = 0;
-+ apc_warning("Error compiling %s in apc_compile_file." TSRMLS_CC, file_handle.filename);
-+ op_array = NULL;
-+ } zend_end_try();
-+ if(op_array != NULL) {
-+ /* Free up everything */
-+ destroy_op_array(op_array TSRMLS_CC);
-+ efree(op_array);
-+ RETVAL_TRUE;
-+ } else {
-+ RETVAL_FALSE;
-+ }
-+ zend_destroy_file_handle(&file_handle TSRMLS_CC);
-+
-+ } else { /* IS_ARRAY */
-+
-+ array_init(return_value);
-+
-+ t = apc_time();
-+
-+ op_arrays = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(zend_op_array*));
-+ cache_entries = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(apc_cache_entry_t*));
-+ keys = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(apc_cache_key_t));
-+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(file), &hpos);
-+ while(zend_hash_get_current_data_ex(Z_ARRVAL_P(file), (void**)&hentry, &hpos) == SUCCESS) {
-+ if (Z_TYPE_PP(hentry) != IS_STRING) {
-+ apc_warning("apc_compile_file array values must be strings, aborting." TSRMLS_CC);
-+ break;
-+ }
-+ file_handle.type = ZEND_HANDLE_FILENAME;
-+ file_handle.filename = Z_STRVAL_PP(hentry);
-+ file_handle.free_filename = 0;
-+ file_handle.opened_path = NULL;
-+
-+ if (!apc_cache_make_file_key(&(keys[i]), file_handle.filename, PG(include_path), t TSRMLS_CC)) {
-+ add_assoc_long(return_value, Z_STRVAL_PP(hentry), -1); /* -1: compilation error */
-+ apc_warning("Error compiling %s in apc_compile_file." TSRMLS_CC, file_handle.filename);
-+ break;
-+ }
-+
-+ if (keys[i].type == APC_CACHE_KEY_FPFILE) {
-+ keys[i].data.fpfile.fullpath = estrndup(keys[i].data.fpfile.fullpath, keys[i].data.fpfile.fullpath_len);
-+ } else if (keys[i].type == APC_CACHE_KEY_USER) {
-+ keys[i].data.user.identifier = estrndup(keys[i].data.user.identifier, keys[i].data.user.identifier_len);
-+ }
-+
-+ orig_current_execute_data = EG(current_execute_data);
-+ zend_try {
-+ if (apc_compile_cache_entry(&keys[i], &file_handle, ZEND_INCLUDE, t, &op_arrays[i], &cache_entries[i] TSRMLS_CC) != SUCCESS) {
-+ op_arrays[i] = NULL;
-+ cache_entries[i] = NULL;
-+ add_assoc_long(return_value, Z_STRVAL_PP(hentry), -2); /* -2: input or cache insertion error */
-+ apc_warning("Error compiling %s in apc_compile_file." TSRMLS_CC, file_handle.filename);
-+ }
-+ } zend_catch {
-+ EG(current_execute_data) = orig_current_execute_data;
-+ EG(in_execution) = 1;
-+ CG(unclean_shutdown) = 0;
-+ op_arrays[i] = NULL;
-+ cache_entries[i] = NULL;
-+ add_assoc_long(return_value, Z_STRVAL_PP(hentry), -1); /* -1: compilation error */
-+ apc_warning("Error compiling %s in apc_compile_file." TSRMLS_CC, file_handle.filename);
-+ } zend_end_try();
-+
-+ zend_destroy_file_handle(&file_handle TSRMLS_CC);
-+ if(op_arrays[i] != NULL) {
-+ count++;
-+ }
-+
-+ /* clean out the function/class tables */
-+ zend_hash_clean(&cg_function_table);
-+ zend_hash_clean(&cg_class_table);
-+
-+ zend_hash_move_forward_ex(Z_ARRVAL_P(file), &hpos);
-+ i++;
-+ }
-+
-+ /* atomically update the cache if no errors or not atomic */
-+ ctxt.copy = APC_COPY_IN_OPCODE;
-+ ctxt.force_update = 1;
-+ if (count == i || !atomic) {
-+ rval = apc_cache_insert_mult(apc_cache, keys, cache_entries, &ctxt, t, i TSRMLS_CC);
-+ atomic_fail = 0;
-+ } else {
-+ atomic_fail = 1;
-+ }
-+
-+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(file), &hpos);
-+ for(c=0; c < i; c++) {
-+ zend_hash_get_current_data_ex(Z_ARRVAL_P(file), (void**)&hentry, &hpos);
-+ if (rval && rval[c] != 1) {
-+ add_assoc_long(return_value, Z_STRVAL_PP(hentry), -2); /* -2: input or cache insertion error */
-+ if (cache_entries[c]) {
-+ apc_pool_destroy(cache_entries[c]->pool TSRMLS_CC);
-+ }
-+ }
-+ if (op_arrays[c]) {
-+ destroy_op_array(op_arrays[c] TSRMLS_CC);
-+ efree(op_arrays[c]);
-+ }
-+ if (atomic_fail && cache_entries[c]) {
-+ apc_pool_destroy(cache_entries[c]->pool TSRMLS_CC);
-+ }
-+ if (keys[c].type == APC_CACHE_KEY_FPFILE) {
-+ efree((void*)keys[c].data.fpfile.fullpath);
-+ } else if (keys[c].type == APC_CACHE_KEY_USER) {
-+ efree((void*)keys[c].data.user.identifier);
-+ }
-+ zend_hash_move_forward_ex(Z_ARRVAL_P(file), &hpos);
-+ }
-+ efree(op_arrays);
-+ efree(keys);
-+ efree(cache_entries);
-+ if (rval) {
-+ efree(rval);
-+ }
-+
-+ }
-+
-+ /* Return class/function tables to previous states, destroy temp tables */
-+ APCG(force_file_update) = 0;
-+ CG(function_table) = cg_orig_function_table;
-+ zend_hash_destroy(&cg_function_table);
-+ CG(class_table) = cg_orig_class_table;
-+ zend_hash_destroy(&cg_class_table);
-+ EG(function_table) = eg_orig_function_table;
-+ EG(class_table) = eg_orig_class_table;
-+
-+ /* Restore global settings */
-+ APCG(filters) = filters;
-+ APCG(cache_by_default) = cache_by_default;
-+
-+ APCG(current_cache) = NULL;
-+ HANDLE_UNBLOCK_INTERRUPTIONS();
-+
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed apc_bin_dump([array files [, array user_vars]])
-+ Returns a binary dump of the given files and user variables from the APC cache.
-+ A NULL for files or user_vars signals a dump of every entry, while array() will dump nothing.
-+ */
-+PHP_FUNCTION(apc_bin_dump) {
-+
-+ zval *z_files = NULL, *z_user_vars = NULL;
-+ HashTable *h_files, *h_user_vars;
-+ apc_bd_t *bd;
-+
-+ if(!APCG(enabled)) {
-+ apc_warning("APC is not enabled, apc_bin_dump not available." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!a!", &z_files, &z_user_vars) == FAILURE) {
-+ return;
-+ }
-+
-+ h_files = z_files ? Z_ARRVAL_P(z_files) : NULL;
-+ h_user_vars = z_user_vars ? Z_ARRVAL_P(z_user_vars) : NULL;
-+ bd = apc_bin_dump(h_files, h_user_vars TSRMLS_CC);
-+ if(bd) {
-+ RETVAL_STRINGL((char*)bd, bd->size-1, 0);
-+ } else {
-+ apc_error("Unknown error encountered during apc_bin_dump." TSRMLS_CC);
-+ RETVAL_NULL();
-+ }
-+
-+ return;
-+}
-+
-+/* {{{ proto mixed apc_bin_dumpfile(array files, array user_vars, string filename, [int flags [, resource context]])
-+ Output a binary dump of the given files and user variables from the APC cache to the named file.
-+ */
-+PHP_FUNCTION(apc_bin_dumpfile) {
-+
-+ zval *z_files = NULL, *z_user_vars = NULL;
-+ HashTable *h_files, *h_user_vars;
-+ char *filename = NULL;
-+ int filename_len;
-+ long flags=0;
-+ zval *zcontext = NULL;
-+ php_stream_context *context = NULL;
-+ php_stream *stream;
-+ int numbytes = 0;
-+ apc_bd_t *bd;
-+
-+ if(!APCG(enabled)) {
-+ apc_warning("APC is not enabled, apc_bin_dumpfile not available." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!s|lr!", &z_files, &z_user_vars, &filename, &filename_len, &flags, &zcontext) == FAILURE) {
-+ return;
-+ }
-+
-+ if(!filename_len) {
-+ apc_error("apc_bin_dumpfile filename argument must be a valid filename." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ h_files = z_files ? Z_ARRVAL_P(z_files) : NULL;
-+ h_user_vars = z_user_vars ? Z_ARRVAL_P(z_user_vars) : NULL;
-+ bd = apc_bin_dump(h_files, h_user_vars TSRMLS_CC);
-+ if(!bd) {
-+ apc_error("Unknown error encountered during apc_bin_dumpfile." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+
-+ /* Most of the following has been taken from the file_get/put_contents functions */
-+
-+ context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
-+ stream = php_stream_open_wrapper_ex(filename, (flags & PHP_FILE_APPEND) ? "ab" : "wb",
-+ ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
-+ if (stream == NULL) {
-+ efree(bd);
-+ apc_error("Unable to write to file in apc_bin_dumpfile." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ if (flags & LOCK_EX && php_stream_lock(stream, LOCK_EX)) {
-+ php_stream_close(stream);
-+ efree(bd);
-+ apc_error("Unable to get a lock on file in apc_bin_dumpfile." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ numbytes = php_stream_write(stream, (char*)bd, bd->size);
-+ if(numbytes != bd->size) {
-+ numbytes = -1;
-+ }
-+
-+ php_stream_close(stream);
-+ efree(bd);
-+
-+ if(numbytes < 0) {
-+ apc_error("Only %d of %d bytes written, possibly out of free disk space" TSRMLS_CC, numbytes, bd->size);
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_LONG(numbytes);
-+}
-+
-+/* {{{ proto mixed apc_bin_load(string data, [int flags])
-+ Load the given binary dump into the APC file/user cache.
-+ */
-+PHP_FUNCTION(apc_bin_load) {
-+
-+ int data_len;
-+ char *data;
-+ long flags = 0;
-+
-+ if(!APCG(enabled)) {
-+ apc_warning("APC is not enabled, apc_bin_load not available." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags) == FAILURE) {
-+ return;
-+ }
-+
-+ if(!data_len || data_len != ((apc_bd_t*)data)->size -1) {
-+ apc_error("apc_bin_load string argument does not appear to be a valid APC binary dump due to size (%d vs expected %d)." TSRMLS_CC, data_len, ((apc_bd_t*)data)->size -1);
-+ RETURN_FALSE;
-+ }
-+
-+ apc_bin_load((apc_bd_t*)data, (int)flags TSRMLS_CC);
-+
-+ RETURN_TRUE;
-+}
-+
-+/* {{{ proto mixed apc_bin_loadfile(string filename, [resource context, [int flags]])
-+ Load the given binary dump from the named file into the APC file/user cache.
-+ */
-+PHP_FUNCTION(apc_bin_loadfile) {
-+
-+ char *filename;
-+ int filename_len;
-+ zval *zcontext = NULL;
-+ long flags;
-+ php_stream_context *context = NULL;
-+ php_stream *stream;
-+ char *data;
-+ int len;
-+
-+ if(!APCG(enabled)) {
-+ apc_warning("APC is not enabled, apc_bin_loadfile not available." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r!l", &filename, &filename_len, &zcontext, &flags) == FAILURE) {
-+ return;
-+ }
-+
-+ if(!filename_len) {
-+ apc_error("apc_bin_loadfile filename argument must be a valid filename." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ context = php_stream_context_from_zval(zcontext, 0);
-+ stream = php_stream_open_wrapper_ex(filename, "rb",
-+ ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
-+ if (!stream) {
-+ apc_error("Unable to read from file in apc_bin_loadfile." TSRMLS_CC);
-+ RETURN_FALSE;
-+ }
-+
-+ len = php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0);
-+ if(len == 0) {
-+ apc_warning("File passed to apc_bin_loadfile was empty: %s." TSRMLS_CC, filename);
-+ RETURN_FALSE;
-+ } else if(len < 0) {
-+ apc_warning("Error reading file passed to apc_bin_loadfile: %s." TSRMLS_CC, filename);
-+ RETURN_FALSE;
-+ } else if(len != ((apc_bd_t*)data)->size) {
-+ apc_warning("file passed to apc_bin_loadfile does not appear to be valid due to size (%d vs expected %d)." TSRMLS_CC, len, ((apc_bd_t*)data)->size -1);
-+ RETURN_FALSE;
-+ }
-+ php_stream_close(stream);
-+
-+ apc_bin_load((apc_bd_t*)data, (int)flags TSRMLS_CC);
-+ efree(data);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ arginfo */
-+#if (PHP_MAJOR_VERSION >= 6 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3))
-+# define PHP_APC_ARGINFO
-+#else
-+# define PHP_APC_ARGINFO static
-+#endif
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_store, 0, 0, 2)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(0, var)
-+ ZEND_ARG_INFO(0, ttl)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_clear_cache, 0, 0, 0)
-+ ZEND_ARG_INFO(0, info)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_sma_info, 0, 0, 0)
-+ ZEND_ARG_INFO(0, limited)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_cache_info, 0, 0, 0)
-+ ZEND_ARG_INFO(0, type)
-+ ZEND_ARG_INFO(0, limited)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_define_constants, 0, 0, 2)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(0, constants)
-+ ZEND_ARG_INFO(0, case_sensitive)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO(arginfo_apc_delete_file, 0)
-+ ZEND_ARG_INFO(0, keys)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO(arginfo_apc_delete, 0)
-+ ZEND_ARG_INFO(0, keys)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_fetch, 0, 0, 1)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(1, success)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_inc, 0, 0, 1)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(0, step)
-+ ZEND_ARG_INFO(1, success)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO(arginfo_apc_cas, 0)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(0, old)
-+ ZEND_ARG_INFO(0, new)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_load_constants, 0, 0, 1)
-+ ZEND_ARG_INFO(0, key)
-+ ZEND_ARG_INFO(0, case_sensitive)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_compile_file, 0, 0, 1)
-+ ZEND_ARG_INFO(0, filenames)
-+ ZEND_ARG_INFO(0, atomic)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_dump, 0, 0, 0)
-+ ZEND_ARG_INFO(0, files)
-+ ZEND_ARG_INFO(0, user_vars)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_dumpfile, 0, 0, 3)
-+ ZEND_ARG_INFO(0, files)
-+ ZEND_ARG_INFO(0, user_vars)
-+ ZEND_ARG_INFO(0, filename)
-+ ZEND_ARG_INFO(0, flags)
-+ ZEND_ARG_INFO(0, context)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_load, 0, 0, 1)
-+ ZEND_ARG_INFO(0, data)
-+ ZEND_ARG_INFO(0, flags)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_loadfile, 0, 0, 1)
-+ ZEND_ARG_INFO(0, filename)
-+ ZEND_ARG_INFO(0, context)
-+ ZEND_ARG_INFO(0, flags)
-+ZEND_END_ARG_INFO()
-+
-+PHP_APC_ARGINFO
-+ZEND_BEGIN_ARG_INFO(arginfo_apc_exists, 0)
-+ ZEND_ARG_INFO(0, keys)
-+ZEND_END_ARG_INFO()
-+/* }}} */
-+
-+/* {{{ apc_functions[] */
-+zend_function_entry apc_functions[] = {
-+ PHP_FE(apc_cache_info, arginfo_apc_cache_info)
-+ PHP_FE(apc_clear_cache, arginfo_apc_clear_cache)
-+ PHP_FE(apc_sma_info, arginfo_apc_sma_info)
-+ PHP_FE(apc_store, arginfo_apc_store)
-+ PHP_FE(apc_fetch, arginfo_apc_fetch)
-+ PHP_FE(apc_delete, arginfo_apc_delete)
-+ PHP_FE(apc_delete_file, arginfo_apc_delete_file)
-+ PHP_FE(apc_define_constants, arginfo_apc_define_constants)
-+ PHP_FE(apc_load_constants, arginfo_apc_load_constants)
-+ PHP_FE(apc_compile_file, arginfo_apc_compile_file)
-+ PHP_FE(apc_add, arginfo_apc_store)
-+ PHP_FE(apc_inc, arginfo_apc_inc)
-+ PHP_FE(apc_dec, arginfo_apc_inc)
-+ PHP_FE(apc_cas, arginfo_apc_cas)
-+ PHP_FE(apc_bin_dump, arginfo_apc_bin_dump)
-+ PHP_FE(apc_bin_load, arginfo_apc_bin_load)
-+ PHP_FE(apc_bin_dumpfile, arginfo_apc_bin_dumpfile)
-+ PHP_FE(apc_bin_loadfile, arginfo_apc_bin_loadfile)
-+ PHP_FE(apc_exists, arginfo_apc_exists)
-+ {NULL, NULL, NULL}
-+};
-+/* }}} */
-+
-+/* {{{ module definition structure */
-+
-+zend_module_entry apc_module_entry = {
-+ STANDARD_MODULE_HEADER,
-+ "apc",
-+ apc_functions,
-+ PHP_MINIT(apc),
-+ PHP_MSHUTDOWN(apc),
-+ PHP_RINIT(apc),
-+ PHP_RSHUTDOWN(apc),
-+ PHP_MINFO(apc),
-+ PHP_APC_VERSION,
-+ STANDARD_MODULE_PROPERTIES
-+};
-+
-+#ifdef COMPILE_DL_APC
-+ZEND_GET_MODULE(apc)
-+#endif
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/php_apc.h b/ext/apc/php_apc.h
---- a/ext/apc/php_apc.h 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/php_apc.h 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,54 @@
-+/*
-+ +----------------------------------------------------------------------+
-+ | APC |
-+ +----------------------------------------------------------------------+
-+ | Copyright (c) 2006-2011 The PHP Group |
-+ +----------------------------------------------------------------------+
-+ | This source file is subject to version 3.01 of the PHP license, |
-+ | that is bundled with this package in the file LICENSE, and is |
-+ | available through the world-wide-web at the following url: |
-+ | http://www.php.net/license/3_01.txt |
-+ | If you did not receive a copy of the PHP license and are unable to |
-+ | obtain it through the world-wide-web, please send a note to |
-+ | license@php.net so we can mail you a copy immediately. |
-+ +----------------------------------------------------------------------+
-+ | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
-+ | George Schlossnagle <george@omniti.com> |
-+ | Rasmus Lerdorf <rasmus@php.net> |
-+ +----------------------------------------------------------------------+
-+
-+ This software was contributed to PHP by Community Connect Inc. in 2002
-+ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-+ Future revisions and derivatives of this source code must acknowledge
-+ Community Connect Inc. as the original contributor of this module by
-+ leaving this note intact in the source code.
-+
-+ All other licensing and usage conditions are those of the PHP Group.
-+
-+ */
-+
-+/* $Id: php_apc.h 326713 2012-07-19 22:07:31Z rasmus $ */
-+
-+#ifndef PHP_APC_H
-+#define PHP_APC_H
-+
-+#include "apc_php.h"
-+#include "apc_globals.h"
-+
-+#define PHP_APC_VERSION "3.1.11"
-+
-+extern zend_module_entry apc_module_entry;
-+#define apc_module_ptr &apc_module_entry
-+
-+#define phpext_apc_ptr apc_module_ptr
-+
-+#endif /* PHP_APC_H */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
-+ * vim<600: expandtab sw=4 ts=4 sts=4
-+ */
-diff -Naur a/ext/apc/TECHNOTES.txt b/ext/apc/TECHNOTES.txt
---- a/ext/apc/TECHNOTES.txt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/TECHNOTES.txt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,361 @@
-+APC Quick-Start Braindump
-+
-+This is a rapidly written braindump of how APC currently works in the
-+form of a quick-start guide to start hacking on APC.
-+
-+1. Install and use APC a bit so you know what it does from the end-user's
-+ perspective.
-+ user-space functions are all explained here:
-+
-+2. Grab the current APC code from CVS:
-+
-+ cvs -d:pserver:cvsread@cvs.php.net:/repository login
-+ Password: phpfi
-+ cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/apc
-+
-+ apc/php_apc.c has most of the code for the user-visible stuff. It is
-+ also a regular PHP extension in the sense that there are MINIT, MINFO,
-+ MSHUTDOWN, RSHUTDOWN, etc. functions.
-+
-+3. Build it.
-+
-+ cd pecl/apc
-+ phpize
-+ ./configure --enable-apc --enable-mmap
-+ make
-+ cp modules/apc.so /usr/local/lib/php
-+ apachectl restart
-+
-+4. Debugging Hints
-+
-+ apachectl stop
-+ gdb /usr/bin/httpd
-+ break ??
-+ run -X
-+
-+ Grab the .gdbinit from the PHP source tree and have a look at the macros.
-+
-+5. Look through apc/apc_sma.c
-+ It is a pretty standard memory allocator.
-+
-+ apc_sma_malloc, apc_sma_realloc, apc_sma_strdup and apc_sma_free behave to the
-+ caller just like malloc, realloc, strdup and free
-+
-+ On server startup the MINIT hook in php_apc.c calls apc_module_init() in
-+ apc_main.c which in turn calls apc_sma_init(). apc_sma_init calls into
-+ apc_mmap.c to mmap the specified sized segment (I tend to just use a single
-+ segment). apc_mmap.c should be self-explanatory. It mmaps a temp file and
-+ then unlinks that file right after the mmap to provide automatic shared memory
-+ cleanup in case the process dies.
-+
-+ Once the region has been initialized we stick a header_t at the beginning
-+ of the region. It contains the total size in header->segsize and the number
-+ of bytes available in header->avail.
-+
-+ After the header comes a bit of a hack. A zero-sized block is inserted just
-+ to make things easier later on. And then a huge block that is basically
-+ the size of the entire segment minus the two (for the 0-sized block, and this one)
-+ block headers.
-+
-+ The code for this is:
-+
-+ header = (header_t*) shmaddr;
-+ header->segsize = sma_segsize;
-+ header->avail = sma_segsize - sizeof(header_t) - sizeof(block_t) - alignword(sizeof(int));
-+ memset(&header->lock,0,sizeof(header->lock));
-+ sma_lock = &header->lock;
-+ block = BLOCKAT(sizeof(header_t));
-+ block->size = 0;
-+ block->next = sizeof(header_t) + sizeof(block_t);
-+ block = BLOCKAT(block->next);
-+ block->size = header->avail;
-+ block->next = 0;
-+
-+ So the shared memory looks like this:
-+
-+ +--------+-------+---------------------------------+
-+ | header | block | block |
-+ +--------+-------+---------------------------------+
-+
-+ sma_shmaddrs[0] gives you the address of header
-+
-+ The blocks are just a simple offset-based linked list (so no pointers):
-+
-+ typedef struct block_t block_t;
-+ struct block_t {
-+ size_t size; /* size of this block */
-+ size_t next; /* offset in segment of next free block */
-+ size_t canary; /* canary to check for memory overwrites */
-+#ifdef __APC_SMA_DEBUG__
-+ int id; /* identifier for the memory block */
-+#endif
-+ };
-+
-+ The BLOCKAT macro turns an offset into an actual address for you:
-+
-+ #define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset))
-+
-+ where shmaddr = sma_shaddrs[0]
-+
-+ And the OFFSET macro goes the other way:
-+
-+ #define OFFSET(block) ((int)(((char*)block) - (char*)shmaddr))
-+
-+ Allocating a block with a call to apc_sma_allocate() walks through the
-+ linked list of blocks until it finds one that is >= to the requested size.
-+ The first call to apc_sma_allocate() will hit the second block. We then
-+ chop up that block so it looks like this:
-+
-+ +--------+-------+-------+-------------------------+
-+ | header | block | block | block |
-+ +--------+-------+-------+-------------------------+
-+
-+ Then we unlink that block from the linked list so it won't show up
-+ as an available block on the next allocate. So we actually have:
-+
-+ +--------+-------+ +-------------------------+
-+ | header | block |------>| block |
-+ +--------+-------+ +-------------------------+
-+
-+ And header->avail along with block->size of the remaining large
-+ block are updated accordingly. The arrow there representing the
-+ link which now points to a block with an offset further along in
-+ the segment.
-+
-+ When the block is freed using apc_sma_deallocate() the steps are
-+ basically just reversed. The block is put back and then the deallocate
-+ code looks at the block before and after to see if the block immediately
-+ before and after are free and if so the blocks are combined. So you never
-+ have 2 free blocks next to each other, apart from at the front with that
-+ 0-sized dummy block. This mostly prevents fragmentation. I have been
-+ toying with the idea of always allocating block at 2^n boundaries to make
-+ it more likely that they will be re-used to cut down on fragmentation further.
-+ That's what the POWER_OF_TWO_BLOCKSIZE you see in apc_sma.c is all about.
-+
-+ Of course, anytime we fiddle with our shared memory segment we lock using
-+ the locking macros, LOCK() and UNLOCK().
-+
-+ That should mostly take care of the low-level shared memory handling.
-+
-+6. Next up is apc_main.c and apc_cache.c which implement the meat of the
-+ cache logic.
-+
-+ The apc_main.c file mostly calls functions in apc_sma.c to allocate memory
-+ and apc_cache.c for actual cache manipulation.
-+
-+ After the shared memory segment is created and the caches are initialized,
-+ apc_module_init() installs the my_compile_file() function overriding Zend's
-+ version. I'll talk about my_compile_file() and the rest of apc_compile.c
-+ in the next section. For now I will stick with apc_main.c and apc_cache.c
-+ and talk about the actual caches. A cache consists of a block of shared
-+ memory returned by apc_sma_allocate() via apc_sma_malloc(). You will
-+ notice references to apc_emalloc(). apc_emalloc() is just a thin wrapper
-+ around PHP's own emalloc() function which allocates per-process memory from
-+ PHP's pool-based memory allocator. Don't confuse apc_emalloc() and
-+ apc_sma_malloc() as the first is per-process and the second is shared memory.
-+
-+ The cache is stored in/described by this struct allocated locally using
-+ emalloc():
-+
-+ struct apc_cache_t {
-+ void* shmaddr; /* process (local) address of shared cache */
-+ header_t* header; /* cache header (stored in SHM) */
-+ slot_t** slots; /* array of cache slots (stored in SHM) */
-+ int num_slots; /* number of slots in cache */
-+ int gc_ttl; /* maximum time on GC list for a slot */
-+ int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */
-+ };
-+
-+ Whenever you see functions that take a 'cache' argument, this is what they
-+ take. And apc_cache_create() returns a pointer to this populated struct.
-+
-+ At the beginning of the cache we have a header. Remember, we are down a level now
-+ from the sma stuff. The sma stuff is the low-level shared-memory allocator which
-+ has its own header which is completely separate and invisible to apc_cache.c.
-+ As far as apc_cache.c is concerned the block of memory it is working with could
-+ have come from a call to malloc().
-+
-+ The header looks like this:
-+
-+ typedef struct header_t header_t;
-+ struct header_t {
-+ int num_hits; /* total successful hits in cache */
-+ int num_misses; /* total unsuccessful hits in cache */
-+ slot_t* deleted_list; /* linked list of to-be-deleted slots */
-+ };
-+
-+ Since this is at the start of the shared memory segment, these values are accessible
-+ across all the apache processes and hence access to them has to be locked.
-+
-+ After the header we have an array of slots. The number of slots is user-defined
-+ through the apc.num_slots ini hint. Each slot is described by:
-+
-+ typedef struct slot_t slot_t;
-+ struct slot_t {
-+ apc_cache_key_t key; /* slot key */
-+ apc_cache_entry_t* value; /* slot value */
-+ slot_t* next; /* next slot in linked list */
-+ int num_hits; /* number of hits to this bucket */
-+ time_t creation_time; /* time slot was initialized */
-+ time_t deletion_time; /* time slot was removed from cache */
-+ time_t access_time; /* time slot was last accessed */
-+ };
-+
-+ The slot_t *next there is a linked list to other slots that happened to hash to the
-+ same array position.
-+
-+ apc_cache_insert() shows what happens on a new cache insert.
-+
-+ slot = &cache->slots[hash(key) % cache->num_slots];
-+
-+ cache->slots is our array of slots in the segment. hash() is simply:
-+
-+ static unsigned int hash(apc_cache_key_t key)
-+ {
-+ return key.data.file.device + key.data.file.inode;
-+ }
-+
-+ That is, we use the file's device and inode to uniquely identify it. Initially
-+ we had used the file's full path, but getting that requires a realpath() call which
-+ is amazingly expensive since it has to stat each component of the path to resolve
-+ symlinks and get rid of relative path components. By using the device+inode we
-+ can uniquely identify a file with a single stat.
-+
-+ So, on an insert we find the array position in the slots array by hashing the device+inode.
-+ If there are currently no other slots there, we just create the slot and stick it into
-+ the array:
-+
-+ *slot = make_slot(key, value, *slot, t)
-+
-+ If there are other slots already at this position we walk the link list to get to
-+ the end. Here is the loop:
-+
-+ while (*slot) {
-+ if (key_equals((*slot)->key.data.file, key.data.file)) {
-+ /* If existing slot for the same device+inode is different, remove it and insert the new version */
-+ if ((*slot)->key.mtime != key.mtime) {
-+ remove_slot(cache, slot);
-+ break;
-+ }
-+ UNLOCK(cache);
-+ return 0;
-+ } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
-+ remove_slot(cache, slot);
-+ continue;
-+ }
-+ slot = &(*slot)->next;
-+ }
-+
-+ That first key_equals() check sees if we have an exact match meaning the file
-+ is already in the cache. Since we try to find the file in the cache before doing
-+ an insert, this will generally only happen if another process managed to beat us
-+ to inserting it. If we have a newer version of the file at this point we remove
-+ it an insert the new version. If our version is not newer we just return without
-+ doing anything.
-+
-+ While walking the linked list we also check to see if the cache has a TTL defined.
-+ If while walking the linked list we see a slot that has expired, we remove it
-+ since we are right there looking at it. This is the only place we remove stale
-+ entries unless the shared memory segment fills up and we force a full expunge via
-+ apc_cache_expunge(). apc_cache_expunge() walks the entire slots array and walks
-+ down every linked list removing stale slots to free up room. This is obviously
-+ slow and thus only happens when we have run out of room.
-+
-+ apc_cache_find() simply hashes and returns the entry if it is there. If it is there
-+ but older than the mtime in the entry we are looking for, we delete the one that is
-+ there and return indicating we didn't find it.
-+
-+ Next we need to understand what an actual cache entry looks like. Have a look at
-+ apc_cache.h for the structs. I sort of glossed over the key part earlier saying
-+ that we just used the device+inode to find a hash slot. It is actually a bit more
-+ complex than that because we have two kinds of caches. We have the standard file
-+ cache containing opcode arrays, but we also have a user-controlled cache that the
-+ user can insert whatever they want into via apc_store(). For the user cache we
-+ obviously don't have a device+inode. The actual identifier is provided by the user
-+ as a char *. So the key is actually a union that looks like this:
-+
-+ typedef union _apc_cache_key_data_t {
-+ struct {
-+ int device; /* the filesystem device */
-+ int inode; /* the filesystem inode */
-+ } file;
-+ struct {
-+ char *identifier;
-+ } user;
-+ } apc_cache_key_data_t;
-+
-+ struct apc_cache_key_t {
-+ apc_cache_key_data_t data;
-+ int mtime; /* the mtime of this cached entry */
-+ };
-+
-+ And we have two sets of functions to do inserts and finds. apc_cache_user_find()
-+ and apc_cache_user_insert() operate on the user cache.
-+
-+ Ok, on to the actual cache entry. Again, because we have two kinds of caches, we
-+ also have the corresponding two kinds of cache entries described by this union:
-+
-+ typedef union _apc_cache_entry_value_t {
-+ struct {
-+ char *filename; /* absolute path to source file */
-+ zend_op_array* op_array; /* op_array allocated in shared memory */
-+ apc_function_t* functions; /* array of apc_function_t's */
-+ apc_class_t* classes; /* array of apc_class_t's */
-+ } file;
-+ struct {
-+ char *info;
-+ zval *val;
-+ unsigned int ttl;
-+ } user;
-+ } apc_cache_entry_value_t;
-+
-+ And then the actual cache entry:
-+
-+ struct apc_cache_entry_t {
-+ apc_cache_entry_value_t data;
-+ unsigned char type;
-+ int ref_count;
-+ };
-+
-+ The user entry is pretty simple and not all that important for now. I will
-+ concentrate on the file entries since that is what holds the actual compiled
-+ opcode arrays along with the functions and classes required by the executor.
-+
-+ apc_cache_make_file_entry() in apc_cache.c shows how an entry is constructed.
-+ The main thing to understand here is that we need more than just the opcode
-+ array, we also need the functions and classes created by the compiler when it
-+ created the opcode array. As far as the executor is concerned, it doesn't know
-+ that it isn't operating in normal mode being called right after the parse/compile
-+ phase, so we need to recreate everything so it looks exactly like it would at
-+ that point.
-+
-+7. my_compile_file() and apc_compile.c
-+
-+ my_compile_file() in apc_main.c controls where we get the opcodes from. If
-+ the user-specified filters exclude the file from being cached, then we just
-+ call the original compile function and return. Otherwise we fetch the request
-+ time from Apache to avoid an extra syscall, create the key so we can look up
-+ the file in the cache. If we find it we stick it on a local stack which we
-+ use at cleanup time to make sure we return everything back to normal after a
-+ request and call cached_compile() which installs the functions and classes
-+ associated with the op_array in this entry and then copy the op_array down
-+ into our memory space for execution.
-+
-+ If we didn't find the file in the cache, we need to compile it and insert it.
-+ To compile it we simply call the original compile function:
-+
-+ op_array = old_compile_file(h, type TSRMLS_CC);
-+
-+ To do the insert we need to copy the functions, classes and the opcode array
-+ the compile phase created into shared memory. This all happens in apc_compile.c
-+ in the apc_copy_op_array(), apc_copy_new_functions() and apc_copy_new_classes()
-+ functions. Then we make the file entry and do the insert. Both of these
-+ operations were described in the previous section.
-+
-+8. The Optimizer
-+
-+ The optimizer has been deprecated.
-+
-+If you made it to the end of this, you should have a pretty good idea of where things are in
-+the code. I skimmed over a lot of things, so plan on spending some time reading through the code.
-+
-diff -Naur a/ext/apc/tests/apc_001.phpt b/ext/apc/tests/apc_001.phpt
---- a/ext/apc/tests/apc_001.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_001.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,32 @@
-+--TEST--
-+APC: apc_store/fetch with strings
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$foo = 'hello world';
-+var_dump($foo);
-+apc_store('foo',$foo);
-+$bar = apc_fetch('foo');
-+var_dump($bar);
-+$bar = 'nice';
-+var_dump($bar);
-+
-+apc_store('foo\x00bar', $foo);
-+$bar = apc_fetch('foo\x00bar');
-+var_dump($bar);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+string(11) "hello world"
-+string(11) "hello world"
-+string(4) "nice"
-+string(11) "hello world"
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_002.phpt b/ext/apc/tests/apc_002.phpt
---- a/ext/apc/tests/apc_002.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_002.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,34 @@
-+--TEST--
-+APC: apc_store/fetch with objects
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+class foo { }
-+$foo = new foo;
-+var_dump($foo);
-+apc_store('foo',$foo);
-+unset($foo);
-+$bar = apc_fetch('foo');
-+var_dump($bar);
-+$bar->a = true;
-+var_dump($bar);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (1) {
-+ ["a"]=>
-+ bool(true)
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_003b.phpt b/ext/apc/tests/apc_003b.phpt
---- a/ext/apc/tests/apc_003b.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_003b.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,117 @@
-+--TEST--
-+APC: apc_store/fetch with objects (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+class foo { }
-+$foo = new foo;
-+var_dump($foo);
-+apc_store('foo',$foo);
-+unset($foo);
-+$bar = apc_fetch('foo');
-+var_dump($bar);
-+$bar->a = true;
-+var_dump($bar);
-+
-+class bar extends foo
-+{
-+ public $pub = 'bar';
-+ protected $pro = 'bar';
-+ private $pri = 'bar'; // we don't see this, we'd need php 5.1 new serialization
-+
-+ function __construct()
-+ {
-+ $this->bar = true;
-+ }
-+
-+ function change()
-+ {
-+ $this->pri = 'mod';
-+ }
-+}
-+
-+class baz extends bar
-+{
-+ private $pri = 'baz';
-+
-+ function __construct()
-+ {
-+ parent::__construct();
-+ $this->baz = true;
-+ }
-+}
-+
-+$baz = new baz;
-+var_dump($baz);
-+$baz->change();
-+var_dump($baz);
-+apc_store('baz', $baz);
-+unset($baz);
-+var_dump(apc_fetch('baz'));
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (1) {
-+ ["a"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri":"baz":private]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro":protected]=>
-+ string(3) "bar"
-+ ["pri":"bar":private]=>
-+ string(3) "bar"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri":"baz":private]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro":protected]=>
-+ string(3) "bar"
-+ ["pri":"bar":private]=>
-+ string(3) "mod"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri":"baz":private]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro":protected]=>
-+ string(3) "bar"
-+ ["pri":"bar":private]=>
-+ string(3) "mod"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_003.phpt b/ext/apc/tests/apc_003.phpt
---- a/ext/apc/tests/apc_003.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_003.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,117 @@
-+--TEST--
-+APC: apc_store/fetch with objects (php pre-5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') >= 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+class foo { }
-+$foo = new foo;
-+var_dump($foo);
-+apc_store('foo',$foo);
-+unset($foo);
-+$bar = apc_fetch('foo');
-+var_dump($bar);
-+$bar->a = true;
-+var_dump($bar);
-+
-+class bar extends foo
-+{
-+ public $pub = 'bar';
-+ protected $pro = 'bar';
-+ private $pri = 'bar'; // we don't see this, we'd need php 5.1 new serialization
-+
-+ function __construct()
-+ {
-+ $this->bar = true;
-+ }
-+
-+ function change()
-+ {
-+ $this->pri = 'mod';
-+ }
-+}
-+
-+class baz extends bar
-+{
-+ private $pri = 'baz';
-+
-+ function __construct()
-+ {
-+ parent::__construct();
-+ $this->baz = true;
-+ }
-+}
-+
-+$baz = new baz;
-+var_dump($baz);
-+$baz->change();
-+var_dump($baz);
-+apc_store('baz', $baz);
-+unset($baz);
-+var_dump(apc_fetch('baz'));
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (0) {
-+}
-+object(foo)#%d (1) {
-+ ["a"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri:private"]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro:protected"]=>
-+ string(3) "bar"
-+ ["pri:private"]=>
-+ string(3) "bar"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri:private"]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro:protected"]=>
-+ string(3) "bar"
-+ ["pri:private"]=>
-+ string(3) "mod"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+object(baz)#%d (6) {
-+ ["pri:private"]=>
-+ string(3) "baz"
-+ ["pub"]=>
-+ string(3) "bar"
-+ ["pro:protected"]=>
-+ string(3) "bar"
-+ ["pri:private"]=>
-+ string(3) "mod"
-+ ["bar"]=>
-+ bool(true)
-+ ["baz"]=>
-+ bool(true)
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_004.phpt b/ext/apc/tests/apc_004.phpt
---- a/ext/apc/tests/apc_004.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_004.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,38 @@
-+--TEST--
-+APC: apc_store/fetch with bools
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$foo = false;
-+var_dump($foo); /* false */
-+apc_store('foo',$foo);
-+//$success = "some string";
-+
-+$bar = apc_fetch('foo', $success);
-+var_dump($foo); /* false */
-+var_dump($bar); /* false */
-+var_dump($success); /* true */
-+
-+$bar = apc_fetch('not foo', $success);
-+var_dump($foo); /* false */
-+var_dump($bar); /* false */
-+var_dump($success); /* false */
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(true)
-+bool(false)
-+bool(false)
-+bool(false)
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_005.phpt b/ext/apc/tests/apc_005.phpt
---- a/ext/apc/tests/apc_005.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_005.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,50 @@
-+--TEST--
-+APC: apc_store/fetch with arrays of objects
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$foo = array(new stdclass(), new stdclass());
-+
-+var_dump($foo);
-+
-+apc_store('foo',$foo);
-+
-+$bar = apc_fetch('foo');
-+var_dump($foo);
-+var_dump($bar);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+array(2) {
-+ [0]=>
-+ object(stdClass)#1 (0) {
-+ }
-+ [1]=>
-+ object(stdClass)#2 (0) {
-+ }
-+}
-+array(2) {
-+ [0]=>
-+ object(stdClass)#1 (0) {
-+ }
-+ [1]=>
-+ object(stdClass)#2 (0) {
-+ }
-+}
-+array(2) {
-+ [0]=>
-+ object(stdClass)#3 (0) {
-+ }
-+ [1]=>
-+ object(stdClass)#4 (0) {
-+ }
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_006.phpt b/ext/apc/tests/apc_006.phpt
---- a/ext/apc/tests/apc_006.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_006.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,73 @@
-+--TEST--
-+APC: apc_store/fetch reference test
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+apc.serializer=default
-+report_memleaks=0
-+--FILE--
-+<?php
-+
-+$a = 'a';
-+$b = array($a);
-+$c = array('c');
-+$b[] = &$c;
-+$b[] = &$c;
-+$d = 'd';
-+$b[] = &$d;
-+$b[] = &$d;
-+$b[] = &$d;
-+$e = 'e';
-+$b[] = $e;
-+$b[] = $e;
-+$f = array('f');
-+$f[] = &$f;
-+$b[] = &$f;
-+apc_store('test', $b);
-+$x = apc_fetch('test');
-+debug_zval_dump($x);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+array(9) refcount(2){
-+ [0]=>
-+ string(1) "a" refcount(1)
-+ [1]=>
-+ &array(1) refcount(2){
-+ [0]=>
-+ string(1) "c" refcount(1)
-+ }
-+ [2]=>
-+ &array(1) refcount(2){
-+ [0]=>
-+ string(1) "c" refcount(1)
-+ }
-+ [3]=>
-+ &string(1) "d" refcount(3)
-+ [4]=>
-+ &string(1) "d" refcount(3)
-+ [5]=>
-+ &string(1) "d" refcount(3)
-+ [6]=>
-+ string(1) "e" refcount(2)
-+ [7]=>
-+ string(1) "e" refcount(2)
-+ [8]=>
-+ &array(2) refcount(2){
-+ [0]=>
-+ string(1) "f" refcount(1)
-+ [1]=>
-+ &array(2) refcount(2){
-+ [0]=>
-+ string(1) "f" refcount(1)
-+ [1]=>
-+ *RECURSION*
-+ }
-+ }
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_007.phpt b/ext/apc/tests/apc_007.phpt
---- a/ext/apc/tests/apc_007.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_007.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,46 @@
-+--TEST--
-+APC: apc_inc/apc_dec test
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+apc_store('foobar',2);
-+echo "\$foobar = 2 \n";
-+echo "\$foobar += 1 = ".apc_inc('foobar')."\n";
-+echo "\$foobar += 10 = ".apc_inc('foobar', 10)."\n";
-+
-+echo "\$foobar -= 1 = ".apc_dec('foobar')."\n";
-+echo "\$foobar -= 10 = ".apc_dec('foobar',10)."\n";
-+
-+echo "\$f__bar += 1 = ".(apc_inc('f__bar')?"ok":"fail")."\n";
-+
-+apc_store('perfection', "xyz");
-+echo "\$perfection -= 1 = ".(apc_inc('perfection')?"ok":"epic fail")."\n";
-+
-+$success = false;
-+
-+echo "\$foobar += 1 = ".apc_inc('foobar', 1, $success)."\n";
-+echo "pass by ref success ". $success . "\n";
-+echo "\$foobar -= 1 = ".apc_dec('foobar', 1, $success)."\n";
-+echo "pass by ref success ". $success . "\n";
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+$foobar = 2
-+$foobar += 1 = 3
-+$foobar += 10 = 13
-+$foobar -= 1 = 12
-+$foobar -= 10 = 2
-+$f__bar += 1 = fail
-+$perfection -= 1 = epic fail
-+$foobar += 1 = 3
-+pass by ref success 1
-+$foobar -= 1 = 2
-+pass by ref success 1
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_008.phpt b/ext/apc/tests/apc_008.phpt
---- a/ext/apc/tests/apc_008.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_008.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,34 @@
-+--TEST--
-+APC: apc_cas test
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+apc_store('foobar',2);
-+echo "\$foobar = 2\n";
-+echo "\$foobar == 1 ? 2 : 1 = ".(apc_cas('foobar', 1, 2)?"ok":"fail")."\n";
-+echo "\$foobar == 2 ? 1 : 2 = ".(apc_cas('foobar', 2, 1)?"ok":"fail")."\n";
-+echo "\$foobar = ".apc_fetch("foobar")."\n";
-+
-+echo "\$f__bar == 1 ? 2 : 1 = ".(apc_cas('f__bar', 1, 2)?"ok":"fail")."\n";
-+
-+apc_store('perfection', "xyz");
-+echo "\$perfection == 2 ? 1 : 2 = ".(apc_cas('perfection', 2, 1)?"ok":"epic fail")."\n";
-+
-+echo "\$foobar = ".apc_fetch("foobar")."\n";
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+$foobar = 2
-+$foobar == 1 ? 2 : 1 = fail
-+$foobar == 2 ? 1 : 2 = ok
-+$foobar = 1
-+$f__bar == 1 ? 2 : 1 = fail
-+$perfection == 2 ? 1 : 2 = epic fail
-+$foobar = 1
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_009.phpt b/ext/apc/tests/apc_009.phpt
---- a/ext/apc/tests/apc_009.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_009.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,97 @@
-+--TEST--
-+APC: apc_delete_file test
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+apc.stat=On
-+report_memleaks=0
-+--FILE--
-+<?php
-+
-+$files = array( 'apc_009.php',
-+ 'apc_009-1.php',
-+ 'apc_009-2.php',
-+ 'nofile.php',
-+ );
-+
-+file_put_contents(dirname(__FILE__).'/apc_009-1.php', '<?php echo "test file";');
-+file_put_contents(dirname(__FILE__).'/apc_009-2.php', '<?php syntaxerrorhere!');
-+
-+apc_compile_file($files[0]);
-+check_file($files[0]);
-+apc_delete_file($files[0]);
-+check_file($files[0]);
-+
-+apc_compile_file($files[0]);
-+apc_delete_file(array($files[0]));
-+check_file($files[0]);
-+
-+apc_compile_file($files[0]);
-+$it = new APCIterator('file');
-+apc_delete_file($it);
-+check_file($files[0]);
-+
-+var_dump(apc_compile_file(array($files[0], $files[1])));
-+check_file(array($files[0], $files[1]));
-+
-+var_dump(apc_compile_file($files));
-+check_file($files);
-+
-+function check_file($files) {
-+
-+ if (!is_array($files)) {
-+ $files = array($files);
-+ }
-+
-+ $info = apc_cache_info('file');
-+
-+ foreach ($files as $file) {
-+ $match = 0;
-+ foreach($info['cache_list'] as $cached_file) {
-+ if (stristr($cached_file['filename'], $file)) $match = 1;
-+ }
-+ if ($match) {
-+ echo "$file Found File\n";
-+ } else {
-+ echo "$file Not Found\n";
-+ }
-+ }
-+}
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--CLEAN--
-+<?php
-+unlink('apc_009-1.php');
-+unlink('apc_009-2.php');
-+?>
-+--EXPECTF--
-+apc_009.php Found File
-+apc_009.php Not Found
-+apc_009.php Not Found
-+apc_009.php Not Found
-+array(0) {
-+}
-+apc_009.php Found File
-+apc_009-1.php Found File
-+
-+Parse error: syntax error, unexpected '!' in %s/apc_009-2.php on line 1
-+
-+Warning: apc_compile_file(): Error compiling apc_009-2.php in apc_compile_file. in %s/apc_009.php on line 29
-+
-+Warning: apc_compile_file(): Error compiling nofile.php in apc_compile_file. in %s/apc_009.php on line 29
-+array(2) {
-+ ["apc_009-2.php"]=>
-+ int(-1)
-+ ["nofile.php"]=>
-+ int(-1)
-+}
-+apc_009.php Found File
-+apc_009-1.php Found File
-+apc_009-2.php Not Found
-+nofile.php Not Found
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_010.phpt b/ext/apc/tests/apc_010.phpt
---- a/ext/apc/tests/apc_010.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_010.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,83 @@
-+--TEST--
-+APC: apc_store/fetch/add with array of key/value pairs.
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$entries = array();
-+$entries['key1'] = 'value1';
-+$entries['key2'] = 'value2';
-+$entries['key3'] = array('value3a','value3b');
-+$entries['key4'] = 4;
-+
-+var_dump(apc_store($entries));
-+$cached_values = apc_fetch(array_keys($entries));
-+var_dump($cached_values);
-+
-+apc_delete('key2');
-+apc_delete('key4');
-+$cached_values = apc_fetch(array_keys($entries));
-+var_dump($cached_values);
-+var_dump(apc_add($entries));
-+$cached_values = apc_fetch(array_keys($entries));
-+var_dump($cached_values);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+array(0) {
-+}
-+array(4) {
-+ ["key1"]=>
-+ string(6) "value1"
-+ ["key2"]=>
-+ string(6) "value2"
-+ ["key3"]=>
-+ array(2) {
-+ [0]=>
-+ string(7) "value3a"
-+ [1]=>
-+ string(7) "value3b"
-+ }
-+ ["key4"]=>
-+ int(4)
-+}
-+array(2) {
-+ ["key1"]=>
-+ string(6) "value1"
-+ ["key3"]=>
-+ array(2) {
-+ [0]=>
-+ string(7) "value3a"
-+ [1]=>
-+ string(7) "value3b"
-+ }
-+}
-+array(2) {
-+ ["key1"]=>
-+ int(-1)
-+ ["key3"]=>
-+ int(-1)
-+}
-+array(4) {
-+ ["key1"]=>
-+ string(6) "value1"
-+ ["key2"]=>
-+ string(6) "value2"
-+ ["key3"]=>
-+ array(2) {
-+ [0]=>
-+ string(7) "value3a"
-+ [1]=>
-+ string(7) "value3b"
-+ }
-+ ["key4"]=>
-+ int(4)
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc53_001.phpt b/ext/apc/tests/apc53_001.phpt
---- a/ext/apc/tests/apc53_001.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc53_001.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,33 @@
-+--TEST--
-+APC: classes with namespaces (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+require_once(dirname(__FILE__) . '/php_5_3_ns.inc');
-+
-+$a = new Foo\Bar\Baz();
-+var_dump($a);
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+object(Foo\Bar\Baz)#1 (3) {
-+ ["i"]=>
-+ int(1)
-+ ["f":protected]=>
-+ float(3.14)
-+ ["s":"Foo\Bar\Baz":private]=>
-+ string(11) "hello world"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/apc53_002.phpt b/ext/apc/tests/apc53_002.phpt
---- a/ext/apc/tests/apc53_002.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc53_002.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,47 @@
-+--TEST--
-+APC: global spaces (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+require_once(dirname(__FILE__) . '/php_5_3_ns.inc');
-+
-+$a = new Foo\Bar\Baz();
-+$a->foo();
-+var_dump(Foo\Bar\sort());
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+array(4) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ [3]=>
-+ int(4)
-+}
-+array(4) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ [3]=>
-+ int(4)
-+}
-+string(8) "IT WORKS"
-+===DONE===
-diff -Naur a/ext/apc/tests/apc53_003.phpt b/ext/apc/tests/apc53_003.phpt
---- a/ext/apc/tests/apc53_003.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc53_003.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,31 @@
-+--TEST--
-+APC: anonymous functions (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$greet = function($name)
-+{
-+ printf("Hello %s\r\n", $name);
-+};
-+
-+$greet('World');
-+$greet('PHP');
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+Hello World
-+Hello PHP
-+===DONE===
-diff -Naur a/ext/apc/tests/apc53_004.phpt b/ext/apc/tests/apc53_004.phpt
---- a/ext/apc/tests/apc53_004.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc53_004.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,33 @@
-+--TEST--
-+APC: closures (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+function multiplier($n) {
-+ return function($i) use ($n) {
-+ return $n * $i;
-+ };
-+}
-+
-+$doubler = multiplier(2);
-+$tripler = multiplier(3);
-+
-+echo "double of 9 is ".$doubler(9)."\n";
-+echo "triple of 4 is ".$tripler(4)."\n";
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+double of 9 is 18
-+triple of 4 is 12
-+===DONE===
-diff -Naur a/ext/apc/tests/apc53_005.phpt b/ext/apc/tests/apc53_005.phpt
---- a/ext/apc/tests/apc53_005.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc53_005.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,35 @@
-+--TEST--
-+APC: goto (php 5.3)
-+--SKIPIF--
-+<?php
-+ require_once(dirname(__FILE__) . '/skipif.inc');
-+ if(version_compare(zend_version(), '2.3.0') < 0) {
-+ echo "skip\n";
-+ }
-+?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$i = 0;
-+a:
-+$i++;
-+if($i % 3 == 0) goto b;
-+echo "$i\n";
-+b:
-+if($i < 10) goto a;
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+1
-+2
-+4
-+5
-+7
-+8
-+10
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_bin_001.phpt b/ext/apc/tests/apc_bin_001.phpt
---- a/ext/apc/tests/apc_bin_001.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_bin_001.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,24 @@
-+--TEST--
-+APC: bindump user cache
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+--FILE--
-+<?php
-+apc_clear_cache('file');
-+apc_store('testkey','testvalue');
-+apc_bin_dump();
-+$dump = apc_bin_dump(array(), NULL);
-+apc_clear_cache('user');
-+var_dump(apc_fetch('testkey'));
-+apc_bin_load($dump, APC_BIN_VERIFY_MD5 | APC_BIN_VERIFY_CRC32);
-+var_dump(apc_fetch('testkey'));
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+bool(false)
-+string(9) "testvalue"
-+===DONE===
-diff -Naur a/ext/apc/tests/apc_bin_002-1.inc b/ext/apc/tests/apc_bin_002-1.inc
---- a/ext/apc/tests/apc_bin_002-1.inc 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_bin_002-1.inc 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,42 @@
-+<?php
-+
-+$my_class = New my_class();
-+$my_i_class = New my_i_class();
-+
-+echo "apc bindump 002 test\n";
-+echo "\n";
-+echo "global scope execution: Success\n";
-+echo "\n";
-+echo "function execution: ".my_function()."\n";
-+echo "\n";
-+
-+echo "class static method: ".my_class::my_static_method()."\n";
-+echo "class dynamic method: ".$my_class->my_method()."\n";
-+echo "class static property: ".my_class::$my_static_property."\n";
-+echo "class dynamic property: ".$my_class->my_property."\n";
-+echo "class constant: ".my_class::my_constant."\n";
-+echo "\n";
-+echo "inherited class static method: ".my_i_class::my_static_method()."\n";
-+echo "inherited class dynamic method: ".$my_i_class->my_method()."\n";
-+echo "inherited class static property: ".my_i_class::$my_static_property."\n";
-+echo "inherited class dynamic property: ".$my_i_class->my_property."\n";
-+echo "inherited class constant: ".my_i_class::my_constant."\n";
-+echo "\n";
-+
-+
-+
-+function my_function() { return "Success"; }
-+
-+
-+class my_class {
-+ static $my_static_property = "Success";
-+ var $my_property = "Success";
-+ const my_constant = "Success";
-+ static function my_static_method() { return "Success"; }
-+ function my_method() { return "Success"; }
-+}
-+
-+class my_i_class extends my_class {
-+ function dummy() { return 1; }
-+}
-+
-diff -Naur a/ext/apc/tests/apc_bin_002-2.inc b/ext/apc/tests/apc_bin_002-2.inc
---- a/ext/apc/tests/apc_bin_002-2.inc 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_bin_002-2.inc 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,5 @@
-+<?php
-+
-+echo "Failed to use cached version!\n";
-+
-+?>
-diff -Naur a/ext/apc/tests/apc_bin_002.phpt b/ext/apc/tests/apc_bin_002.phpt
---- a/ext/apc/tests/apc_bin_002.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/apc_bin_002.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,53 @@
-+--TEST--
-+APC: bindump file cache part 1
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.stat=0
-+apc.cache_by_default=1
-+apc.filters=
-+report_memleaks = Off
-+--FILE--
-+<?php
-+
-+define('filename',dirname(__FILE__).'/apc_bin_002.inc');
-+define('filename1',dirname(__FILE__).'/apc_bin_002-1.inc');
-+define('filename2',dirname(__FILE__).'/apc_bin_002-2.inc');
-+
-+copy(filename1, filename);
-+apc_compile_file(filename);
-+$data = apc_bin_dump(NULL, NULL);
-+
-+apc_clear_cache();
-+
-+copy(filename2, filename);
-+apc_bin_load($data, APC_BIN_VERIFY_MD5 | APC_BIN_VERIFY_CRC32);
-+include(filename);
-+
-+unlink(filename);
-+
-+?>
-+===DONE===
-+<? php exit(0); ?>
-+--EXPECTF--
-+apc bindump 002 test
-+
-+global scope execution: Success
-+
-+function execution: Success
-+
-+class static method: Success
-+class dynamic method: Success
-+class static property: Success
-+class dynamic property: Success
-+class constant: Success
-+
-+inherited class static method: Success
-+inherited class dynamic method: Success
-+inherited class static property: Success
-+inherited class dynamic property: Success
-+inherited class constant: Success
-+
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_001.phpt b/ext/apc/tests/iterator_001.phpt
---- a/ext/apc/tests/iterator_001.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_001.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,110 @@
-+--TEST--
-+APC: APCIterator general
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$it = new APCIterator('user');
-+for($i = 0; $i < 41; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+foreach($it as $key=>$value) {
-+ $vals[$key] = $value['key'];
-+}
-+ksort($vals);
-+var_dump($vals);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECT--
-+array(41) {
-+ ["key0"]=>
-+ string(4) "key0"
-+ ["key1"]=>
-+ string(4) "key1"
-+ ["key10"]=>
-+ string(5) "key10"
-+ ["key11"]=>
-+ string(5) "key11"
-+ ["key12"]=>
-+ string(5) "key12"
-+ ["key13"]=>
-+ string(5) "key13"
-+ ["key14"]=>
-+ string(5) "key14"
-+ ["key15"]=>
-+ string(5) "key15"
-+ ["key16"]=>
-+ string(5) "key16"
-+ ["key17"]=>
-+ string(5) "key17"
-+ ["key18"]=>
-+ string(5) "key18"
-+ ["key19"]=>
-+ string(5) "key19"
-+ ["key2"]=>
-+ string(4) "key2"
-+ ["key20"]=>
-+ string(5) "key20"
-+ ["key21"]=>
-+ string(5) "key21"
-+ ["key22"]=>
-+ string(5) "key22"
-+ ["key23"]=>
-+ string(5) "key23"
-+ ["key24"]=>
-+ string(5) "key24"
-+ ["key25"]=>
-+ string(5) "key25"
-+ ["key26"]=>
-+ string(5) "key26"
-+ ["key27"]=>
-+ string(5) "key27"
-+ ["key28"]=>
-+ string(5) "key28"
-+ ["key29"]=>
-+ string(5) "key29"
-+ ["key3"]=>
-+ string(4) "key3"
-+ ["key30"]=>
-+ string(5) "key30"
-+ ["key31"]=>
-+ string(5) "key31"
-+ ["key32"]=>
-+ string(5) "key32"
-+ ["key33"]=>
-+ string(5) "key33"
-+ ["key34"]=>
-+ string(5) "key34"
-+ ["key35"]=>
-+ string(5) "key35"
-+ ["key36"]=>
-+ string(5) "key36"
-+ ["key37"]=>
-+ string(5) "key37"
-+ ["key38"]=>
-+ string(5) "key38"
-+ ["key39"]=>
-+ string(5) "key39"
-+ ["key4"]=>
-+ string(4) "key4"
-+ ["key40"]=>
-+ string(5) "key40"
-+ ["key5"]=>
-+ string(4) "key5"
-+ ["key6"]=>
-+ string(4) "key6"
-+ ["key7"]=>
-+ string(4) "key7"
-+ ["key8"]=>
-+ string(4) "key8"
-+ ["key9"]=>
-+ string(4) "key9"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_002.phpt b/ext/apc/tests/iterator_002.phpt
---- a/ext/apc/tests/iterator_002.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_002.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,36 @@
-+--TEST--
-+APC: APCIterator regex
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$it = new APCIterator('user', '/key[0-9]0/');
-+for($i = 0; $i < 41; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+foreach($it as $key=>$value) {
-+ $vals[$key] = $value['key'];
-+}
-+ksort($vals);
-+var_dump($vals);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECT--
-+array(4) {
-+ ["key10"]=>
-+ string(5) "key10"
-+ ["key20"]=>
-+ string(5) "key20"
-+ ["key30"]=>
-+ string(5) "key30"
-+ ["key40"]=>
-+ string(5) "key40"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_003.phpt b/ext/apc/tests/iterator_003.phpt
---- a/ext/apc/tests/iterator_003.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_003.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,110 @@
-+--TEST--
-+APC: APCIterator chunk size
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$it = new APCIterator('user', NULL, APC_ITER_ALL, 10);
-+for($i = 0; $i < 41; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+foreach($it as $key=>$value) {
-+ $vals[$key] = $value['key'];
-+}
-+ksort($vals);
-+var_dump($vals);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECT--
-+array(41) {
-+ ["key0"]=>
-+ string(4) "key0"
-+ ["key1"]=>
-+ string(4) "key1"
-+ ["key10"]=>
-+ string(5) "key10"
-+ ["key11"]=>
-+ string(5) "key11"
-+ ["key12"]=>
-+ string(5) "key12"
-+ ["key13"]=>
-+ string(5) "key13"
-+ ["key14"]=>
-+ string(5) "key14"
-+ ["key15"]=>
-+ string(5) "key15"
-+ ["key16"]=>
-+ string(5) "key16"
-+ ["key17"]=>
-+ string(5) "key17"
-+ ["key18"]=>
-+ string(5) "key18"
-+ ["key19"]=>
-+ string(5) "key19"
-+ ["key2"]=>
-+ string(4) "key2"
-+ ["key20"]=>
-+ string(5) "key20"
-+ ["key21"]=>
-+ string(5) "key21"
-+ ["key22"]=>
-+ string(5) "key22"
-+ ["key23"]=>
-+ string(5) "key23"
-+ ["key24"]=>
-+ string(5) "key24"
-+ ["key25"]=>
-+ string(5) "key25"
-+ ["key26"]=>
-+ string(5) "key26"
-+ ["key27"]=>
-+ string(5) "key27"
-+ ["key28"]=>
-+ string(5) "key28"
-+ ["key29"]=>
-+ string(5) "key29"
-+ ["key3"]=>
-+ string(4) "key3"
-+ ["key30"]=>
-+ string(5) "key30"
-+ ["key31"]=>
-+ string(5) "key31"
-+ ["key32"]=>
-+ string(5) "key32"
-+ ["key33"]=>
-+ string(5) "key33"
-+ ["key34"]=>
-+ string(5) "key34"
-+ ["key35"]=>
-+ string(5) "key35"
-+ ["key36"]=>
-+ string(5) "key36"
-+ ["key37"]=>
-+ string(5) "key37"
-+ ["key38"]=>
-+ string(5) "key38"
-+ ["key39"]=>
-+ string(5) "key39"
-+ ["key4"]=>
-+ string(4) "key4"
-+ ["key40"]=>
-+ string(5) "key40"
-+ ["key5"]=>
-+ string(4) "key5"
-+ ["key6"]=>
-+ string(4) "key6"
-+ ["key7"]=>
-+ string(4) "key7"
-+ ["key8"]=>
-+ string(4) "key8"
-+ ["key9"]=>
-+ string(4) "key9"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_004.phpt b/ext/apc/tests/iterator_004.phpt
---- a/ext/apc/tests/iterator_004.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_004.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,36 @@
-+--TEST--
-+APC: APCIterator regex & chunk size & list
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$it = new APCIterator('user', '/key[0-9]0/', APC_ITER_ALL, 1, APC_LIST_ACTIVE);
-+for($i = 0; $i < 41; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+foreach($it as $key=>$value) {
-+ $vals[$key] = $value['key'];
-+}
-+ksort($vals);
-+var_dump($vals);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECT--
-+array(4) {
-+ ["key10"]=>
-+ string(5) "key10"
-+ ["key20"]=>
-+ string(5) "key20"
-+ ["key30"]=>
-+ string(5) "key30"
-+ ["key40"]=>
-+ string(5) "key40"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_005.phpt b/ext/apc/tests/iterator_005.phpt
---- a/ext/apc/tests/iterator_005.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_005.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,112 @@
-+--TEST--
-+APC: APCIterator delete
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+--FILE--
-+<?php
-+
-+$vals = array();
-+$vals2 = array();
-+$it = new APCIterator('user', '/key[0-9]0/');
-+for($i = 0; $i < 41; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+apc_delete($it);
-+$it2 = new APCIterator('user');
-+foreach($it as $key=>$value) {
-+ $vals[$key] = $value['key'];
-+}
-+foreach($it2 as $key=>$value) {
-+ $vals2[$key] = $value['key'];
-+}
-+ksort($vals2);
-+var_dump($vals);
-+var_dump($vals2);
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECT--
-+array(0) {
-+}
-+array(37) {
-+ ["key0"]=>
-+ string(4) "key0"
-+ ["key1"]=>
-+ string(4) "key1"
-+ ["key11"]=>
-+ string(5) "key11"
-+ ["key12"]=>
-+ string(5) "key12"
-+ ["key13"]=>
-+ string(5) "key13"
-+ ["key14"]=>
-+ string(5) "key14"
-+ ["key15"]=>
-+ string(5) "key15"
-+ ["key16"]=>
-+ string(5) "key16"
-+ ["key17"]=>
-+ string(5) "key17"
-+ ["key18"]=>
-+ string(5) "key18"
-+ ["key19"]=>
-+ string(5) "key19"
-+ ["key2"]=>
-+ string(4) "key2"
-+ ["key21"]=>
-+ string(5) "key21"
-+ ["key22"]=>
-+ string(5) "key22"
-+ ["key23"]=>
-+ string(5) "key23"
-+ ["key24"]=>
-+ string(5) "key24"
-+ ["key25"]=>
-+ string(5) "key25"
-+ ["key26"]=>
-+ string(5) "key26"
-+ ["key27"]=>
-+ string(5) "key27"
-+ ["key28"]=>
-+ string(5) "key28"
-+ ["key29"]=>
-+ string(5) "key29"
-+ ["key3"]=>
-+ string(4) "key3"
-+ ["key31"]=>
-+ string(5) "key31"
-+ ["key32"]=>
-+ string(5) "key32"
-+ ["key33"]=>
-+ string(5) "key33"
-+ ["key34"]=>
-+ string(5) "key34"
-+ ["key35"]=>
-+ string(5) "key35"
-+ ["key36"]=>
-+ string(5) "key36"
-+ ["key37"]=>
-+ string(5) "key37"
-+ ["key38"]=>
-+ string(5) "key38"
-+ ["key39"]=>
-+ string(5) "key39"
-+ ["key4"]=>
-+ string(4) "key4"
-+ ["key5"]=>
-+ string(4) "key5"
-+ ["key6"]=>
-+ string(4) "key6"
-+ ["key7"]=>
-+ string(4) "key7"
-+ ["key8"]=>
-+ string(4) "key8"
-+ ["key9"]=>
-+ string(4) "key9"
-+}
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_006.phpt b/ext/apc/tests/iterator_006.phpt
---- a/ext/apc/tests/iterator_006.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_006.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,1536 @@
-+--TEST--
-+APC: APCIterator formats
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+apc.file_update_protection=0
-+apc.user_entries_hint=4096
-+--FILE--
-+<?php
-+
-+$formats = array(
-+ APC_ITER_TYPE,
-+ APC_ITER_KEY,
-+ APC_ITER_FILENAME,
-+ APC_ITER_DEVICE,
-+ APC_ITER_INODE,
-+ APC_ITER_VALUE,
-+ APC_ITER_MD5,
-+ APC_ITER_NUM_HITS,
-+ APC_ITER_MTIME,
-+ APC_ITER_CTIME,
-+ APC_ITER_DTIME,
-+ APC_ITER_ATIME,
-+ APC_ITER_REFCOUNT,
-+ APC_ITER_MEM_SIZE,
-+ APC_ITER_TTL,
-+ APC_ITER_NONE,
-+ APC_ITER_ALL,
-+ APC_ITER_ALL & ~APC_ITER_TTL,
-+ APC_ITER_KEY | APC_ITER_NUM_HITS | APC_ITER_MEM_SIZE,
-+ );
-+
-+$it_array = array();
-+
-+foreach ($formats as $idx => $format) {
-+ $it_array[$idx] = new APCIterator('user', NULL, $format);
-+}
-+
-+for($i = 0; $i < 11; $i++) {
-+ apc_store("key$i", "value$i");
-+}
-+
-+foreach ($it_array as $idx => $it) {
-+ print_it($it, $idx);
-+}
-+
-+function print_it($it, $idx) {
-+ echo "IT #$idx\n";
-+ echo "============================\n";
-+ foreach ($it as $key=>$value) {
-+ var_dump($key);
-+ var_dump($value);
-+ }
-+ echo "============================\n\n";
-+}
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+IT #0
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key0"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key1"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key2"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key3"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key4"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key5"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key6"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key7"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key8"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+string(4) "key9"
-+array(1) {
-+ ["type"]=>
-+ string(4) "user"
-+}
-+============================
-+
-+IT #1
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["key"]=>
-+ string(5) "key10"
-+}
-+string(4) "key0"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key0"
-+}
-+string(4) "key1"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key1"
-+}
-+string(4) "key2"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key2"
-+}
-+string(4) "key3"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key3"
-+}
-+string(4) "key4"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key4"
-+}
-+string(4) "key5"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key5"
-+}
-+string(4) "key6"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key6"
-+}
-+string(4) "key7"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key7"
-+}
-+string(4) "key8"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key8"
-+}
-+string(4) "key9"
-+array(1) {
-+ ["key"]=>
-+ string(4) "key9"
-+}
-+============================
-+
-+IT #2
-+============================
-+string(5) "key10"
-+array(0) {
-+}
-+string(4) "key0"
-+array(0) {
-+}
-+string(4) "key1"
-+array(0) {
-+}
-+string(4) "key2"
-+array(0) {
-+}
-+string(4) "key3"
-+array(0) {
-+}
-+string(4) "key4"
-+array(0) {
-+}
-+string(4) "key5"
-+array(0) {
-+}
-+string(4) "key6"
-+array(0) {
-+}
-+string(4) "key7"
-+array(0) {
-+}
-+string(4) "key8"
-+array(0) {
-+}
-+string(4) "key9"
-+array(0) {
-+}
-+============================
-+
-+IT #3
-+============================
-+string(5) "key10"
-+array(0) {
-+}
-+string(4) "key0"
-+array(0) {
-+}
-+string(4) "key1"
-+array(0) {
-+}
-+string(4) "key2"
-+array(0) {
-+}
-+string(4) "key3"
-+array(0) {
-+}
-+string(4) "key4"
-+array(0) {
-+}
-+string(4) "key5"
-+array(0) {
-+}
-+string(4) "key6"
-+array(0) {
-+}
-+string(4) "key7"
-+array(0) {
-+}
-+string(4) "key8"
-+array(0) {
-+}
-+string(4) "key9"
-+array(0) {
-+}
-+============================
-+
-+IT #4
-+============================
-+string(5) "key10"
-+array(0) {
-+}
-+string(4) "key0"
-+array(0) {
-+}
-+string(4) "key1"
-+array(0) {
-+}
-+string(4) "key2"
-+array(0) {
-+}
-+string(4) "key3"
-+array(0) {
-+}
-+string(4) "key4"
-+array(0) {
-+}
-+string(4) "key5"
-+array(0) {
-+}
-+string(4) "key6"
-+array(0) {
-+}
-+string(4) "key7"
-+array(0) {
-+}
-+string(4) "key8"
-+array(0) {
-+}
-+string(4) "key9"
-+array(0) {
-+}
-+============================
-+
-+IT #5
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["value"]=>
-+ string(7) "value10"
-+}
-+string(4) "key0"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value0"
-+}
-+string(4) "key1"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value1"
-+}
-+string(4) "key2"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value2"
-+}
-+string(4) "key3"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value3"
-+}
-+string(4) "key4"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value4"
-+}
-+string(4) "key5"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value5"
-+}
-+string(4) "key6"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value6"
-+}
-+string(4) "key7"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value7"
-+}
-+string(4) "key8"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value8"
-+}
-+string(4) "key9"
-+array(1) {
-+ ["value"]=>
-+ string(6) "value9"
-+}
-+============================
-+
-+IT #6
-+============================
-+string(5) "key10"
-+array(0) {
-+}
-+string(4) "key0"
-+array(0) {
-+}
-+string(4) "key1"
-+array(0) {
-+}
-+string(4) "key2"
-+array(0) {
-+}
-+string(4) "key3"
-+array(0) {
-+}
-+string(4) "key4"
-+array(0) {
-+}
-+string(4) "key5"
-+array(0) {
-+}
-+string(4) "key6"
-+array(0) {
-+}
-+string(4) "key7"
-+array(0) {
-+}
-+string(4) "key8"
-+array(0) {
-+}
-+string(4) "key9"
-+array(0) {
-+}
-+============================
-+
-+IT #7
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["num_hits"]=>
-+ int(0)
-+}
-+============================
-+
-+IT #8
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["mtime"]=>
-+ int(%d)
-+}
-+============================
-+
-+IT #9
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["creation_time"]=>
-+ int(%d)
-+}
-+============================
-+
-+IT #10
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["deletion_time"]=>
-+ int(0)
-+}
-+============================
-+
-+IT #11
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["access_time"]=>
-+ int(%d)
-+}
-+============================
-+
-+IT #12
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["ref_count"]=>
-+ int(0)
-+}
-+============================
-+
-+IT #13
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+============================
-+
-+IT #14
-+============================
-+string(5) "key10"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key0"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key1"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key2"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key3"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key4"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key5"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key6"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key7"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key8"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key9"
-+array(1) {
-+ ["ttl"]=>
-+ int(0)
-+}
-+============================
-+
-+IT #15
-+============================
-+string(5) "key10"
-+array(0) {
-+}
-+string(4) "key0"
-+array(0) {
-+}
-+string(4) "key1"
-+array(0) {
-+}
-+string(4) "key2"
-+array(0) {
-+}
-+string(4) "key3"
-+array(0) {
-+}
-+string(4) "key4"
-+array(0) {
-+}
-+string(4) "key5"
-+array(0) {
-+}
-+string(4) "key6"
-+array(0) {
-+}
-+string(4) "key7"
-+array(0) {
-+}
-+string(4) "key8"
-+array(0) {
-+}
-+string(4) "key9"
-+array(0) {
-+}
-+============================
-+
-+IT #16
-+============================
-+string(5) "key10"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(5) "key10"
-+ ["value"]=>
-+ string(7) "value10"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key0"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key0"
-+ ["value"]=>
-+ string(6) "value0"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key1"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key1"
-+ ["value"]=>
-+ string(6) "value1"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key2"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key2"
-+ ["value"]=>
-+ string(6) "value2"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key3"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key3"
-+ ["value"]=>
-+ string(6) "value3"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key4"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key4"
-+ ["value"]=>
-+ string(6) "value4"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key5"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key5"
-+ ["value"]=>
-+ string(6) "value5"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key6"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key6"
-+ ["value"]=>
-+ string(6) "value6"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key7"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key7"
-+ ["value"]=>
-+ string(6) "value7"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key8"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key8"
-+ ["value"]=>
-+ string(6) "value8"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+string(4) "key9"
-+array(11) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key9"
-+ ["value"]=>
-+ string(6) "value9"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+ ["ttl"]=>
-+ int(0)
-+}
-+============================
-+
-+IT #17
-+============================
-+string(5) "key10"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(5) "key10"
-+ ["value"]=>
-+ string(7) "value10"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key0"
-+ ["value"]=>
-+ string(6) "value0"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key1"
-+ ["value"]=>
-+ string(6) "value1"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key2"
-+ ["value"]=>
-+ string(6) "value2"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key3"
-+ ["value"]=>
-+ string(6) "value3"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key4"
-+ ["value"]=>
-+ string(6) "value4"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key5"
-+ ["value"]=>
-+ string(6) "value5"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key6"
-+ ["value"]=>
-+ string(6) "value6"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key7"
-+ ["value"]=>
-+ string(6) "value7"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key8"
-+ ["value"]=>
-+ string(6) "value8"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(10) {
-+ ["type"]=>
-+ string(4) "user"
-+ ["key"]=>
-+ string(4) "key9"
-+ ["value"]=>
-+ string(6) "value9"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mtime"]=>
-+ int(%d)
-+ ["creation_time"]=>
-+ int(%d)
-+ ["deletion_time"]=>
-+ int(0)
-+ ["access_time"]=>
-+ int(%d)
-+ ["ref_count"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+============================
-+
-+IT #18
-+============================
-+string(5) "key10"
-+array(3) {
-+ ["key"]=>
-+ string(5) "key10"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key0"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key0"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key1"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key1"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key2"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key2"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key3"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key3"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key4"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key4"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key5"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key5"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key6"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key6"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key7"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key7"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key8"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key8"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+string(4) "key9"
-+array(3) {
-+ ["key"]=>
-+ string(4) "key9"
-+ ["num_hits"]=>
-+ int(0)
-+ ["mem_size"]=>
-+ int(%d)
-+}
-+============================
-+
-+===DONE===
-diff -Naur a/ext/apc/tests/iterator_007.phpt b/ext/apc/tests/iterator_007.phpt
---- a/ext/apc/tests/iterator_007.phpt 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/iterator_007.phpt 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,36 @@
-+--TEST--
-+APC: APCIterator Overwriting the ctor
-+--SKIPIF--
-+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
-+--INI--
-+apc.enabled=1
-+apc.enable_cli=1
-+--FILE--
-+<?php
-+class foobar extends APCIterator {
-+ public function __construct() {}
-+}
-+$obj = new foobar;
-+var_dump(
-+ $obj->rewind(),
-+ $obj->current(),
-+ $obj->key(),
-+ $obj->next(),
-+ $obj->valid(),
-+ $obj->getTotalHits(),
-+ $obj->getTotalSize(),
-+ $obj->getTotalCount(),
-+ apc_delete($obj)
-+);
-+?>
-+--EXPECTF--
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+bool(false)
-+
-diff -Naur a/ext/apc/tests/php_5_3_ns.inc b/ext/apc/tests/php_5_3_ns.inc
---- a/ext/apc/tests/php_5_3_ns.inc 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/php_5_3_ns.inc 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,18 @@
-+<?php
-+namespace Foo\Bar;
-+
-+function sort() {
-+ $a = array(3,2,1,4);
-+ \sort($a); // global scoping
-+ var_dump($a);
-+ return "IT WORKS";
-+}
-+class Baz {
-+ public $i = 1;
-+ protected $f = 3.14;
-+ private $s = "hello world";
-+
-+ public function foo() {
-+ sort();
-+ }
-+}
-diff -Naur a/ext/apc/tests/skipif.inc b/ext/apc/tests/skipif.inc
---- a/ext/apc/tests/skipif.inc 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/tests/skipif.inc 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,6 @@
-+<?php
-+
-+if (!extension_loaded("apc")) die("skip");
-+//if (!ini_get('apc.enabled')) die("skip apc not enabled");
-+
-+?>
-diff -Naur a/ext/apc/TODO b/ext/apc/TODO
---- a/ext/apc/TODO 1970-01-01 01:00:00.000000000 +0100
-+++ b/ext/apc/TODO 2012-07-20 00:10:35.000000000 +0200
-@@ -0,0 +1,35 @@
-+Known Bugs
-+
-+1. Gallery2 doesn't work with PHP5+APC. There is something wrong
-+ with the way methods are restored in some edge case I haven't
-+ been able to figure out yet.
-+ To reproduce install gallery2 and click down to an individual photo.
-+
-+2. apc_store() probably needs some checks to skip trying to store
-+ internal classes. Something along the lines of:
-+
-+ if(Z_TYPE_P(val) == IS_OBJECT) {
-+ zend_class_entry *ce = Z_OBJCE_P(val);
-+ if(ce->type == ZEND_INTERNAL_CLASS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot cache internal objects");
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ in the apc_store() function in php_apc.c but I am wondering if it needs to do more
-+ than that.
-+
-+Windows
-+
-+1. The following configurations (build arguments) have not been implemented yet
-+
-+ (*) --enable-apc-mmap Memory mapping support
-+ (*) --enable-apc-sem Semaphore locking support (FCNTL replacement)
-+ (*) --enable-apc-phreadmutex Thread mutexes, while implemented we should probably rename the internals to thread
-+ (*) --enable-apc-pthreadrwlocks Thread mutexes, read/write locking
-+
-+2. Non-blocking locks is not supported either
-+
-+3. Update fileinfo to support stat info in a more portable way (see PECL #17903)
-+
-+4. Check whether the signal handling needs to be enabled, and if it makes sense on Windows
-\ Kein Zeilenumbruch am Dateiende.
+++ /dev/null
---- /dev/null
-+++ b/ext/http/CREDITS
-@@ -0,0 +1,2 @@
-+HTTP extension for PHP
-+Michael Wallner
---- /dev/null
-+++ b/ext/http/KnownIssues.txt
-@@ -0,0 +1,33 @@
-+Known Issues
-+============
-+$Id: KnownIssues.txt 292753 2009-12-29 12:30:43Z mike $
-+
-+PHP < 5.1.3:
-+ HttpResponse::getHeader() does not work with Apache2 SAPIs.
-+ Using an encoding stream filter on a stream you read from doesn't work.
-+
-+Windows:
-+ If you keep getting "SSL connect error" when trying to issue
-+ requests, try another (newer) libeay32.dll/ssleay32.dll pair.
-+
-+Internals:
-+ Our http_urlencode_hash() does not differentiate between prefixes
-+ for numeric or string keys.
-+ Inflating raw deflated data causes a re-initialization of the inflate
-+ stream where the corresponding window bits are modified to tell libz
-+ to not check for zlib header bytes. This is not preventable AFAICS.
-+ LFS dependant parts of libcurl are left out because of off_t,
-+ respectively off64_t confusion.
-+ Persistent handles and "cookiestore" request option do interfere,
-+ as libcurl saves the cookies to the file on curl_easy_destroy(),
-+ cookies are not saved until the CURL handle will be recycled.
-+ Thus one would either need to
-+ * run PHP with http.persistent.handles.limit = 0
-+ * call http_persistent_handles_clean() every request
-+ * call $HttpRequest->flushCookies(), which is available
-+ since libcurl v7.17.1 and does not work with the
-+ procedural API
-+ Anyway, none of these options is really perfect.
-+ HTTP and Proxy authentication information (username/password) can not be
-+ unset with NULL prior libcurl v7.19.6 and separate options for setting
-+ username and password--which work--are only available since v7.19.6.
---- /dev/null
-+++ b/ext/http/LICENSE
-@@ -0,0 +1,47 @@
-+Copyright (c) 2004-2010, Michael Wallner <mike@iworks.at>.
-+All rights reserved.
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions are met:
-+
-+ * Redistributions of source code must retain the above copyright notice,
-+ this list of conditions and the following disclaimer.
-+ * Redistributions in binary form must reproduce the above copyright
-+ notice, this list of conditions and the following disclaimer in the
-+ documentation and/or other materials provided with the distribution.
-+
-+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+
-+===============================================================================
-+
-+The date parser in file http_date_api.c is derived from the implementation
-+found in the original libcurl source, licensed under the following conditions:
-+
-+Copyright (c) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>.
-+All rights reserved.
-+
-+Permission to use, copy, modify, and distribute this software for any purpose
-+with or without fee is hereby granted, provided that the above copyright
-+notice and this permission notice appear in all copies.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
-+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-+OR OTHER DEALINGS IN THE SOFTWARE.
-+
-+Except as contained in this notice, the name of a copyright holder shall not
-+be used in advertising or otherwise to promote the sale, use or other dealings
-+in this Software without prior written authorization of the copyright holder.
-+
---- /dev/null
-+++ b/ext/http/Makefile.frag
-@@ -0,0 +1,23 @@
-+# vim: noet ts=1 sw=1
-+
-+phpincludedir=$(prefix)/include/php
-+
-+install-http: install install-http-headers
-+
-+install-http-headers:
-+ @echo "Installing HTTP headers: $(INSTALL_ROOT)$(phpincludedir)/ext/http/"
-+ @$(mkinstalldirs) $(INSTALL_ROOT)$(phpincludedir)/ext/http
-+ @for f in $(PHP_HTTP_HEADERS); do \
-+ if test -f "$(top_srcdir)/$$f"; then \
-+ $(INSTALL_DATA) $(top_srcdir)/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/http; \
-+ elif test -f "$(top_builddir)/$$f"; then \
-+ $(INSTALL_DATA) $(top_builddir)/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/http; \
-+ elif test -f "$(top_srcdir)/ext/http/$$f"; then \
-+ $(INSTALL_DATA) $(top_srcdir)/ext/http/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/http; \
-+ elif test -f "$(top_builddir)/ext/http/$$f"; then \
-+ $(INSTALL_DATA) $(top_builddir)/ext/http/$$f $(INSTALL_ROOT)$(phpincludedir)/ext/http; \
-+ else \
-+ echo "WTF? $$f"; \
-+ fi \
-+ done;
-+
---- /dev/null
-+++ b/ext/http/ThanksTo.txt
-@@ -0,0 +1,20 @@
-+Thanks To
-+=========
-+$Id: ThanksTo.txt 275653 2009-02-12 13:11:05Z mike $
-+
-+People who repeatedly reported issues with this extension in a manner
-+so they could be fixed in a reasonable way, or suggested useful features
-+to implement, in alphabetical order:
-+
-+ Ilia Alshanetsky (ilia at php dot net)
-+ Petr Czaderna (petr at hroch dot info)
-+ David James (james82 at gmail dot com)
-+ Thomas Landro Johnsen (thomas dot l dot johnsen at gmail dot com)
-+ Clay Loveless (clay at killersoft dot com)
-+ Felipe Pena (felipe at php dot net)
-+ David Sklar (sklar at sklar dot com)
-+ Travis Swicegood (travis at mashery dot com)
-+ Alexey Zakhlestin (indeyets at gmail dot com)
-+ Alexander Zhuravlev (zaa at zaa dot pp dot ru)
-+
-+Thanks a lot!
---- /dev/null
-+++ b/ext/http/config.m4
-@@ -0,0 +1,5 @@
-+dnl phpize stub of config9.m4 for pecl/http
-+dnl $Id: config.m4 214417 2006-06-07 21:05:34Z mike $
-+dnl vim: noet ts=1 sw=1
-+
-+sinclude(config9.m4)
---- /dev/null
-+++ b/ext/http/config.w32
-@@ -0,0 +1,129 @@
-+// config.w32 for pecl/http
-+// $Id: config.w32 287971 2009-09-02 14:36:08Z pajoye $
-+
-+ARG_ENABLE("http", "whether to enable extended HTTP support", "no");
-+
-+function check_for_main_ext(ext, header)
-+{
-+ if (!header) {
-+ header = "php_"+ ext +".h";
-+ }
-+
-+ /* When in configure, we're always in the root of PHP source */
-+ var ext_path = "ext\\" + ext;
-+
-+ STDOUT.Write("Checking for ext/"+ ext +" ... ");
-+
-+ if (FSO.FileExists(ext_path + "\\" + header)) {
-+ STDOUT.WriteLine(ext_path);
-+ return ext_path;
-+ }
-+
-+ STDOUT.WriteLine("<not found>");
-+ return false;
-+}
-+
-+function check_for_pecl_ext(ext, header)
-+{
-+ if (!header) {
-+ header = "php_"+ ext +".h";
-+ }
-+
-+ var g;
-+ var s = ext +"\\"+ header;
-+
-+ STDOUT.Write("Checking for pecl/"+ ext +" ... ");
-+ if ( (g = glob(configure_module_dirname +"\\..\\"+ s)) ||
-+ (g = glob(configure_module_dirname +"\\..\\..\\..\\pecl\\"+ s))) {
-+ var f = g[0].substr(0, g[0].length - header.length - 1);
-+ STDOUT.WriteLine(f);
-+ return f;
-+ }
-+ STDOUT.WriteLine("<not found>");
-+ return false;
-+}
-+
-+if (PHP_HTTP != "no") {
-+
-+ EXTENSION("http",
-+ "missing.c http.c http_functions.c http_exception_object.c "+
-+ "http_util_object.c http_message_object.c http_requestpool_object.c "+
-+ "http_request_object.c http_response_object.c "+
-+ "http_api.c http_cache_api.c http_request_pool_api.c "+
-+ "http_request_api.c http_date_api.c http_headers_api.c "+
-+ "http_message_api.c http_send_api.c http_url_api.c "+
-+ "http_info_api.c http_request_method_api.c http_encoding_api.c "+
-+ "http_filter_api.c http_request_body_api.c http_querystring_object.c "+
-+ "http_deflatestream_object.c http_inflatestream_object.c "+
-+ "http_cookie_api.c http_querystring_api.c http_request_datashare_api.c "+
-+ "http_requestdatashare_object.c http_request_info.c http_persistent_handle_api.c",
-+ null,
-+ "/I\"" + configure_module_dirname + "/phpstr\"");
-+ ADD_SOURCES(configure_module_dirname + "/phpstr", "phpstr.c", "http");
-+ AC_DEFINE("HAVE_HTTP", 1, "Have extended HTTP support");
-+ AC_DEFINE("HTTP_SHARED_DEPS", 1, "Depend on shared extensions");
-+
-+ AC_DEFINE("HAVE_GETHOSTNAME", 1);
-+ AC_DEFINE("HAVE_GETSERVBYPORT", 1);
-+ AC_DEFINE("HAVE_GETSERVBYNAME", 1);
-+
-+ if (PHP_DEBUG != "no") {
-+ ADD_FLAG("CFLAGS_HTTP", "/W3");
-+ }
-+
-+ if (CHECK_HEADER_ADD_INCLUDE('zlib.h', 'CFLAGS_HTTP', '..\\zlib;' + php_usual_include_suspects)) {
-+ AC_DEFINE('HTTP_HAVE_ZLIB', 1, "Have zlib library");
-+ ADD_FLAG("LDFLAGS_HTTP", "/FORCE:MULTIPLE");
-+ } else {
-+ WARNING("zlib encoding functions not enabled; libraries and headers not found");
-+ }
-+
-+ if (typeof(PHP_HASH) != "undefined" && PHP_HASH != "no") {
-+ var f;
-+
-+ if ((f = check_for_pecl_ext("hash")) || (f = check_for_main_ext("hash"))) {
-+ ADD_FLAG("CFLAGS_HTTP", '/I "' + f + '" /DHTTP_HAVE_PHP_HASH_H=1');
-+ ADD_EXTENSION_DEP("http", "hash", true);
-+ }
-+ }
-+
-+ if (PHP_SESSION != "no") {
-+ ADD_EXTENSION_DEP("http", "session", true);
-+ }
-+
-+ if (PHP_ICONV != "no") {
-+ ADD_EXTENSION_DEP("http", "iconv", true);
-+ }
-+
-+ CURL_LIB="libcurl_a.lib;libcurl.lib;" + (PHP_DEBUG != "no" ? "libcurld.lib":"libcurl.lib");
-+ if (CHECK_HEADER_ADD_INCLUDE("curl/curl.h", "CFLAGS_HTTP") &&
-+ CHECK_HEADER_ADD_INCLUDE("openssl/crypto.h", "CFLAGS_HTTP") &&
-+ CHECK_LIB(CURL_LIB, "http", PHP_HTTP) &&
-+ CHECK_LIB("ssleay32.lib", "http", PHP_HTTP) &&
-+ CHECK_LIB("libeay32.lib", "http", PHP_HTTP) &&
-+ CHECK_LIB("zlib.lib;zlib_a.lib", "http", PHP_HTTP) &&
-+ CHECK_LIB("winmm.lib", "http", PHP_HTTP)) {
-+ AC_DEFINE("HTTP_HAVE_CURL", 1, "Have CURL library");
-+ AC_DEFINE("HTTP_HAVE_SSL", 1, "Have SSL");
-+ AC_DEFINE("HAVE_CURL_MULTI_STRERROR", 1, "");
-+ AC_DEFINE("HAVE_CURL_SHARE_STRERROR", 1, "");
-+ AC_DEFINE("HAVE_CURL_EASY_STRERROR", 1, "");
-+ AC_DEFINE("HAVE_CURL_EASY_RESET", 1, "");
-+ AC_DEFINE("HAVE_CURL_GETFORMDATA", 1, "");
-+ AC_DEFINE("HAVE_CURL_FORMGET", 1, "");
-+ AC_DEFINE("HAVE_CURL_MULTI_SETOPT", 1, "");
-+ AC_DEFINE("HAVE_CURL_MULTI_TIMEOUT", 1, "");
-+ } else {
-+ WARNING("curl convenience functions not enabled; libraries and headers not found");
-+ }
-+/*
-+// MAGIC_LIB = PHP_DEBUG != "no" ? "libmagic-staticd.lib":"libmagic-static.lib";
-+// if (CHECK_HEADER_ADD_INCLUDE("magic.h", "CFLAGS_HTTP") &&
-+// CHECK_LIB(MAGIC_LIB, "http", PHP_HTTP)) {
-+// AC_DEFINE("HTTP_HAVE_MAGIC", 1, "Have magic library");
-+// AC_DEFINE("USE_MAGIC_STATIC", "", "");
-+// } else {
-+// WARNING("content type guessing not enabled; libraries and headers not found");
-+// }
-+*/
-+}
---- /dev/null
-+++ b/ext/http/config9.m4
-@@ -0,0 +1,468 @@
-+dnl config.m4 for pecl/http
-+dnl $Id: config9.m4 242664 2007-09-18 19:13:37Z mike $
-+dnl vim: noet ts=1 sw=1
-+
-+PHP_ARG_ENABLE([http], [whether to enable extended HTTP support],
-+[ --enable-http Enable extended HTTP support])
-+PHP_ARG_WITH([http-shared-deps], [whether to depend on extensions which have been built shared],
-+[ --with-http-shared-deps
-+ HTTP: disable to not depend on extensions like hash,
-+ iconv and session (when built shared)], $PHP_HTTP, $PHP_HTTP)
-+PHP_ARG_WITH([http-curl-requests], [whether to enable cURL HTTP request support],
-+[ --with-http-curl-requests[=LIBCURLDIR]
-+ HTTP: with cURL request support], $PHP_HTTP, $PHP_HTTP)
-+PHP_ARG_WITH([http-curl-libevent], [whether to enable libevent support fur cURL],
-+[ --with-http-curl-libevent[=LIBEVENTDIR]
-+ HTTP: libevent install directory], $PHP_HTTP_CURL_REQUESTS, "")
-+PHP_ARG_WITH([http-zlib-compression], [whether to enable zlib encodings support],
-+[ --with-http-zlib-compression[=LIBZDIR]
-+ HTTP: with zlib encodings support], $PHP_HTTP, $PHP_HTTP)
-+PHP_ARG_WITH([http-magic-mime], [whether to enable response content type guessing],
-+[ --with-http-magic-mime[=LIBMAGICDIR]
-+ HTTP: with magic mime response content type guessing], "no", "no")
-+
-+if test "$PHP_HTTP" != "no"; then
-+
-+ ifdef([AC_PROG_EGREP], [
-+ AC_PROG_EGREP
-+ ], [
-+ AC_CHECK_PROG(EGREP, egrep, egrep)
-+ ])
-+ ifdef([AC_PROG_SED], [
-+ AC_PROG_SED
-+ ], [
-+ ifdef([LT_AC_PROG_SED], [
-+ LT_AC_PROG_SED
-+ ], [
-+ AC_CHECK_PROG(SED, sed, sed)
-+ ])
-+ ])
-+
-+ AC_PROG_CPP
-+
-+ if test "$PHP_HTTP_SHARED_DEPS" != "no"; then
-+ AC_DEFINE([HTTP_SHARED_DEPS], [1], [ ])
-+ else
-+ AC_DEFINE([HTTP_SHARED_DEPS], [0], [ ])
-+ fi
-+
-+ dnl
-+ dnl HTTP_SHARED_DEP(name[, code-if-yes[, code-if-not]])
-+ dnl
-+ AC_DEFUN([HTTP_SHARED_DEP], [
-+ extname=$1
-+ haveext=$[HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)
-+
-+ AC_MSG_CHECKING([whether to add a dependency on ext/$extname])
-+ if test "$PHP_HTTP_SHARED_DEPS" = "no"; then
-+ AC_MSG_RESULT([no])
-+ $3
-+ elif test "$haveext"; then
-+ AC_MSG_RESULT([yes])
-+ ifdef([PHP_ADD_EXTENSION_DEP], [
-+ PHP_ADD_EXTENSION_DEP([http], $1, true)
-+ ])
-+ $2
-+ else
-+ AC_MSG_RESULT([no])
-+ $3
-+ fi
-+ ])
-+
-+ dnl
-+ dnl HTTP_HAVE_PHP_EXT(name[, code-if-yes[, code-if-not]])
-+ dnl
-+ AC_DEFUN([HTTP_HAVE_PHP_EXT], [
-+ extname=$1
-+ haveext=$[PHP_]translit($1,a-z_-,A-Z__)
-+
-+ AC_MSG_CHECKING([for ext/$extname support])
-+ if test -x "$PHP_EXECUTABLE"; then
-+ grepext=`$PHP_EXECUTABLE -m | $EGREP ^$extname\$`
-+ if test "$grepext" = "$extname"; then
-+ [HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1
-+ AC_MSG_RESULT([yes])
-+ $2
-+ else
-+ [HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=
-+ AC_MSG_RESULT([no])
-+ $3
-+ fi
-+ elif test "$haveext" != "no" && test "x$haveext" != "x"; then
-+ [HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1
-+ AC_MSG_RESULT([yes])
-+ $2
-+ else
-+ [HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=
-+ AC_MSG_RESULT([no])
-+ $3
-+ fi
-+ ])
-+
-+ dnl
-+ dnl odd PHP4 fix
-+ dnl
-+ if test "x$PHP_LIBDIR" = "x"; then
-+ PHP_LIBDIR=lib
-+ fi
-+
-+dnl ----
-+dnl STDC
-+dnl ----
-+ AC_CHECK_HEADERS([netdb.h unistd.h])
-+ PHP_CHECK_FUNC(gethostname, nsl)
-+ PHP_CHECK_FUNC(getdomainname, nsl)
-+ PHP_CHECK_FUNC(getservbyport, nsl)
-+ PHP_CHECK_FUNC(getservbyname, nsl)
-+
-+dnl ----
-+dnl ZLIB
-+dnl ----
-+ if test "$PHP_HTTP_ZLIB_COMPRESSION" != "no"; then
-+ AC_MSG_CHECKING([for zlib.h])
-+ ZLIB_DIR=
-+ for i in "$PHP_HTTP_ZLIB_COMPRESSION" "$PHP_ZLIB_DIR" "$PHP_ZLIB" /usr/local /usr /opt; do
-+ if test -f "$i/include/zlib.h"; then
-+ ZLIB_DIR=$i
-+ break;
-+ fi
-+ done
-+ if test "x$ZLIB_DIR" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ AC_MSG_ERROR([could not find zlib.h])
-+ else
-+ AC_MSG_RESULT([found in $ZLIB_DIR])
-+ AC_MSG_CHECKING([for zlib version >= 1.2.0.4])
-+ ZLIB_VERSION=`$EGREP "define ZLIB_VERSION" $ZLIB_DIR/include/zlib.h | $SED -e 's/[[^0-9\.]]//g'`
-+ AC_MSG_RESULT([$ZLIB_VERSION])
-+ if test `echo $ZLIB_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*1000000 + $2*10000 + $3*100 + $4}'` -lt 1020004; then
-+ AC_MSG_ERROR([libz version greater or equal to 1.2.0.4 required])
-+ else
-+ PHP_ADD_INCLUDE($ZLIB_DIR/include)
-+ PHP_ADD_LIBRARY_WITH_PATH(z, $ZLIB_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD)
-+ AC_DEFINE([HTTP_HAVE_ZLIB], [1], [Have zlib support])
-+ fi
-+ fi
-+ fi
-+
-+dnl ----
-+dnl CURL
-+dnl ----
-+ if test "$PHP_HTTP_CURL_REQUESTS" != "no"; then
-+ AC_MSG_CHECKING([for curl/curl.h])
-+ CURL_DIR=
-+ for i in "$PHP_HTTP_CURL_REQUESTS" /usr/local /usr /opt; do
-+ if test -f "$i/include/curl/curl.h"; then
-+ CURL_DIR=$i
-+ break
-+ fi
-+ done
-+ if test "x$CURL_DIR" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ AC_MSG_ERROR([could not find curl/curl.h])
-+ else
-+ AC_MSG_RESULT([found in $CURL_DIR])
-+ fi
-+
-+ AC_MSG_CHECKING([for curl-config])
-+ CURL_CONFIG=
-+ for i in "$CURL_DIR/bin/curl-config" "$CURL_DIR/curl-config" `which curl-config`; do
-+ if test -x "$i"; then
-+ CURL_CONFIG=$i
-+ break
-+ fi
-+ done
-+ if test "x$CURL_CONFIG" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ AC_MSG_ERROR([could not find curl-config])
-+ else
-+ AC_MSG_RESULT([found: $CURL_CONFIG])
-+ fi
-+
-+ dnl Debian stable has currently 7.13.2 (this is not a typo)
-+ AC_MSG_CHECKING([for curl version >= 7.12.3])
-+ CURL_VERSION=`$CURL_CONFIG --version | $SED -e 's/[[^0-9\.]]//g'`
-+ AC_MSG_RESULT([$CURL_VERSION])
-+ if test `echo $CURL_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*10000 + $2*100 + $3}'` -lt 71203; then
-+ AC_MSG_ERROR([libcurl version greater or equal to 7.12.3 required])
-+ fi
-+
-+ dnl
-+ dnl compile tests
-+ dnl
-+
-+ save_INCLUDES="$INCLUDES"
-+ INCLUDES=
-+ save_LIBS="$LIBS"
-+ LIBS=
-+ save_CFLAGS="$CFLAGS"
-+ CFLAGS=`$CURL_CONFIG --cflags`
-+ save_LDFLAGS="$LDFLAGS"
-+ LDFLAGS=`$CURL_CONFIG --libs`
-+ LDFLAGS="$LDFLAGS $ld_runpath_switch$CURL_DIR/$PHP_LIBDIR"
-+
-+ AC_MSG_CHECKING([for SSL support in libcurl])
-+ CURL_SSL=`$CURL_CONFIG --feature | $EGREP SSL`
-+ if test "$CURL_SSL" = "SSL"; then
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE([HTTP_HAVE_SSL], [1], [ ])
-+
-+ AC_MSG_CHECKING([for openssl support in libcurl])
-+ AC_TRY_RUN([
-+ #include <curl/curl.h>
-+ int main(int argc, char *argv[]) {
-+ curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
-+ if (data && data->ssl_version && *data->ssl_version) {
-+ const char *ptr = data->ssl_version;
-+ while(*ptr == ' ') ++ptr;
-+ return strncasecmp(ptr, "OpenSSL", sizeof("OpenSSL")-1);
-+ }
-+ return 1;
-+ }
-+ ], [
-+ AC_MSG_RESULT([yes])
-+ AC_CHECK_HEADER([openssl/crypto.h], [
-+ AC_DEFINE([HTTP_HAVE_OPENSSL], [1], [ ])
-+ ])
-+ ], [
-+ AC_MSG_RESULT([no])
-+ ], [
-+ AC_MSG_RESULT([no])
-+ ])
-+
-+ AC_MSG_CHECKING([for gnutls support in libcurl])
-+ AC_TRY_RUN([
-+ #include <curl/curl.h>
-+ int main(int argc, char *argv[]) {
-+ curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
-+ if (data && data->ssl_version && *data->ssl_version) {
-+ const char *ptr = data->ssl_version;
-+ while(*ptr == ' ') ++ptr;
-+ return strncasecmp(ptr, "GnuTLS", sizeof("GnuTLS")-1);
-+ }
-+ return 1;
-+ }
-+ ], [
-+ AC_MSG_RESULT([yes])
-+ AC_CHECK_HEADER([gcrypt.h], [
-+ AC_DEFINE([HTTP_HAVE_GNUTLS], [1], [ ])
-+ ])
-+ ], [
-+ AC_MSG_RESULT([no])
-+ ], [
-+ AC_MSG_RESULT([no])
-+ ])
-+ else
-+ AC_MSG_RESULT([no])
-+ fi
-+
-+ INCLUDES="$save_INCLUDES"
-+ LIBS="$save_LIBS"
-+ CFLAGS="$save_CFLAGS"
-+ LDFLAGS="$save_LDFLAGS"
-+
-+ dnl end compile tests
-+
-+ AC_MSG_CHECKING([for bundled SSL CA info])
-+ CURL_CAINFO=
-+ for i in `$CURL_CONFIG --ca` "/etc/ssl/certs/ca-certificates.crt"; do
-+ if test -f "$i"; then
-+ CURL_CAINFO="$i"
-+ break
-+ fi
-+ done
-+ if test "x$CURL_CAINFO" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ else
-+ AC_MSG_RESULT([$CURL_CAINFO])
-+ AC_DEFINE_UNQUOTED([HTTP_CURL_CAINFO], ["$CURL_CAINFO"], [path to bundled SSL CA info])
-+ fi
-+
-+ PHP_ADD_INCLUDE($CURL_DIR/include)
-+ PHP_ADD_LIBRARY_WITH_PATH(curl, $CURL_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD)
-+ PHP_EVAL_LIBLINE(`$CURL_CONFIG --libs`, HTTP_SHARED_LIBADD)
-+ AC_DEFINE([HTTP_HAVE_CURL], [1], [Have cURL support])
-+
-+ PHP_CHECK_LIBRARY(curl, curl_share_strerror,
-+ [AC_DEFINE([HAVE_CURL_SHARE_STRERROR], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_multi_strerror,
-+ [AC_DEFINE([HAVE_CURL_MULTI_STRERROR], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_easy_strerror,
-+ [AC_DEFINE([HAVE_CURL_EASY_STRERROR], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_easy_reset,
-+ [AC_DEFINE([HAVE_CURL_EASY_RESET], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_formget,
-+ [AC_DEFINE([HAVE_CURL_FORMGET], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_multi_setopt,
-+ [AC_DEFINE([HAVE_CURL_MULTI_SETOPT], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ PHP_CHECK_LIBRARY(curl, curl_multi_timeout,
-+ [AC_DEFINE([HAVE_CURL_MULTI_TIMEOUT], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+
-+ dnl ----
-+ dnl EVENT
-+ dnl ----
-+
-+ if test "$PHP_HTTP_CURL_LIBEVENT" != "no"; then
-+ HTTP_HAVE_PHP_EXT([event], [
-+ AC_MSG_WARN([event support is incompatible with pecl/event; continuing without libevent support])
-+ ], [
-+ AC_MSG_CHECKING([for event.h])
-+ EVENT_DIR=
-+ for i in "$PHP_HTTP_CURL_LIBEVENT" /usr/local /usr /opt; do
-+ if test -f "$i/include/event.h"; then
-+ EVENT_DIR=$i
-+ break
-+ fi
-+ done
-+ if test "x$EVENT_DIR" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ AC_MSG_WARN([continuing without libevent support])
-+ else
-+ AC_MSG_RESULT([found in $EVENT_DIR])
-+
-+ AC_MSG_CHECKING([for libevent version, roughly])
-+ EVENT_VER="1.1b or lower"
-+ if test -f "$EVENT_DIR/include/evhttp.h" && test -f "$EVENT_DIR/include/evdns.h"; then
-+ if test -f "$EVENT_DIR/include/evrpc.h"; then
-+ EVENT_VER="1.4 or greater"
-+ else
-+ EVENT_VER="1.2 or greater"
-+ fi
-+ fi
-+ AC_DEFINE_UNQUOTED([HTTP_EVENT_VERSION], ["$EVENT_VER"], [ ])
-+ AC_MSG_RESULT([$EVENT_VER])
-+
-+ AC_MSG_CHECKING([for libcurl version >= 7.16.0])
-+ AC_MSG_RESULT([$CURL_VERSION])
-+ if test `echo $CURL_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*10000 + $2*100 + $3}'` -lt 71600; then
-+ AC_MSG_WARN([libcurl version greater or equal to 7.16.0 required; continuing without libevent support])
-+ else
-+ PHP_ADD_INCLUDE($EVENT_DIR/include)
-+ PHP_ADD_LIBRARY_WITH_PATH(event, $EVENT_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD)
-+ AC_DEFINE([HTTP_HAVE_EVENT], [1], [Have libevent support for cURL])
-+ PHP_CHECK_LIBRARY(curl, curl_multi_socket_action,
-+ [AC_DEFINE([HAVE_CURL_MULTI_SOCKET_ACTION], [1], [ ])], [ ],
-+ [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
-+ )
-+ fi
-+ fi
-+ ])
-+ fi
-+ fi
-+
-+dnl ----
-+dnl MAGIC
-+dnl ----
-+ if test "$PHP_HTTP_MAGIC_MIME" != "no"; then
-+ AC_MSG_CHECKING([for magic.h])
-+ MAGIC_DIR=
-+ for i in "$PHP_HTTP_MAGIC_MIME" /usr/local /usr /opt; do
-+ if test -f "$i/include/magic.h"; then
-+ MAGIC_DIR=$i
-+ break
-+ fi
-+ done
-+ if test "x$MAGIC_DIR" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ AC_MSG_ERROR([could not find magic.h])
-+ else
-+ AC_MSG_RESULT([found in $MAGIC_DIR])
-+ fi
-+
-+ PHP_ADD_INCLUDE($MAGIC_DIR/include)
-+ PHP_ADD_LIBRARY_WITH_PATH(magic, $MAGIC_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD)
-+ AC_DEFINE([HTTP_HAVE_MAGIC], [1], [Have magic mime support])
-+ fi
-+
-+dnl ----
-+dnl HASH
-+dnl ----
-+ HTTP_HAVE_PHP_EXT([hash], [
-+ AC_MSG_CHECKING([for php_hash.h])
-+ HTTP_EXT_HASH_INCDIR=
-+ for i in `echo $INCLUDES | $SED -e's/-I//g'` $abs_srcdir ../hash; do
-+ if test -d $i; then
-+ if test -f $i/php_hash.h; then
-+ HTTP_EXT_HASH_INCDIR=$i
-+ break
-+ elif test -f $i/ext/hash/php_hash.h; then
-+ HTTP_EXT_HASH_INCDIR=$i/ext/hash
-+ break
-+ fi
-+ fi
-+ done
-+ if test "x$HTTP_EXT_HASH_INCDIR" = "x"; then
-+ AC_MSG_RESULT([not found])
-+ else
-+ AC_MSG_RESULT([$HTTP_EXT_HASH_INCDIR])
-+ AC_DEFINE([HTTP_HAVE_PHP_HASH_H], [1], [Have ext/hash support])
-+ PHP_ADD_INCLUDE([$HTTP_EXT_HASH_INCDIR])
-+ fi
-+ ])
-+
-+dnl ----
-+dnl ICONV
-+dnl ----
-+ HTTP_HAVE_PHP_EXT([iconv])
-+
-+dnl ----
-+dnl SESSION
-+dnl ----
-+ HTTP_HAVE_PHP_EXT([session])
-+
-+dnl ----
-+dnl DONE
-+dnl ----
-+ PHP_HTTP_SOURCES="missing.c http.c http_functions.c phpstr/phpstr.c \
-+ http_util_object.c http_message_object.c http_request_object.c http_request_pool_api.c \
-+ http_response_object.c http_exception_object.c http_requestpool_object.c \
-+ http_api.c http_cache_api.c http_request_api.c http_request_info.c http_date_api.c \
-+ http_headers_api.c http_message_api.c http_send_api.c http_url_api.c \
-+ http_info_api.c http_request_method_api.c http_encoding_api.c \
-+ http_filter_api.c http_request_body_api.c http_querystring_object.c \
-+ http_deflatestream_object.c http_inflatestream_object.c http_cookie_api.c \
-+ http_querystring_api.c http_request_datashare_api.c http_requestdatashare_object.c \
-+ http_persistent_handle_api.c"
-+
-+ PHP_NEW_EXTENSION([http], $PHP_HTTP_SOURCES, $ext_shared)
-+
-+ dnl shared extension deps
-+ HTTP_SHARED_DEP([hash])
-+ HTTP_SHARED_DEP([iconv])
-+ HTTP_SHARED_DEP([session])
-+
-+ PHP_ADD_BUILD_DIR($ext_builddir/phpstr, 1)
-+ PHP_SUBST([HTTP_SHARED_LIBADD])
-+
-+ PHP_HTTP_HEADERS="php_http_std_defs.h php_http.h php_http_api.h php_http_cache_api.h \
-+ php_http_date_api.h php_http_headers_api.h php_http_info_api.h php_http_message_api.h \
-+ php_http_request_api.h php_http_request_method_api.h php_http_send_api.h php_http_url_api.h \
-+ php_http_encoding_api.h phpstr/phpstr.h missing.h php_http_request_body_api.h \
-+ php_http_exception_object.h php_http_message_object.h php_http_request_object.h \
-+ php_http_requestpool_object.h php_http_response_object.h php_http_util_object.h \
-+ php_http_querystring_object.h php_http_deflatestream_object.h php_http_inflatestream_object.h \
-+ php_http_cookie_api.h php_http_querystring_api.h php_http_request_datashare_api.h php_http_requestdatashare_object.h \
-+ php_http_persistent_handle_api.h"
-+ ifdef([PHP_INSTALL_HEADERS], [
-+ PHP_INSTALL_HEADERS(ext/http, $PHP_HTTP_HEADERS)
-+ ], [
-+ PHP_SUBST([PHP_HTTP_HEADERS])
-+ PHP_ADD_MAKEFILE_FRAGMENT
-+ ])
-+
-+ AC_DEFINE([HAVE_HTTP], [1], [Have extended HTTP support])
-+fi
---- /dev/null
-+++ b/ext/http/docs/examples/tutorial.txt
-@@ -0,0 +1,175 @@
-+
-+A Beginners Tutorial
-+--------------------
-+$Revision: 208773 $
-+
-+
-+- GET Queries
-+
-+ The HttpRequest class can be used to execute any HTTP request method.
-+ The following example shows a simple GET request where a few query
-+ parameters are supplied. Additionally potential cookies will be
-+ read from and written to a file.
-+
-+<?php
-+$r = new HttpRequest('http://www.google.com/search');
-+
-+// store Googles cookies in a dedicated file
-+touch('google.txt');
-+$r->setOptions(
-+ array( 'cookiestore' => 'google.txt',
-+ )
-+);
-+
-+$r->setQueryData(
-+ array( 'q' => '+"pecl_http" -msg -cvs -list',
-+ 'hl' => 'de'
-+ )
-+);
-+
-+// HttpRequest::send() returns an HttpMessage object
-+// of type HttpMessage::TYPE_RESPONSE or throws an exception
-+try {
-+ print $r->send()->getBody();
-+} catch (HttpException $e) {
-+ print $e;
-+}
-+?>
-+
-+- Multipart Posts
-+
-+ The following example shows an multipart POST request, with two form
-+ fields and an image that's supposed to be uploaded to the server.
-+ It's a bad habit as well as common practice to issue a redirect after
-+ an received POST request, so we'll allow a redirect by enabling the
-+ redirect option.
-+
-+<?php
-+$r = new HttpRequest('http://dev.iworks.at/.print_request.php', HTTP_METH_POST);
-+
-+// if redirects is set to true, a single redirect is allowed;
-+// one can set any reasonable count of allowed redirects
-+$r->setOptions(
-+ array( 'cookies' => array('MyCookie' => 'has a value'),
-+ 'redirect' => true,
-+ )
-+);
-+
-+// common form data
-+$r->setPostFields(
-+ array( 'name' => 'Mike',
-+ 'mail' => 'mike@php.net',
-+ )
-+);
-+// add the file to post (form name, file name, file type)
-+touch('profile.jpg');
-+$r->addPostFile('image', 'profile.jpg', 'image/jpeg');
-+
-+try {
-+ print $r->send()->getBody();
-+} catch (HttpException $e) {
-+ print $e;
-+}
-+?>
-+
-+- Parallel Requests
-+
-+ It's possible to execute several HttpRequests in parallel with the
-+ HttpRequestPool class. HttpRequests to send, do not need to perform
-+ the same request method, but can only be attached to one HttpRequestPool
-+ at the same time.
-+
-+<?php
-+try {
-+ $p = new HttpRequestPool;
-+ // if you want to set _any_ options of the HttpRequest object,
-+ // you need to do so *prior attaching* to the request pool!
-+ $p->attach(new HttpRequest('http://pear.php.net', HTTP_METH_HEAD));
-+ $p->attach(new HttpRequest('http://pecl.php.net', HTTP_METH_HEAD));
-+} catch (HttpException $e) {
-+ print $e;
-+ exit;
-+}
-+
-+try {
-+ $p->send();
-+ // HttpRequestPool implements an iterator over attached HttpRequest objects
-+ foreach ($p as $r) {
-+ echo "Checking ", $r->getUrl(), " reported ", $r->getResponseCode(), "\n";
-+ }
-+} catch (HttpException $e) {
-+ print $e;
-+}
-+?>
-+
-+- Parallel Requests?
-+
-+ You can use a more advanced approach by using the protected interface of
-+ the HttpRequestPool class. This allows you to perform some other tasks
-+ while the requests are executed.
-+
-+<?php
-+class Pool extends HttpRequestPool
-+{
-+ public function __construct()
-+ {
-+ parent::__construct(
-+ new HttpRequest('http://pear.php.net', HTTP_METH_HEAD),
-+ new HttpRequest('http://pecl.php.net', HTTP_METH_HEAD)
-+ );
-+
-+ // HttpRequestPool methods socketPerform() and socketSelect() are
-+ // protected; one could use this approach to do something else
-+ // while the requests are being executed
-+ print "Executing requests";
-+ for ($i = 0; $this->socketPerform(); $i++) {
-+ $i % 10 or print ".";
-+ if (!$this->socketSelect()) {
-+ throw new HttpException("Socket error!");
-+ }
-+ }
-+ print "\nDone!\n";
-+ }
-+}
-+
-+try {
-+ foreach (new Pool as $r) {
-+ echo "Checking ", $r->getUrl(), " reported ", $r->getResponseCode(), "\n";
-+ }
-+} catch (HttpException $ex) {
-+ print $e;
-+}
-+?>
-+
-+- Cached Responses
-+
-+ One of the main key features of HttpResponse is HTTP caching. HttpResponse
-+ will calculate an ETag based on the http.etag_mode INI setting as well as
-+ it will determine the last modification time of the sent entity. It uses
-+ those two indicators to decide if the cache entry on the client side is
-+ still valid and will emit an "304 Not Modified" response if applicable.
-+
-+<?php
-+HttpResponse::setCacheControl('public');
-+HttpResponse::setCache(true);
-+HttpResponse::capture();
-+
-+print "This will be cached until content changes!\n";
-+print "Note that this approach will only save the clients download time.\n";
-+?>
-+
-+- Bandwidth Throttling
-+
-+ HttpResponse supports a basic throttling mechanism, which is enabled by
-+ setting a throttle delay and a buffer size. PHP will sleep the specified
-+ amount of seconds after each sent chunk of specified bytes.
-+
-+<?php
-+// send 5000 bytes every 0.2 seconds, i.e. max ~25kByte/s
-+HttpResponse::setThrottleDelay(0.2);
-+HttpResponse::setBufferSize(5000);
-+HttpResponse::setCache(true);
-+HttpResponse::setContentType('application/x-zip');
-+HttpResponse::setFile('../archive.zip');
-+HttpResponse::send();
-+?>
---- /dev/null
-+++ b/ext/http/docs/http.ini
-@@ -0,0 +1,61 @@
-+; example INI file for pecl/http
-+; $Id: http.ini 229420 2007-02-09 14:19:40Z mike $
-+
-+[http]
-+; enable if you want to transform all errors to exceptions (PHP >= 5 only)
-+;http.only_exceptions = 1
-+
-+; disable if you don't want php to exit in case of redirects and cache hits;
-+; a "NULL" output handler will be started instead, which discards all output
-+;http.force_exit = 0
-+
-+; disable if you don't want 404 Not found status messages being sent,
-+; if a file attempted to be sent with http_send_file() etc. cannot be found
-+;http.send.not_found_404 = 0
-+
-+; the hashing algorithm with wich ETags are generated (MD5, SHA1, CRC32B);
-+; if ext/hash is available, this can be set to any hash algorithm ext/hash supports
-+; MD5 is the default and fallback algorithm
-+;http.etag.mode = "MD5"
-+
-+; allowed request methods
-+; by default PHP ignores unkown request methods
-+; PHP will exit with a response status of 405 and an Allow header
-+; if it encounters a request method not contained in the specified list
-+;http.request.methods.allowed = "HEAD, GET, POST"
-+
-+; custom request methods
-+;http.request.methods.custom = "KICK, BANN"
-+
-+; log file for positive cache hits
-+;http.log.cache =
-+
-+; log file for redirects
-+;http.log.redirect =
-+
-+; log file for responses with http_send_file() etc. where the file's not been found
-+;http.log.not_found =
-+
-+; log file for requests with an unallowed request method
-+;http.log.allowed_methods =
-+
-+; composite log file (i.e. log all messages to this file)
-+;http.log.composite =
-+
-+; automatically deflate content if requested/supported by client
-+;http.send.deflate.start_auto = 1
-+;http.send.deflate.start_flags = HTTP_DEFLATE_LEVEL_DEF
-+
-+; automatically inflate sent content
-+;http.send.inflate.start_auto = 0
-+;http.send.inflate.start_flags =
-+
-+; global HttpRequestDataShare settings
-+;http.request.datashare.cookie = 0
-+;http.request.datashare.dns = 1
-+
-+; limit of idle persistent handles per provider
-+;http.persistent.handles.limit = -1
-+
-+; default ident of persistent handles
-+;http.persistent.handles.ident = "GLOBAL"
---- /dev/null
-+++ b/ext/http/http.c
-@@ -0,0 +1,546 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http.c 300300 2010-06-09 07:29:35Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_CURL
-+#define HTTP_WANT_EVENT
-+#define HTTP_WANT_ZLIB
-+#define HTTP_WANT_MAGIC
-+#include "php_http.h"
-+
-+#include "php_ini.h"
-+#include "ext/standard/info.h"
-+#include "zend_extensions.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_cache_api.h"
-+#include "php_http_cookie_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_filter_api.h"
-+#include "php_http_message_api.h"
-+#include "php_http_persistent_handle_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_datashare_api.h"
-+#include "php_http_request_method_api.h"
-+#include "php_http_request_pool_api.h"
-+#include "php_http_send_api.h"
-+#include "php_http_url_api.h"
-+
-+#include "php_http_deflatestream_object.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_inflatestream_object.h"
-+#include "php_http_message_object.h"
-+#include "php_http_querystring_object.h"
-+#include "php_http_request_object.h"
-+#include "php_http_requestdatashare_object.h"
-+#include "php_http_requestpool_object.h"
-+#include "php_http_response_object.h"
-+#include "php_http_util_object.h"
-+
-+ZEND_DECLARE_MODULE_GLOBALS(http);
-+HTTP_DECLARE_ARG_PASS_INFO();
-+
-+#ifdef COMPILE_DL_HTTP
-+ZEND_GET_MODULE(http)
-+#endif
-+
-+/* {{{ http_functions[] */
-+zend_function_entry http_functions[] = {
-+ PHP_FE(http_date, NULL)
-+ PHP_FE(http_build_url, http_arg_pass_ref_4)
-+ PHP_FE(http_build_str, NULL)
-+#ifndef ZEND_ENGINE_2
-+ PHP_FALIAS(http_build_query, http_build_str, NULL)
-+#endif
-+ PHP_FE(http_negotiate_language, http_arg_pass_ref_2)
-+ PHP_FE(http_negotiate_charset, http_arg_pass_ref_2)
-+ PHP_FE(http_negotiate_content_type, http_arg_pass_ref_2)
-+ PHP_FE(http_negotiate, http_arg_pass_ref_3)
-+ PHP_FE(http_redirect, NULL)
-+ PHP_FE(http_throttle, NULL)
-+ PHP_FE(http_send_status, NULL)
-+ PHP_FE(http_send_last_modified, NULL)
-+ PHP_FE(http_send_content_type, NULL)
-+ PHP_FE(http_send_content_disposition, NULL)
-+ PHP_FE(http_match_modified, NULL)
-+ PHP_FE(http_match_etag, NULL)
-+ PHP_FE(http_cache_last_modified, NULL)
-+ PHP_FE(http_cache_etag, NULL)
-+ PHP_FE(http_send_data, NULL)
-+ PHP_FE(http_send_file, NULL)
-+ PHP_FE(http_send_stream, NULL)
-+ PHP_FE(http_chunked_decode, NULL)
-+ PHP_FE(http_parse_message, NULL)
-+ PHP_FE(http_parse_headers, NULL)
-+ PHP_FE(http_parse_cookie, NULL)
-+ PHP_FE(http_build_cookie, NULL)
-+ PHP_FE(http_parse_params, NULL)
-+ PHP_FE(http_get_request_headers, NULL)
-+ PHP_FE(http_get_request_body, NULL)
-+ PHP_FE(http_get_request_body_stream, NULL)
-+ PHP_FE(http_match_request_header, NULL)
-+ PHP_FE(http_persistent_handles_count, NULL)
-+ PHP_FE(http_persistent_handles_clean, NULL)
-+ PHP_FE(http_persistent_handles_ident, NULL)
-+#ifdef HTTP_HAVE_CURL
-+ PHP_FE(http_get, http_arg_pass_ref_3)
-+ PHP_FE(http_head, http_arg_pass_ref_3)
-+ PHP_FE(http_post_data, http_arg_pass_ref_4)
-+ PHP_FE(http_post_fields, http_arg_pass_ref_5)
-+ PHP_FE(http_put_data, http_arg_pass_ref_4)
-+ PHP_FE(http_put_file, http_arg_pass_ref_4)
-+ PHP_FE(http_put_stream, http_arg_pass_ref_4)
-+ PHP_FE(http_request, http_arg_pass_ref_5)
-+ PHP_FE(http_request_body_encode, NULL)
-+#endif
-+ PHP_FE(http_request_method_register, NULL)
-+ PHP_FE(http_request_method_unregister, NULL)
-+ PHP_FE(http_request_method_exists, NULL)
-+ PHP_FE(http_request_method_name, NULL)
-+ PHP_FE(ob_etaghandler, NULL)
-+#ifdef HTTP_HAVE_ZLIB
-+ PHP_FE(http_deflate, NULL)
-+ PHP_FE(http_inflate, NULL)
-+ PHP_FE(ob_deflatehandler, NULL)
-+ PHP_FE(ob_inflatehandler, NULL)
-+#endif
-+ PHP_FE(http_support, NULL)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+/* }}} */
-+
-+PHP_MINIT_FUNCTION(http);
-+PHP_MSHUTDOWN_FUNCTION(http);
-+PHP_RINIT_FUNCTION(http);
-+PHP_RSHUTDOWN_FUNCTION(http);
-+PHP_MINFO_FUNCTION(http);
-+
-+/* {{{ http_module_dep */
-+#if ZEND_EXTENSION_API_NO >= 220050617
-+static zend_module_dep http_module_deps[] = {
-+# ifdef HTTP_HAVE_SPL
-+ ZEND_MOD_REQUIRED("spl")
-+# endif
-+# ifdef HTTP_HAVE_HASH
-+ ZEND_MOD_REQUIRED("hash")
-+# endif
-+# ifdef HTTP_HAVE_SESSION
-+ ZEND_MOD_REQUIRED("session")
-+# endif
-+# ifdef HTTP_HAVE_ICONV
-+ ZEND_MOD_REQUIRED("iconv")
-+# endif
-+# ifdef HTTP_HAVE_EVENT
-+ ZEND_MOD_CONFLICTS("event")
-+#endif
-+ {NULL, NULL, NULL, 0}
-+};
-+#endif
-+/* }}} */
-+
-+/* {{{ http_module_entry */
-+zend_module_entry http_module_entry = {
-+#if ZEND_EXTENSION_API_NO >= 220050617
-+ STANDARD_MODULE_HEADER_EX, NULL,
-+ http_module_deps,
-+#else
-+ STANDARD_MODULE_HEADER,
-+#endif
-+ "http",
-+ http_functions,
-+ PHP_MINIT(http),
-+ PHP_MSHUTDOWN(http),
-+ PHP_RINIT(http),
-+ PHP_RSHUTDOWN(http),
-+ PHP_MINFO(http),
-+ PHP_HTTP_VERSION,
-+ STANDARD_MODULE_PROPERTIES
-+};
-+/* }}} */
-+
-+int http_module_number;
-+
-+/* {{{ http_globals */
-+static void http_globals_init_once(zend_http_globals *G)
-+{
-+ memset(G, 0, sizeof(zend_http_globals));
-+}
-+
-+#define http_globals_init(g) _http_globals_init((g) TSRMLS_CC)
-+static inline void _http_globals_init(zend_http_globals *G TSRMLS_DC)
-+{
-+#ifdef HTTP_HAVE_SAPI_RTIME
-+ G->request.time = sapi_get_request_time(TSRMLS_C);
-+#else
-+ G->request.time = time(NULL);
-+#endif
-+ G->send.buffer_size = 0;
-+ G->read_post_data = 0;
-+}
-+
-+#define http_globals_free(g) _http_globals_free((g) TSRMLS_CC)
-+static inline void _http_globals_free(zend_http_globals *G TSRMLS_DC)
-+{
-+ if (G->request.headers) {
-+ zend_hash_destroy(G->request.headers);
-+ FREE_HASHTABLE(G->request.headers);
-+ G->request.headers = NULL;
-+ }
-+ STR_SET(G->send.content_type, NULL);
-+ STR_SET(G->send.unquoted_etag, NULL);
-+ if (G->server_var) {
-+ zval_ptr_dtor(&G->server_var);
-+ G->server_var = NULL;
-+ }
-+}
-+
-+#if defined(ZTS) && defined(PHP_DEBUG)
-+#if ZTS && PHP_DEBUG
-+zend_http_globals *http_globals(void)
-+{
-+ TSRMLS_FETCH();
-+ return HTTP_G;
-+}
-+#endif
-+#endif
-+/* }}} */
-+
-+/* {{{ static inline void http_check_allowed_methods(char *) */
-+#define http_check_allowed_methods(m) _http_check_allowed_methods((m) TSRMLS_CC)
-+static inline void _http_check_allowed_methods(const char *methods TSRMLS_DC)
-+{
-+ if (*methods && SG(request_info).request_method) {
-+ if (SUCCESS != http_check_method_ex(SG(request_info).request_method, methods)) {
-+ char *header;
-+ spprintf(&header, 0, "Allow: %s", methods);
-+ http_exit(405, header);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ PHP_INI */
-+PHP_INI_MH(http_update_allowed_methods)
-+{
-+ if (*new_value) {
-+ http_check_allowed_methods(new_value);
-+ }
-+ return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-+}
-+PHP_INI_MH(http_update_persistent_handle_ident)
-+{
-+ HTTP_G->persistent.handles.ident.h = zend_hash_func(new_value, HTTP_G->persistent.handles.ident.l = new_value_length+1);
-+ return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-+}
-+
-+#ifndef ZEND_ENGINE_2
-+# define OnUpdateLong OnUpdateInt
-+#endif
-+
-+PHP_INI_BEGIN()
-+ HTTP_PHP_INI_ENTRY("http.etag.mode", "MD5", PHP_INI_ALL, OnUpdateString, etag.mode)
-+ HTTP_PHP_INI_ENTRY("http.log.cache", "", PHP_INI_ALL, OnUpdateString, log.cache)
-+ HTTP_PHP_INI_ENTRY("http.log.redirect", "", PHP_INI_ALL, OnUpdateString, log.redirect)
-+ HTTP_PHP_INI_ENTRY("http.log.not_found", "", PHP_INI_ALL, OnUpdateString, log.not_found)
-+ HTTP_PHP_INI_ENTRY("http.log.allowed_methods", "", PHP_INI_ALL, OnUpdateString, log.allowed_methods)
-+ HTTP_PHP_INI_ENTRY("http.log.composite", "", PHP_INI_ALL, OnUpdateString, log.composite)
-+ HTTP_PHP_INI_ENTRY("http.request.methods.allowed", "", PHP_INI_ALL, http_update_allowed_methods, request.methods.allowed)
-+ HTTP_PHP_INI_ENTRY("http.request.methods.custom", "", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateString, request.methods.custom)
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+ HTTP_PHP_INI_ENTRY("http.request.datashare.cookie", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.cookie)
-+ HTTP_PHP_INI_ENTRY("http.request.datashare.dns", "1", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.dns)
-+ HTTP_PHP_INI_ENTRY("http.request.datashare.ssl", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.ssl)
-+ HTTP_PHP_INI_ENTRY("http.request.datashare.connect", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.connect)
-+#endif
-+#ifdef HTTP_HAVE_ZLIB
-+ HTTP_PHP_INI_ENTRY("http.send.inflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.inflate.start_auto)
-+ HTTP_PHP_INI_ENTRY("http.send.inflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.inflate.start_flags)
-+ HTTP_PHP_INI_ENTRY("http.send.deflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.deflate.start_auto)
-+ HTTP_PHP_INI_ENTRY("http.send.deflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.deflate.start_flags)
-+#endif
-+ HTTP_PHP_INI_ENTRY("http.persistent.handles.limit", "-1", PHP_INI_SYSTEM, OnUpdateLong, persistent.handles.limit)
-+ HTTP_PHP_INI_ENTRY("http.persistent.handles.ident", "GLOBAL", PHP_INI_ALL, http_update_persistent_handle_ident, persistent.handles.ident.s)
-+ HTTP_PHP_INI_ENTRY("http.send.not_found_404", "1", PHP_INI_ALL, OnUpdateBool, send.not_found_404)
-+#ifdef ZEND_ENGINE_2
-+ HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions)
-+#endif
-+ HTTP_PHP_INI_ENTRY("http.force_exit", "1", PHP_INI_ALL, OnUpdateBool, force_exit)
-+PHP_INI_END()
-+/* }}} */
-+
-+/* {{{ PHP_MINIT_FUNCTION */
-+PHP_MINIT_FUNCTION(http)
-+{
-+ http_module_number = module_number;
-+ ZEND_INIT_MODULE_GLOBALS(http, http_globals_init_once, NULL);
-+ REGISTER_INI_ENTRIES();
-+
-+ if (0
-+ || SUCCESS != PHP_MINIT_CALL(http_persistent_handle) /* first */
-+ || SUCCESS != PHP_MINIT_CALL(http_cookie)
-+#ifdef HTTP_HAVE_ZLIB
-+ || SUCCESS != PHP_MINIT_CALL(http_encoding)
-+#endif
-+#ifdef HTTP_HAVE_CURL
-+ || SUCCESS != PHP_MINIT_CALL(http_request)
-+# ifdef ZEND_ENGINE_2
-+# endif
-+#endif
-+ || SUCCESS != PHP_MINIT_CALL(http_request_method)
-+ || SUCCESS != PHP_MINIT_CALL(http_send)
-+ || SUCCESS != PHP_MINIT_CALL(http_support)
-+ || SUCCESS != PHP_MINIT_CALL(http_url)
-+
-+#ifdef ZEND_ENGINE_2
-+ || SUCCESS != PHP_MINIT_CALL(http_filter)
-+ || SUCCESS != PHP_MINIT_CALL(http_exception_object)
-+# ifdef HTTP_HAVE_ZLIB
-+ || SUCCESS != PHP_MINIT_CALL(http_deflatestream_object)
-+ || SUCCESS != PHP_MINIT_CALL(http_inflatestream_object)
-+# endif
-+ || SUCCESS != PHP_MINIT_CALL(http_message_object)
-+ || SUCCESS != PHP_MINIT_CALL(http_querystring_object)
-+# ifdef HTTP_HAVE_CURL
-+ || SUCCESS != PHP_MINIT_CALL(http_request_datashare)
-+ || SUCCESS != PHP_MINIT_CALL(http_request_pool)
-+ || SUCCESS != PHP_MINIT_CALL(http_request_object)
-+ || SUCCESS != PHP_MINIT_CALL(http_requestdatashare_object)
-+ || SUCCESS != PHP_MINIT_CALL(http_requestpool_object)
-+# endif
-+# ifndef WONKY
-+ || SUCCESS != PHP_MINIT_CALL(http_response_object)
-+# endif
-+ || SUCCESS != PHP_MINIT_CALL(http_util_object)
-+#endif
-+ ) {
-+ return FAILURE;
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_MSHUTDOWN_FUNCTION */
-+PHP_MSHUTDOWN_FUNCTION(http)
-+{
-+ UNREGISTER_INI_ENTRIES();
-+
-+ if (0
-+#ifdef HTTP_HAVE_CURL
-+ || SUCCESS != PHP_MSHUTDOWN_CALL(http_request)
-+# ifdef ZEND_ENGINE_2
-+ || SUCCESS != PHP_MSHUTDOWN_CALL(http_request_datashare)
-+# endif
-+#endif
-+ || SUCCESS != PHP_MSHUTDOWN_CALL(http_message_object)
-+ || SUCCESS != PHP_MSHUTDOWN_CALL(http_persistent_handle) /* last */
-+ ) {
-+ return FAILURE;
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_RINIT_FUNCTION */
-+PHP_RINIT_FUNCTION(http)
-+{
-+ http_globals_init(HTTP_G);
-+
-+ if (HTTP_G->request.methods.allowed && *HTTP_G->request.methods.allowed) {
-+ http_check_allowed_methods(HTTP_G->request.methods.allowed);
-+ }
-+
-+ if (0
-+#ifdef HTTP_HAVE_ZLIB
-+ || SUCCESS != PHP_RINIT_CALL(http_encoding)
-+#endif
-+#ifdef HTTP_HAVE_CURL
-+# ifdef ZEND_ENGINE_2
-+# ifdef HTTP_HAVE_EVENT
-+ || SUCCESS != PHP_RINIT_CALL(http_request_pool)
-+# endif
-+ || SUCCESS != PHP_RINIT_CALL(http_request_datashare)
-+# endif
-+#endif
-+ || SUCCESS != PHP_RINIT_CALL(http_request_method)
-+ ) {
-+ return FAILURE;
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_RSHUTDOWN_FUNCTION */
-+PHP_RSHUTDOWN_FUNCTION(http)
-+{
-+ STATUS status = SUCCESS;
-+
-+ if (0
-+#ifdef HTTP_HAVE_ZLIB
-+ || SUCCESS != PHP_RSHUTDOWN_CALL(http_encoding)
-+#endif
-+#ifdef HTTP_HAVE_CURL
-+# ifdef ZEND_ENGINE_2
-+ || SUCCESS != PHP_RSHUTDOWN_CALL(http_request_datashare)
-+# endif
-+#endif
-+ || SUCCESS != PHP_RSHUTDOWN_CALL(http_request_method)
-+ ) {
-+ status = FAILURE;
-+ }
-+
-+ http_globals_free(HTTP_G);
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ PHP_MINFO_FUNCTION */
-+PHP_MINFO_FUNCTION(http)
-+{
-+ php_info_print_table_start();
-+ {
-+ php_info_print_table_header(2, "HTTP Support", "enabled");
-+ php_info_print_table_row(2, "Extension Version", PHP_HTTP_VERSION);
-+ php_info_print_table_row(2, "Registered Classes",
-+#ifndef ZEND_ENGINE_2
-+ "none"
-+#else
-+ "HttpUtil, "
-+ "HttpMessage, "
-+# ifdef HTTP_HAVE_CURL
-+ "HttpRequest, "
-+ "HttpRequestPool, "
-+ "HttpRequestDataShare, "
-+# endif
-+# ifdef HTTP_HAVE_ZLIB
-+ "HttpDeflateStream, "
-+ "HttpInflateStream, "
-+# endif
-+# ifndef WONKY
-+ "HttpResponse, "
-+# endif
-+ "HttpQueryString"
-+#endif
-+ );
-+ php_info_print_table_row(2, "Output Handlers", "ob_deflatehandler, ob_inflatehandler, ob_etaghandler");
-+ php_info_print_table_row(2, "Stream Filters",
-+#ifndef ZEND_ENGINE_2
-+ "none"
-+#else
-+ "http.chunked_decode, http.chunked_encode, http.deflate, http.inflate"
-+#endif
-+ );
-+ }
-+ php_info_print_table_end();
-+
-+ php_info_print_table_start();
-+ php_info_print_table_header(3, "Used Library", "Compiled", "Linked");
-+ {
-+#ifdef HTTP_HAVE_CURL
-+ curl_version_info_data *cv = curl_version_info(CURLVERSION_NOW);
-+ php_info_print_table_row(3, "libcurl", LIBCURL_VERSION, cv->version);
-+#else
-+ php_info_print_table_row(2, "libcurl", "disabled", "disabled");
-+#endif
-+#ifdef HTTP_HAVE_EVENT
-+ php_info_print_table_row(3, "libevent", HTTP_EVENT_VERSION, event_get_version());
-+#else
-+ php_info_print_table_row(3, "libevent", "disabled", "disabled");
-+#endif
-+#ifdef HTTP_HAVE_ZLIB
-+ php_info_print_table_row(3, "libz", ZLIB_VERSION, zlibVersion());
-+#else
-+ php_info_print_table_row(3, "libz", "disabled", "disabled");
-+#endif
-+#if defined(HTTP_HAVE_MAGIC)
-+ php_info_print_table_row(3, "libmagic", "unknown", "unknown");
-+#else
-+ php_info_print_table_row(3, "libmagic", "disabled", "disabled");
-+#endif
-+ }
-+ php_info_print_table_end();
-+
-+ php_info_print_table_start();
-+ php_info_print_table_colspan_header(4, "Persistent Handles");
-+ php_info_print_table_header(4, "Provider", "Ident", "Used", "Free");
-+ {
-+ HashTable *ht;
-+ HashPosition pos1, pos2;
-+ HashKey provider = initHashKey(0), ident = initHashKey(0);
-+ zval **val, **sub, **zused, **zfree;
-+
-+ if ((ht = http_persistent_handle_statall()) && zend_hash_num_elements(ht)) {
-+ FOREACH_HASH_KEYVAL(pos1, ht, provider, val) {
-+ if (zend_hash_num_elements(Z_ARRVAL_PP(val))) {
-+ FOREACH_KEYVAL(pos2, *val, ident, sub) {
-+ if ( SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("used"), (void *) &zused) &&
-+ SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("free"), (void *) &zfree)) {
-+ zval *used = http_zsep(IS_STRING, *zused);
-+ zval *free = http_zsep(IS_STRING, *zfree);
-+ php_info_print_table_row(4, provider.str, ident.str, Z_STRVAL_P(used), Z_STRVAL_P(free));
-+ zval_ptr_dtor(&used);
-+ zval_ptr_dtor(&free);
-+ } else {
-+ php_info_print_table_row(4, provider.str, ident.str, "0", "0");
-+ }
-+ }
-+ } else {
-+ php_info_print_table_row(4, provider.str, "N/A", "0", "0");
-+ }
-+ }
-+ } else {
-+ php_info_print_table_row(4, "N/A", "N/A", "0", "0");
-+ }
-+ if (ht) {
-+ zend_hash_destroy(ht);
-+ FREE_HASHTABLE(ht);
-+ }
-+ }
-+ php_info_print_table_end();
-+
-+ php_info_print_table_start();
-+ php_info_print_table_colspan_header(2, "Request Methods");
-+ {
-+ HashPosition pos;
-+ phpstr *methods = phpstr_new();
-+ char **name;
-+
-+ FOREACH_HASH_VAL(pos, &HTTP_G->request.methods.registered, name) {
-+ if (pos->h) {
-+ phpstr_appendf(methods, "%s, ", *name);
-+ }
-+ }
-+ phpstr_fix(methods);
-+ php_info_print_table_row(2, "Registered", PHPSTR_VAL(methods));
-+ php_info_print_table_row(2, "Allowed", *HTTP_G->request.methods.allowed ? HTTP_G->request.methods.allowed : "(ANY)");
-+ phpstr_free(&methods);
-+ }
-+ php_info_print_table_end();
-+
-+ DISPLAY_INI_ENTRIES();
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http.dsp
-@@ -0,0 +1,257 @@
-+# Microsoft Developer Studio Project File - Name="http" - Package Owner=<4>
-+# Microsoft Developer Studio Generated Build File, Format Version 6.00
-+# ** DO NOT EDIT **
-+
-+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-+
-+CFG=http - Win32 Release_TS
-+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-+!MESSAGE use the Export Makefile command and run
-+!MESSAGE
-+!MESSAGE NMAKE /f "http.mak".
-+!MESSAGE
-+!MESSAGE You can specify a configuration when running NMAKE
-+!MESSAGE by defining the macro CFG on the command line. For example:
-+!MESSAGE
-+!MESSAGE NMAKE /f "http.mak" CFG="http - Win32 Release_TS"
-+!MESSAGE
-+!MESSAGE Possible choices for configuration are:
-+!MESSAGE
-+!MESSAGE "http - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
-+!MESSAGE "http - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
-+!MESSAGE
-+
-+# Begin Project
-+# PROP AllowPerConfigDependencies 0
-+# PROP Scc_ProjName ""
-+# PROP Scc_LocalPath ""
-+CPP=cl.exe
-+MTL=midl.exe
-+RSC=rc.exe
-+
-+!IF "$(CFG)" == "http - Win32 Release_TS"
-+
-+# PROP BASE Use_MFC 0
-+# PROP BASE Use_Debug_Libraries 0
-+# PROP BASE Output_Dir "Release_TS"
-+# PROP BASE Intermediate_Dir "Release_TS"
-+# PROP BASE Ignore_Export_Lib 0
-+# PROP BASE Target_Dir ""
-+# PROP Use_MFC 0
-+# PROP Use_Debug_Libraries 0
-+# PROP Output_Dir "Release_TS"
-+# PROP Intermediate_Dir "Release_TS"
-+# PROP Ignore_Export_Lib 0
-+# PROP Target_Dir ""
-+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_HTTP" /D ZTS=1 /YX /FD /c
-+# ADD CPP /nologo /Gd /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HTTP_EXPORTS" /D "COMPILE_DL_HTTP" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_HTTP=1 /D HTTP_HAVE_CURL=1 /D HAVE_CURL_EASY_STRERROR=1 /D HAVE_CURL_SHARE_STRERROR=1 /D HAVE_CURL_MULTI_STRERROR=1 /D HAVE_CURL_EASY_RESET=1 /D HAVE_CURL_FORMGET=1 /D HAVE_GETHOSTNAME=1 /D HAVE_GETSERVBYPORT=1 /D HAVE_GETSERVBYNAME=1 /D "_WINSOCKAPI_=" /FR /YX /FD /c
-+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-+# ADD BASE RSC /l 0x406 /d "NDEBUG"
-+# ADD RSC /l 0x406 /d "NDEBUG"
-+BSC32=bscmake.exe
-+# ADD BASE BSC32 /nologo
-+# ADD BSC32 /nologo
-+LINK32=link.exe
-+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386
-+# ADD LINK32 libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_http.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline"
-+
-+!ELSEIF "$(CFG)" == "http - Win32 Debug_TS"
-+
-+# PROP BASE Use_MFC 0
-+# PROP BASE Use_Debug_Libraries 0
-+# PROP BASE Output_Dir "Debug_TS"
-+# PROP BASE Intermediate_Dir "Debug_TS"
-+# PROP BASE Ignore_Export_Lib 0
-+# PROP BASE Target_Dir ""
-+# PROP Use_MFC 0
-+# PROP Use_Debug_Libraries 0
-+# PROP Output_Dir "Debug_TS"
-+# PROP Intermediate_Dir "Debug_TS"
-+# PROP Ignore_Export_Lib 0
-+# PROP Target_Dir ""
-+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_HTTP" /D ZTS=1 /YX /FD /c
-+# ADD CPP /nologo /MDd /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HTTP_EXPORTS" /D "COMPILE_DL_HTTP" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_HTTP=1 /D HTTP_HAVE_CURL=1 /D HAVE_CURL_EASY_STRERROR=1 /D HAVE_CURL_SHARE_STRERROR=1 /D HAVE_CURL_MULTI_STRERROR=1 /D HAVE_CURL_EASY_RESET=1 /D HAVE_CURL_FORMGET=1 /D HAVE_GETHOSTNAME=1 /D HAVE_GETSERVBYPORT=1 /D HAVE_GETSERVBYNAME=1 /D "_WINSOCKAPI_=" /YX /FD /c
-+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-+# ADD BASE RSC /l 0x406 /d "NDEBUG"
-+# ADD RSC /l 0x406 /d "NDEBUG"
-+BSC32=bscmake.exe
-+# ADD BASE BSC32 /nologo
-+# ADD BSC32 /nologo
-+LINK32=link.exe
-+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386
-+# ADD LINK32 libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/http.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline"
-+
-+!ENDIF
-+
-+# Begin Target
-+
-+# Name "http - Win32 Release_TS"
-+# Name "http - Win32 Debug_TS"
-+# Begin Group "Source Files"
-+
-+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-+# Begin Source File
-+
-+SOURCE=.\http.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_encoding_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_request_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_request_info.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_request_body_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_request_method_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_functions.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_persistent_handle_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_cache_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_cookie_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_date_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_headers_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_message_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_send_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_url_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_querystring_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\http_info_api.c
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\phpstr\phpstr.c
-+# End Source File
-+# End Group
-+# Begin Group "Header Files"
-+
-+# PROP Default_Filter "h;hpp;hxx;hm;inl"
-+# Begin Source File
-+
-+SOURCE=.\php_http.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_encoding_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_request_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_request_int.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_request_body_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_request_method_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_persistent_handle_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_cache_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_cookie_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_date_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_message_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_send_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_headers_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_url_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_querystring_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_info_api.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\php_http_std_defs.h
-+# End Source File
-+# Begin Source File
-+
-+SOURCE=.\phpstr\phpstr.h
-+# End Source File
-+# End Group
-+# Begin Group "Resource Files"
-+
-+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-+# End Group
-+# End Target
-+# End Project
---- /dev/null
-+++ b/ext/http/http_api.c
-@@ -0,0 +1,754 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_api.c 323405 2012-02-21 10:05:05Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#include "php_http.h"
-+
-+#include "php_output.h"
-+#include "ext/standard/url.h"
-+#include "ext/standard/php_lcg.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_send_api.h"
-+
-+#ifdef ZEND_ENGINE_2
-+# include "php_http_exception_object.h"
-+#endif
-+
-+PHP_MINIT_FUNCTION(http_support)
-+{
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT", HTTP_SUPPORT);
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_REQUESTS", HTTP_SUPPORT_REQUESTS);
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_MAGICMIME", HTTP_SUPPORT_MAGICMIME);
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_ENCODINGS", HTTP_SUPPORT_ENCODINGS);
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_SSLREQUESTS", HTTP_SUPPORT_SSLREQUESTS);
-+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_EVENTS", HTTP_SUPPORT_EVENTS);
-+
-+ HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_COMMA", HTTP_PARAMS_ALLOW_COMMA);
-+ HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_FAILURE", HTTP_PARAMS_ALLOW_FAILURE);
-+ HTTP_LONG_CONSTANT("HTTP_PARAMS_RAISE_ERROR", HTTP_PARAMS_RAISE_ERROR);
-+ HTTP_LONG_CONSTANT("HTTP_PARAMS_DEFAULT", HTTP_PARAMS_DEFAULT);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API long _http_support(long feature)
-+{
-+ long support = HTTP_SUPPORT;
-+
-+#ifdef HTTP_HAVE_CURL
-+ support |= HTTP_SUPPORT_REQUESTS;
-+# ifdef HTTP_HAVE_SSL
-+ support |= HTTP_SUPPORT_SSLREQUESTS;
-+# endif
-+# ifdef HTTP_HAVE_EVENT
-+ support |= HTTP_SUPPORT_EVENTS;
-+# endif
-+#endif
-+#ifdef HTTP_HAVE_MAGIC
-+ support |= HTTP_SUPPORT_MAGICMIME;
-+#endif
-+#ifdef HTTP_HAVE_ZLIB
-+ support |= HTTP_SUPPORT_ENCODINGS;
-+#endif
-+
-+ if (feature) {
-+ return (feature == (support & feature));
-+ }
-+ return support;
-+}
-+
-+/* char *pretty_key(char *, size_t, zend_bool, zend_bool) */
-+char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
-+{
-+ size_t i;
-+ int wasalpha;
-+
-+ if (key && key_len) {
-+ if ((wasalpha = HTTP_IS_CTYPE(alpha, key[0]))) {
-+ key[0] = (char) (uctitle ? HTTP_TO_CTYPE(upper, key[0]) : HTTP_TO_CTYPE(lower, key[0]));
-+ }
-+ for (i = 1; i < key_len; i++) {
-+ if (HTTP_IS_CTYPE(alpha, key[i])) {
-+ key[i] = (char) (((!wasalpha) && uctitle) ? HTTP_TO_CTYPE(upper, key[i]) : HTTP_TO_CTYPE(lower, key[i]));
-+ wasalpha = 1;
-+ } else {
-+ if (xhyphen && (key[i] == '_')) {
-+ key[i] = '-';
-+ }
-+ wasalpha = 0;
-+ }
-+ }
-+ }
-+ return key;
-+}
-+/* }}} */
-+
-+/* {{{ http_boundary(char *, size_t) */
-+size_t _http_boundary(char *buf, size_t buf_len TSRMLS_DC)
-+{
-+ return snprintf(buf, buf_len, "%lu%0.9f", (ulong) HTTP_G->request.time, (float) php_combined_lcg(TSRMLS_C));
-+}
-+/* }}} */
-+
-+/* {{{ void http_error(long, long, char*) */
-+void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...)
-+{
-+ va_list args;
-+
-+ va_start(args, format);
-+#ifdef ZEND_ENGINE_2
-+ if ((type == E_THROW) || (GLOBAL_ERROR_HANDLING == EH_THROW)) {
-+ char *message;
-+ zend_class_entry *ce = http_exception_get_for_code(code);
-+
-+ http_try {
-+ vspprintf(&message, 0, format, args);
-+ zend_throw_exception(ce, message, code TSRMLS_CC);
-+ efree(message);
-+ } http_catch(GLOBAL_EXCEPTION_CLASS ? GLOBAL_EXCEPTION_CLASS : HTTP_EX_DEF_CE);
-+ } else
-+#endif
-+ php_verror(NULL, "", type, format, args TSRMLS_CC);
-+ va_end(args);
-+}
-+/* }}} */
-+
-+#ifdef ZEND_ENGINE_2
-+static inline void copy_bt_args(zval *from, zval *to TSRMLS_DC)
-+{
-+ zval **args, **trace_0, *old_trace_0, *trace = NULL;
-+
-+ if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), from, "trace", lenof("trace"), 0 TSRMLS_CC))) {
-+ if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
-+ old_trace_0 = *trace_0;
-+ if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) {
-+ if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), to, "trace", lenof("trace"), 0 TSRMLS_CC))) {
-+ if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
-+ ZVAL_ADDREF(*args);
-+ add_assoc_zval(*trace_0, "args", *args);
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */
-+zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC)
-+{
-+ int inner = 1;
-+ char *message;
-+ zval *sub_exception, *tmp_exception;
-+
-+ if (!new_exception) {
-+ MAKE_STD_ZVAL(new_exception);
-+ object_init_ex(new_exception, ce);
-+
-+ zend_update_property(ce, new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
-+ copy_bt_args(old_exception, new_exception TSRMLS_CC);
-+
-+ sub_exception = old_exception;
-+
-+ while ((sub_exception = zend_read_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(sub_exception) == IS_OBJECT) {
-+ ++inner;
-+ }
-+
-+ spprintf(&message, 0, "Exception caused by %d inner exception(s)", inner);
-+ zend_update_property_string(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "message", lenof("message"), message TSRMLS_CC);
-+ efree(message);
-+ } else {
-+ sub_exception = new_exception;
-+ tmp_exception = new_exception;
-+
-+ while ((tmp_exception = zend_read_property(Z_OBJCE_P(tmp_exception), tmp_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(tmp_exception) == IS_OBJECT) {
-+ sub_exception = tmp_exception;
-+ }
-+
-+ zend_update_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
-+ copy_bt_args(old_exception, new_exception TSRMLS_CC);
-+ copy_bt_args(old_exception, sub_exception TSRMLS_CC);
-+ }
-+#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3
-+ Z_ADDREF_P(old_exception);
-+ zend_exception_set_previous(new_exception, old_exception TSRMLS_CC);
-+#endif
-+ zval_ptr_dtor(&old_exception);
-+ return new_exception;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_object_new(zend_object_value *, const char *, uint, http_object_new_t, zend_class_entry *, void *, void **) */
-+STATUS _http_object_new(zend_object_value *ov, const char *cname_str, uint cname_len, http_object_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC)
-+{
-+ zend_class_entry *ce = parent_ce;
-+
-+ if (cname_str && cname_len) {
-+ if (!(ce = zend_fetch_class(HTTP_ZAPI_CONST_CAST(char *) cname_str, cname_len, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC))) {
-+ return FAILURE;
-+ }
-+ if (!instanceof_function(ce, parent_ce TSRMLS_CC)) {
-+ http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Class %s does not extend %s", cname_str, parent_ce->name);
-+ return FAILURE;
-+ }
-+ }
-+
-+ *ov = create(ce, intern_ptr, obj_ptr TSRMLS_CC);
-+ return SUCCESS;
-+}
-+/* }}} */
-+#endif /* ZEND_ENGINE_2 */
-+
-+/* {{{ void http_log(char *, char *, char *) */
-+void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC)
-+{
-+ time_t now;
-+ struct tm nowtm;
-+ char datetime[20] = {0};
-+
-+ now = HTTP_G->request.time;
-+ strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", php_localtime_r(&now, &nowtm));
-+
-+#define HTTP_LOG_WRITE(file, type, msg) \
-+ if (file && *file) { \
-+ php_stream *log = php_stream_open_wrapper_ex(file, "ab", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT); \
-+ \
-+ if (log) { \
-+ php_stream_printf(log TSRMLS_CC, "%s\t[%s]\t%s\t<%s>%s", datetime, type, msg, SG(request_info).request_uri, PHP_EOL); \
-+ php_stream_close(log); \
-+ } \
-+ \
-+ }
-+
-+ HTTP_LOG_WRITE(file, ident, message);
-+ HTTP_LOG_WRITE(HTTP_G->log.composite, ident, message);
-+}
-+/* }}} */
-+
-+static void http_ob_blackhole(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
-+{
-+ *handled_output = ecalloc(1,1);
-+ *handled_output_len = 0;
-+}
-+
-+/* {{{ STATUS http_exit(int, char*, char*) */
-+STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header TSRMLS_DC)
-+{
-+ if ( (send_header && (SUCCESS != http_send_status_header(status, header))) ||
-+ (status && (SUCCESS != http_send_status(status)))) {
-+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, STR_PTR(header));
-+ STR_FREE(header);
-+ STR_FREE(body);
-+ return FAILURE;
-+ }
-+
-+#ifndef PHP_OUTPUT_NEWAPI
-+ if (!OG(ob_lock) &&
-+ !php_ob_handler_used("zlib output compression" TSRMLS_CC) && !php_ob_handler_used("ob_gzhandler" TSRMLS_CC)) {
-+ php_end_ob_buffers(0 TSRMLS_CC);
-+ }
-+#endif
-+
-+ if ((SUCCESS == sapi_send_headers(TSRMLS_C)) && body) {
-+ PHPWRITE(body, strlen(body));
-+ }
-+
-+ switch (status) {
-+ case 301: http_log(HTTP_G->log.redirect, "301-REDIRECT", header); break;
-+ case 302: http_log(HTTP_G->log.redirect, "302-REDIRECT", header); break;
-+ case 303: http_log(HTTP_G->log.redirect, "303-REDIRECT", header); break;
-+ case 305: http_log(HTTP_G->log.redirect, "305-REDIRECT", header); break;
-+ case 307: http_log(HTTP_G->log.redirect, "307-REDIRECT", header); break;
-+ case 304: http_log(HTTP_G->log.cache, "304-CACHE", header); break;
-+ case 404: http_log(HTTP_G->log.not_found, "404-NOTFOUND", NULL); break;
-+ case 405: http_log(HTTP_G->log.allowed_methods, "405-ALLOWED", header); break;
-+ default: http_log(NULL, header, body); break;
-+ }
-+
-+ STR_FREE(header);
-+ STR_FREE(body);
-+
-+ if (HTTP_G->force_exit) {
-+ zend_bailout();
-+ } else {
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_start_devnull(TSRMLS_C);
-+#else
-+ php_ob_set_internal_handler(http_ob_blackhole, 4096, "blackhole", 0 TSRMLS_CC);
-+#endif
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_check_method(char *) */
-+STATUS _http_check_method_ex(const char *method, const char *methods)
-+{
-+ const char *found;
-+
-+ if ( (found = strstr(methods, method)) &&
-+ (found == method || !HTTP_IS_CTYPE(alpha, found[-1])) &&
-+ (strlen(found) >= strlen(method) && !HTTP_IS_CTYPE(alpha, found[strlen(method)]))) {
-+ return SUCCESS;
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ zval *http_get_server_var_ex(char *, size_t) */
-+PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_len, zend_bool check TSRMLS_DC)
-+{
-+ zval **hsv, **var;
-+ char *env;
-+
-+ /* if available, this is a lot faster than accessing $_SERVER */
-+ if (sapi_module.getenv) {
-+ if ((!(env = sapi_module.getenv((char *) key, key_len TSRMLS_CC))) || (check && !*env)) {
-+ return NULL;
-+ }
-+ if (HTTP_G->server_var) {
-+ zval_ptr_dtor(&HTTP_G->server_var);
-+ }
-+ MAKE_STD_ZVAL(HTTP_G->server_var);
-+ ZVAL_STRING(HTTP_G->server_var, env, 1);
-+ return HTTP_G->server_var;
-+ }
-+
-+#ifdef ZEND_ENGINE_2
-+ zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
-+#endif
-+
-+ if ((SUCCESS != zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv)) || (Z_TYPE_PP(hsv) != IS_ARRAY)) {
-+ return NULL;
-+ }
-+ if ((SUCCESS != zend_hash_find(Z_ARRVAL_PP(hsv), HTTP_ZAPI_CONST_CAST(char *) key, key_len + 1, (void *) &var))) {
-+ return NULL;
-+ }
-+ if (check && !((Z_TYPE_PP(var) == IS_STRING) && Z_STRVAL_PP(var) && Z_STRLEN_PP(var))) {
-+ return NULL;
-+ }
-+ return *var;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_get_request_body(char **, size_t *) */
-+PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_bool dup TSRMLS_DC)
-+{
-+ *length = 0;
-+ *body = NULL;
-+
-+ if (SG(request_info).raw_post_data) {
-+ *length = SG(request_info).raw_post_data_length;
-+ *body = SG(request_info).raw_post_data;
-+
-+ if (dup) {
-+ *body = estrndup(*body, *length);
-+ }
-+ return SUCCESS;
-+ } else if (sapi_module.read_post && !HTTP_G->read_post_data) {
-+ char *buf = emalloc(4096);
-+ int len;
-+
-+ HTTP_G->read_post_data = 1;
-+
-+ while (0 < (len = sapi_module.read_post(buf, 4096 TSRMLS_CC))) {
-+ SG(read_post_bytes) += len;
-+ *body = erealloc(*body, *length + len + 1);
-+ memcpy(*body + *length, buf, len);
-+ *length += len;
-+ (*body)[*length] = '\0';
-+ if (len < 4096) {
-+ break;
-+ }
-+ }
-+ efree(buf);
-+
-+ /* check for error */
-+ if (len < 0) {
-+ STR_FREE(*body);
-+ *length = 0;
-+ return FAILURE;
-+ }
-+
-+ SG(request_info).raw_post_data = *body;
-+ SG(request_info).raw_post_data_length = *length;
-+
-+ if (dup) {
-+ *body = estrndup(*body, *length);
-+ }
-+ return SUCCESS;
-+ }
-+
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ php_stream *http_get_request_body_stream(void) */
-+PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D)
-+{
-+ php_stream *s = NULL;
-+
-+ if (SG(request_info).raw_post_data) {
-+ s = php_stream_open_wrapper("php://input", "rb", 0, NULL);
-+ } else if (sapi_module.read_post && !HTTP_G->read_post_data) {
-+ HTTP_G->read_post_data = 1;
-+
-+ if ((s = php_stream_temp_new())) {
-+ char *buf = emalloc(4096);
-+ int len;
-+
-+ while (0 < (len = sapi_module.read_post(buf, 4096 TSRMLS_CC))) {
-+ SG(read_post_bytes) += len;
-+ php_stream_write(s, buf, len);
-+ if (len < 4096) {
-+ break;
-+ }
-+ }
-+ efree(buf);
-+
-+ if (len < 0) {
-+ php_stream_close(s);
-+ s = NULL;
-+ } else {
-+ php_stream_rewind(s);
-+ }
-+ }
-+ }
-+
-+ return s;
-+}
-+/* }}} */
-+
-+/* {{{ void http_parse_params_default_callback(...) */
-+PHP_HTTP_API void _http_parse_params_default_callback(void *arg, const char *key, int keylen, const char *val, int vallen TSRMLS_DC)
-+{
-+ char *kdup;
-+ zval tmp, *entry;
-+ HashTable *ht = (HashTable *) arg;
-+
-+ if (ht) {
-+ INIT_ZARR(tmp, ht);
-+
-+ if (vallen) {
-+ MAKE_STD_ZVAL(entry);
-+ array_init(entry);
-+ if (keylen) {
-+ kdup = estrndup(key, keylen);
-+ add_assoc_stringl_ex(entry, kdup, keylen + 1, (char *) val, vallen, 1);
-+ efree(kdup);
-+ } else {
-+ add_next_index_stringl(entry, (char *) val, vallen, 1);
-+ }
-+ add_next_index_zval(&tmp, entry);
-+ } else {
-+ add_next_index_stringl(&tmp, (char *) key, keylen, 1);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_parse_params(const char *, HashTable *) */
-+PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_parse_params_callback cb, void *cb_arg TSRMLS_DC)
-+{
-+#define ST_QUOTE 1
-+#define ST_VALUE 2
-+#define ST_KEY 3
-+#define ST_ASSIGN 4
-+#define ST_ADD 5
-+
-+ int st = ST_KEY, keylen = 0, vallen = 0;
-+ char *s, *c, *key = NULL, *val = NULL;
-+
-+ for(c = s = estrdup(param);;) {
-+ continued:
-+#if 0
-+ {
-+ char *tk = NULL, *tv = NULL;
-+
-+ if (key) {
-+ if (keylen) {
-+ tk= estrndup(key, keylen);
-+ } else {
-+ tk = ecalloc(1, 7);
-+ memcpy(tk, key, 3);
-+ tk[3]='.'; tk[4]='.'; tk[5]='.';
-+ }
-+ }
-+ if (val) {
-+ if (vallen) {
-+ tv = estrndup(val, vallen);
-+ } else {
-+ tv = ecalloc(1, 7);
-+ memcpy(tv, val, 3);
-+ tv[3]='.'; tv[4]='.'; tv[5]='.';
-+ }
-+ }
-+ fprintf(stderr, "[%6s] %c \"%s=%s\"\n",
-+ (
-+ st == ST_QUOTE ? "QUOTE" :
-+ st == ST_VALUE ? "VALUE" :
-+ st == ST_KEY ? "KEY" :
-+ st == ST_ASSIGN ? "ASSIGN" :
-+ st == ST_ADD ? "ADD":
-+ "HUH?"
-+ ), *c?*c:'0', tk, tv
-+ );
-+ STR_FREE(tk); STR_FREE(tv);
-+ }
-+#endif
-+ switch (st) {
-+ case ST_QUOTE:
-+ quote:
-+ if (*c == '"') {
-+ if (*(c-1) == '\\') {
-+ memmove(c-1, c, strlen(c)+1);
-+ goto quote;
-+ } else {
-+ goto add;
-+ }
-+ } else {
-+ if (!val) {
-+ val = c;
-+ }
-+ if (!*c) {
-+ --val;
-+ st = ST_ADD;
-+ }
-+ }
-+ break;
-+
-+ case ST_VALUE:
-+ switch (*c) {
-+ case '"':
-+ if (!val) {
-+ st = ST_QUOTE;
-+ }
-+ break;
-+
-+ case ' ':
-+ break;
-+
-+ case ';':
-+ case '\0':
-+ goto add;
-+ break;
-+ case ',':
-+ if (flags & HTTP_PARAMS_ALLOW_COMMA) {
-+ goto add;
-+ }
-+ default:
-+ if (!val) {
-+ val = c;
-+ }
-+ break;
-+ }
-+ break;
-+
-+ case ST_KEY:
-+ switch (*c) {
-+ case ',':
-+ if (flags & HTTP_PARAMS_ALLOW_COMMA) {
-+ goto allow_comma;
-+ }
-+ case '\r':
-+ case '\n':
-+ case '\t':
-+ case '\013':
-+ case '\014':
-+ goto failure;
-+ break;
-+
-+ case ' ':
-+ if (key) {
-+ keylen = c - key;
-+ st = ST_ASSIGN;
-+ }
-+ break;
-+
-+ case ';':
-+ case '\0':
-+ allow_comma:
-+ if (key) {
-+ keylen = c-- - key;
-+ st = ST_ADD;
-+ }
-+ break;
-+
-+ case ':':
-+ if (!(flags & HTTP_PARAMS_COLON_SEPARATOR)) {
-+ goto not_separator;
-+ }
-+ if (key) {
-+ keylen = c - key;
-+ st = ST_VALUE;
-+ } else {
-+ goto failure;
-+ }
-+ break;
-+
-+ case '=':
-+ if (flags & HTTP_PARAMS_COLON_SEPARATOR) {
-+ goto not_separator;
-+ }
-+ if (key) {
-+ keylen = c - key;
-+ st = ST_VALUE;
-+ } else {
-+ goto failure;
-+ }
-+ break;
-+
-+ default:
-+ not_separator:
-+ if (!key) {
-+ key = c;
-+ }
-+ break;
-+ }
-+ break;
-+
-+ case ST_ASSIGN:
-+ if (*c == '=') {
-+ st = ST_VALUE;
-+ } else if (!*c || *c == ';' || ((flags & HTTP_PARAMS_ALLOW_COMMA) && *c == ',')) {
-+ st = ST_ADD;
-+ } else if (*c != ' ') {
-+ goto failure;
-+ }
-+ break;
-+
-+ case ST_ADD:
-+ add:
-+ if (val) {
-+ vallen = c - val;
-+ if (st != ST_QUOTE) {
-+ while (val[vallen-1] == ' ') --vallen;
-+ }
-+ } else {
-+ val = "";
-+ vallen = 0;
-+ }
-+
-+ cb(cb_arg, key, keylen, val, vallen TSRMLS_CC);
-+
-+ st = ST_KEY;
-+ key = val = NULL;
-+ keylen = vallen = 0;
-+ break;
-+ }
-+ if (*c) {
-+ ++c;
-+ } else if (st == ST_ADD) {
-+ goto add;
-+ } else {
-+ break;
-+ }
-+ }
-+
-+ efree(s);
-+ return SUCCESS;
-+
-+failure:
-+ if (flags & HTTP_PARAMS_RAISE_ERROR) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Unexpected character (%c) at pos %tu of %zu", *c, c-s, strlen(s));
-+ }
-+ if (flags & HTTP_PARAMS_ALLOW_FAILURE) {
-+ if (st == ST_KEY) {
-+ if (key) {
-+ keylen = c - key;
-+ } else {
-+ key = c;
-+ }
-+ } else {
-+ --c;
-+ }
-+ st = ST_ADD;
-+ goto continued;
-+ }
-+ efree(s);
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ array_join */
-+int apply_array_append_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
-+{
-+ int flags;
-+ char *key = NULL;
-+ HashTable *dst;
-+ zval **data = NULL, **value = (zval **) pDest;
-+
-+ dst = va_arg(args, HashTable *);
-+ flags = va_arg(args, int);
-+
-+ if ((!(flags & ARRAY_JOIN_STRONLY)) || hash_key->nKeyLength) {
-+ if ((flags & ARRAY_JOIN_PRETTIFY) && hash_key->nKeyLength) {
-+ key = pretty_key(estrndup(hash_key->arKey, hash_key->nKeyLength - 1), hash_key->nKeyLength - 1, 1, 1);
-+ zend_hash_find(dst, key, hash_key->nKeyLength, (void *) &data);
-+ } else {
-+ zend_hash_quick_find(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void *) &data);
-+ }
-+
-+ ZVAL_ADDREF(*value);
-+ if (data) {
-+ add_next_index_zval(http_zset(IS_ARRAY, *data), *value);
-+ } else if (key) {
-+ zend_hash_add(dst, key, hash_key->nKeyLength, value, sizeof(zval *), NULL);
-+ } else {
-+ zend_hash_quick_add(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, value, sizeof(zval *), NULL);
-+ }
-+
-+ if (key) {
-+ efree(key);
-+ }
-+ }
-+
-+ return ZEND_HASH_APPLY_KEEP;
-+}
-+
-+int apply_array_merge_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
-+{
-+ int flags;
-+ char *key = NULL;
-+ HashTable *dst;
-+ zval **value = (zval **) pDest;
-+
-+ dst = va_arg(args, HashTable *);
-+ flags = va_arg(args, int);
-+
-+ if ((!(flags & ARRAY_JOIN_STRONLY)) || hash_key->nKeyLength) {
-+ ZVAL_ADDREF(*value);
-+ if ((flags & ARRAY_JOIN_PRETTIFY) && hash_key->nKeyLength) {
-+ key = pretty_key(estrndup(hash_key->arKey, hash_key->nKeyLength - 1), hash_key->nKeyLength - 1, 1, 1);
-+ zend_hash_update(dst, key, hash_key->nKeyLength, (void *) value, sizeof(zval *), NULL);
-+ efree(key);
-+ } else {
-+ zend_hash_quick_update(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void *) value, sizeof(zval *), NULL);
-+ }
-+ }
-+
-+ return ZEND_HASH_APPLY_KEEP;
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_cache_api.c
-@@ -0,0 +1,267 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_cache_api.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#include "php_http.h"
-+
-+#include "php_output.h"
-+#include "php_streams.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_cache_api.h"
-+#include "php_http_date_api.h"
-+#include "php_http_send_api.h"
-+
-+/* {{{ char *http_etag(void *, size_t, http_send_mode) */
-+PHP_HTTP_API char *_http_etag(const void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC)
-+{
-+ void *ctx = http_etag_init();
-+
-+ if (data_mode == SEND_DATA) {
-+ http_etag_update(ctx, data_ptr, data_len);
-+ } else {
-+ STATUS ss = FAILURE;
-+ php_stream_statbuf ssb;
-+
-+ if (data_mode == SEND_RSRC) {
-+ ss = php_stream_stat((php_stream *) data_ptr, &ssb);
-+ } else {
-+ ss = php_stream_stat_path((char *) data_ptr, &ssb);
-+ }
-+
-+ if (SUCCESS != ss) {
-+ efree(ctx);
-+ return NULL;
-+ } else {
-+ size_t ssb_len;
-+ char ssb_buf[128];
-+
-+ ssb_len = snprintf(ssb_buf, sizeof(ssb_buf), "%ld=%ld=%ld", (long) ssb.sb.st_mtime,
-+ (long) ssb.sb.st_ino,
-+ (long) ssb.sb.st_size);
-+ http_etag_update(ctx, ssb_buf, ssb_len);
-+ }
-+ }
-+
-+ return http_etag_finish(ctx);
-+}
-+/* }}} */
-+
-+/* {{{ time_t http_last_modified(void *, http_send_mode) */
-+PHP_HTTP_API time_t _http_last_modified(const void *data_ptr, http_send_mode data_mode TSRMLS_DC)
-+{
-+ php_stream_statbuf ssb;
-+
-+ switch (data_mode) {
-+ case SEND_DATA: return HTTP_G->request.time;
-+ case SEND_RSRC: return php_stream_stat((php_stream *) data_ptr, &ssb) ? 0 : ssb.sb.st_mtime;
-+ default: return php_stream_stat_path((char *) data_ptr, &ssb) ? 0 : ssb.sb.st_mtime;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ zend_bool http_match_last_modified(char *, time_t) */
-+PHP_HTTP_API zend_bool _http_match_last_modified_ex(const char *entry, time_t t, zend_bool enforce_presence TSRMLS_DC)
-+{
-+ zend_bool retval;
-+ zval *zmodified;
-+ char *modified, *chr_ptr;
-+
-+ if (!(zmodified = http_get_server_var(entry, 1))) {
-+ return !enforce_presence;
-+ }
-+
-+ modified = estrndup(Z_STRVAL_P(zmodified), Z_STRLEN_P(zmodified));
-+ if ((chr_ptr = strrchr(modified, ';'))) {
-+ chr_ptr = 0;
-+ }
-+
-+ retval = (t <= http_parse_date_ex(modified, 1));
-+ efree(modified);
-+ return retval;
-+}
-+/* }}} */
-+
-+/* {{{ zend_bool http_match_etag(char *, char *) */
-+PHP_HTTP_API zend_bool _http_match_etag_ex(const char *entry, const char *etag, zend_bool enforce_presence TSRMLS_DC)
-+{
-+ zval *zetag;
-+ char *quoted_etag;
-+ zend_bool result;
-+
-+ if (!(zetag = http_get_server_var_ex(entry, strlen(entry)+1, 1))) {
-+ return !enforce_presence;
-+ }
-+
-+ if (NULL != strchr(Z_STRVAL_P(zetag), '*')) {
-+ return 1;
-+ }
-+
-+ spprintf("ed_etag, 0, "\"%s\"", etag);
-+ if (!strchr(Z_STRVAL_P(zetag), ',')) {
-+ result = !strcmp(Z_STRVAL_P(zetag), quoted_etag);
-+ } else {
-+ result = (NULL != strstr(Z_STRVAL_P(zetag), quoted_etag));
-+ }
-+ efree(quoted_etag);
-+
-+ return result;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_cache_last_modified(time_t, time_t, char *, size_t) */
-+PHP_HTTP_API STATUS _http_cache_last_modified(time_t last_modified,
-+ time_t send_modified, const char *cache_control, size_t cc_len TSRMLS_DC)
-+{
-+ char *sent_header = NULL;
-+
-+ if (SG(headers_sent)) {
-+ return FAILURE;
-+ }
-+
-+ if (cc_len && (SUCCESS != http_send_cache_control(cache_control, cc_len))) {
-+ return FAILURE;
-+ }
-+
-+ if (SUCCESS != http_send_last_modified_ex(send_modified, &sent_header)) {
-+ return FAILURE;
-+ }
-+
-+ if (http_match_last_modified("HTTP_IF_MODIFIED_SINCE", last_modified)) {
-+ http_exit_ex(304, sent_header, NULL, 0);
-+ } else {
-+ STR_FREE(sent_header);
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_cache_etag(char *, size_t, char *, size_t) */
-+PHP_HTTP_API STATUS _http_cache_etag(const char *etag, size_t etag_len,
-+ const char *cache_control, size_t cc_len TSRMLS_DC)
-+{
-+ char *sent_header = NULL;
-+
-+ if (SG(headers_sent)) {
-+ return FAILURE;
-+ }
-+
-+ if (cc_len && (SUCCESS != http_send_cache_control(cache_control, cc_len))) {
-+ return FAILURE;
-+ }
-+
-+ if (etag_len) {
-+ if (SUCCESS != http_send_etag_ex(etag, etag_len, &sent_header)) {
-+ return FAILURE;
-+ }
-+ if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
-+ http_exit_ex(304, sent_header, NULL, 0);
-+ } else {
-+ STR_FREE(sent_header);
-+ }
-+ return SUCCESS;
-+ }
-+
-+ /* start ob_etaghandler */
-+ return http_start_ob_etaghandler();
-+}
-+/* }}} */
-+
-+PHP_HTTP_API STATUS _http_start_ob_etaghandler(TSRMLS_D)
-+{
-+ /* already running? */
-+#ifdef PHP_OUTPUT_NEWAPI
-+ STATUS rv;
-+
-+ if (php_output_handler_conflict(ZEND_STRL("ob_etaghandler"), ZEND_STRL("ob_etaghandler") TSRMLS_CC)) {
-+ return FAILURE;
-+ }
-+#else
-+ if (php_ob_handler_used("ob_etaghandler" TSRMLS_CC)) {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "ob_etaghandler can only be used once");
-+ return FAILURE;
-+ }
-+#endif
-+ HTTP_G->etag.started = 1;
-+#ifdef PHP_OUTPUT_NEWAPI
-+ return php_output_start_internal(ZEND_STRL("ob_etaghandler"), _http_ob_etaghandler, HTTP_G->send.buffer_size, 0 TSRMLS_CC);
-+#else
-+ return php_start_ob_buffer_named("ob_etaghandler", HTTP_G->send.buffer_size, 0 TSRMLS_CC);
-+#endif
-+}
-+
-+PHP_HTTP_API zend_bool _http_interrupt_ob_etaghandler(TSRMLS_D)
-+{
-+ if (HTTP_G->etag.started) {
-+ HTTP_G->etag.started = 0;
-+ if (HTTP_G->etag.ctx) {
-+ efree(HTTP_G->etag.ctx);
-+ HTTP_G->etag.ctx = NULL;
-+ }
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/* {{{ void http_ob_etaghandler(char *, uint, char **, uint *, int) */
-+void _http_ob_etaghandler(char *output, uint output_len,
-+ char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
-+{
-+ /* passthru */
-+ *handled_output_len = output_len;
-+ *handled_output = estrndup(output, output_len);
-+
-+ /* are we supposed to run? */
-+ if (HTTP_G->etag.started) {
-+ /* initialize the etag context */
-+ if (mode & PHP_OUTPUT_HANDLER_START) {
-+ HTTP_G->etag.ctx = http_etag_init();
-+ }
-+
-+ /* update */
-+ http_etag_update(HTTP_G->etag.ctx, output, output_len);
-+
-+ /* finish */
-+ if (mode & PHP_OUTPUT_HANDLER_END) {
-+ char *sent_header = NULL;
-+ char *etag = http_etag_finish(HTTP_G->etag.ctx);
-+
-+ HTTP_G->etag.ctx = NULL;
-+
-+ http_send_cache_control(HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL));
-+ http_send_etag_ex(etag, strlen(etag), &sent_header);
-+
-+ if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
-+ /* force exit; ob within ob does not work */
-+ HTTP_G->force_exit = 1;
-+ http_exit_ex(304, sent_header, etag, 0);
-+ }
-+
-+ STR_FREE(sent_header);
-+ STR_FREE(etag);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_cookie_api.c
-@@ -0,0 +1,371 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_cookie_api.c 298662 2010-04-27 13:42:32Z mike $ */
-+
-+#include "php_http.h"
-+#include "php_http_api.h"
-+#include "php_http_date_api.h"
-+#include "php_http_cookie_api.h"
-+
-+#include "ext/standard/url.h"
-+
-+/* {{{ PHP_MINIT_FUNCTION(http_cookie) */
-+PHP_MINIT_FUNCTION(http_cookie)
-+{
-+ HTTP_LONG_CONSTANT("HTTP_COOKIE_PARSE_RAW", HTTP_COOKIE_PARSE_RAW);
-+ HTTP_LONG_CONSTANT("HTTP_COOKIE_SECURE", HTTP_COOKIE_SECURE);
-+ HTTP_LONG_CONSTANT("HTTP_COOKIE_HTTPONLY", HTTP_COOKIE_HTTPONLY);
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ http_cookie_list *http_cookie_list_init(http_cookie_list *) */
-+PHP_HTTP_API http_cookie_list *_http_cookie_list_init(http_cookie_list *list ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ if (!list) {
-+ list = emalloc_rel(sizeof(http_cookie_list));
-+ }
-+
-+ zend_hash_init(&list->cookies, 0, NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_init(&list->extras, 0, NULL, ZVAL_PTR_DTOR, 0);
-+
-+ list->path = NULL;
-+ list->domain = NULL;
-+ list->expires = 0;
-+ list->flags = 0;
-+
-+ return list;
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_dtor(http_cookie_list *) */
-+PHP_HTTP_API void _http_cookie_list_dtor(http_cookie_list *list TSRMLS_DC)
-+{
-+ if (list) {
-+ zend_hash_destroy(&list->cookies);
-+ zend_hash_destroy(&list->extras);
-+
-+ STR_SET(list->path, NULL);
-+ STR_SET(list->domain, NULL);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_free(http_cookie_list **) */
-+PHP_HTTP_API void _http_cookie_list_free(http_cookie_list **list TSRMLS_DC)
-+{
-+ if (list) {
-+ http_cookie_list_dtor(*list);
-+ efree(*list);
-+ *list = NULL;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ const char *http_cookie_list_get_cookie(http_cookie_list *, const char*, size_t) */
-+PHP_HTTP_API const char *_http_cookie_list_get_cookie(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC)
-+{
-+ zval **cookie = NULL;
-+ if ((SUCCESS != zend_hash_find(&list->cookies, HTTP_ZAPI_CONST_CAST(char *) name, name_len + 1, (void *) &cookie)) || (Z_TYPE_PP(cookie) != IS_STRING)) {
-+ return NULL;
-+ }
-+ return Z_STRVAL_PP(cookie);
-+}
-+/* }}} */
-+
-+/* {{{ const char *http_cookie_list_get_extra(http_cookie_list *, const char *, size_t) */
-+PHP_HTTP_API const char *_http_cookie_list_get_extra(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC)
-+{
-+ zval **extra = NULL;
-+ if ((SUCCESS != zend_hash_find(&list->extras, HTTP_ZAPI_CONST_CAST(char *) name, name_len + 1, (void *) &extra)) || (Z_TYPE_PP(extra) != IS_STRING)) {
-+ return NULL;
-+ }
-+ return Z_STRVAL_PP(extra);
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_add_cookie(http_cookie_list *, const char *, size_t, const char *, size_t) */
-+PHP_HTTP_API void _http_cookie_list_add_cookie(http_cookie_list *list, const char *name, size_t name_len, const char *value, size_t value_len TSRMLS_DC)
-+{
-+ zval *cookie_value;
-+ char *key = estrndup(name, name_len);
-+ MAKE_STD_ZVAL(cookie_value);
-+ ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
-+ zend_hash_update(&list->cookies, key, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
-+ efree(key);
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_add_extr(http_cookie_list *, const char *, size_t, const char *, size_t) */
-+PHP_HTTP_API void _http_cookie_list_add_extra(http_cookie_list *list, const char *name, size_t name_len, const char *value, size_t value_len TSRMLS_DC)
-+{
-+ zval *cookie_value;
-+ char *key = estrndup(name, name_len);
-+ MAKE_STD_ZVAL(cookie_value);
-+ ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
-+ zend_hash_update(&list->extras, key, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
-+ efree(key);
-+}
-+/* }}} */
-+
-+typedef struct _http_parse_param_cb_arg_t {
-+ http_cookie_list *list;
-+ long flags;
-+ char **allowed_extras;
-+} http_parse_param_cb_arg;
-+
-+/* {{{ static void http_parse_cookie_callback */
-+static void http_parse_cookie_callback(void *ptr, const char *key, int keylen, const char *val, int vallen TSRMLS_DC)
-+{
-+ http_parse_param_cb_arg *arg = (http_parse_param_cb_arg *) ptr;
-+
-+#define _KEY_IS(s) (keylen == lenof(s) && !strncasecmp(key, (s), keylen))
-+ if _KEY_IS("path") {
-+ STR_SET(arg->list->path, estrndup(val, vallen));
-+ } else if _KEY_IS("domain") {
-+ STR_SET(arg->list->domain, estrndup(val, vallen));
-+ } else if _KEY_IS("expires") {
-+ char *date = estrndup(val, vallen);
-+ arg->list->expires = http_parse_date(date);
-+ efree(date);
-+ } else if _KEY_IS("secure") {
-+ arg->list->flags |= HTTP_COOKIE_SECURE;
-+ } else if _KEY_IS("httpOnly") {
-+ arg->list->flags |= HTTP_COOKIE_HTTPONLY;
-+ } else {
-+ /* check for extra */
-+ if (arg->allowed_extras) {
-+ char **ae = arg->allowed_extras;
-+
-+ for (; *ae; ++ae) {
-+ if ((size_t) keylen == strlen(*ae) && !strncasecmp(key, *ae, keylen)) {
-+ if (arg->flags & HTTP_COOKIE_PARSE_RAW) {
-+ http_cookie_list_add_extra(arg->list, key, keylen, val, vallen);
-+ } else {
-+ char *dec = estrndup(val, vallen);
-+ int declen = php_url_decode(dec, vallen);
-+
-+ http_cookie_list_add_extra(arg->list, key, keylen, dec, declen);
-+ efree(dec);
-+ }
-+ return;
-+ }
-+ }
-+ }
-+ /* new cookie */
-+ if (arg->flags & HTTP_COOKIE_PARSE_RAW) {
-+ http_cookie_list_add_cookie(arg->list, key, keylen, val, vallen);
-+ } else {
-+ char *dec = estrndup(val, vallen);
-+ int declen = php_url_decode(dec, vallen);
-+
-+ http_cookie_list_add_cookie(arg->list, key, keylen, dec, declen);
-+ efree(dec);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ http_cookie_list *http_parse_cookie(char *, long) */
-+PHP_HTTP_API http_cookie_list *_http_parse_cookie_ex(http_cookie_list *list, const char *string, long flags, char **allowed_extras TSRMLS_DC)
-+{
-+ int free_list = !list;
-+ http_parse_param_cb_arg arg;
-+
-+ list = http_cookie_list_init(list);
-+
-+ arg.list = list;
-+ arg.flags = flags;
-+ arg.allowed_extras = allowed_extras;
-+
-+ if (SUCCESS != http_parse_params_ex(string, HTTP_PARAMS_RAISE_ERROR, http_parse_cookie_callback, &arg)) {
-+ if (free_list) {
-+ http_cookie_list_free(&list);
-+ } else {
-+ http_cookie_list_dtor(list);
-+ }
-+ list = NULL;
-+ }
-+
-+ return list;
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_tostruct(http_cookie_list *, zval *) */
-+PHP_HTTP_API void _http_cookie_list_tostruct(http_cookie_list *list, zval *strct TSRMLS_DC)
-+{
-+ zval array, *cookies, *extras;
-+
-+ INIT_ZARR(array, HASH_OF(strct));
-+
-+ MAKE_STD_ZVAL(cookies);
-+ array_init(cookies);
-+ zend_hash_copy(Z_ARRVAL_P(cookies), &list->cookies, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ add_assoc_zval(&array, "cookies", cookies);
-+
-+ MAKE_STD_ZVAL(extras);
-+ array_init(extras);
-+ zend_hash_copy(Z_ARRVAL_P(extras), &list->extras, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ add_assoc_zval(&array, "extras", extras);
-+
-+ add_assoc_long(&array, "flags", list->flags);
-+ add_assoc_long(&array, "expires", (long) list->expires);
-+ add_assoc_string(&array, "path", STR_PTR(list->path), 1);
-+ add_assoc_string(&array, "domain", STR_PTR(list->domain), 1);
-+}
-+/* }}} */
-+
-+/* {{{ http_cookie_list *http_cookie_list_fromstruct(http_cookie_list *, zval *strct) */
-+PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *list, zval *strct TSRMLS_DC)
-+{
-+ zval **tmp, *cpy;
-+ HashTable *ht = HASH_OF(strct);
-+
-+ list = http_cookie_list_init(list);
-+
-+ if (SUCCESS == zend_hash_find(ht, "cookies", sizeof("cookies"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
-+ zend_hash_copy(&list->cookies, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "extras", sizeof("extras"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
-+ zend_hash_copy(&list->extras, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "flags", sizeof("flags"), (void *) &tmp)) {
-+ switch (Z_TYPE_PP(tmp)) {
-+ case IS_LONG:
-+ list->flags = Z_LVAL_PP(tmp);
-+ break;
-+ case IS_DOUBLE:
-+ list->flags = (long) Z_DVAL_PP(tmp);
-+ break;
-+ case IS_STRING:
-+ cpy = http_zsep(IS_LONG, *tmp);
-+ list->flags = Z_LVAL_P(cpy);
-+ zval_ptr_dtor(&cpy);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "expires", sizeof("expires"), (void *) &tmp)) {
-+ switch (Z_TYPE_PP(tmp)) {
-+ case IS_LONG:
-+ list->expires = Z_LVAL_PP(tmp);
-+ break;
-+ case IS_DOUBLE:
-+ list->expires = (long) Z_DVAL_PP(tmp);
-+ break;
-+ case IS_STRING:
-+ cpy = http_zsep(IS_LONG, *tmp);
-+ if (Z_LVAL_P(cpy)) {
-+ list->expires = Z_LVAL_P(cpy);
-+ } else {
-+ time_t expires = http_parse_date(Z_STRVAL_PP(tmp));
-+ if (expires > 0) {
-+ list->expires = expires;
-+ }
-+ }
-+ zval_ptr_dtor(&cpy);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "path", sizeof("path"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
-+ list->path = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "domain", sizeof("domain"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
-+ list->domain = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-+ }
-+
-+ return list;
-+}
-+/* }}} */
-+
-+/* {{{ inline append_encoded */
-+static inline void append_encoded(phpstr *buf, const char *key, size_t key_len, const char *val, size_t val_len)
-+{
-+ char *enc_str[2];
-+ int enc_len[2];
-+
-+ enc_str[0] = php_url_encode(key, key_len, &enc_len[0]);
-+ enc_str[1] = php_url_encode(val, val_len, &enc_len[1]);
-+
-+ phpstr_append(buf, enc_str[0], enc_len[0]);
-+ phpstr_appends(buf, "=");
-+ phpstr_append(buf, enc_str[1], enc_len[1]);
-+ phpstr_appends(buf, "; ");
-+
-+ efree(enc_str[0]);
-+ efree(enc_str[1]);
-+}
-+/* }}} */
-+
-+/* {{{ void http_cookie_list_tostring(http_cookie_list *, char **, size_t *) */
-+PHP_HTTP_API void _http_cookie_list_tostring(http_cookie_list *list, char **str, size_t *len TSRMLS_DC)
-+{
-+ phpstr buf;
-+ zval **val;
-+ HashKey key = initHashKey(0);
-+ HashPosition pos;
-+
-+ phpstr_init(&buf);
-+
-+ FOREACH_HASH_KEYVAL(pos, &list->cookies, key, val) {
-+ if (key.type == HASH_KEY_IS_STRING && key.len) {
-+ zval *tmp = http_zsep(IS_STRING, *val);
-+ append_encoded(&buf, key.str, key.len-1, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
-+ zval_ptr_dtor(&tmp);
-+ }
-+ }
-+
-+ if (list->domain && *list->domain) {
-+ phpstr_appendf(&buf, "domain=%s; ", list->domain);
-+ }
-+ if (list->path && *list->path) {
-+ phpstr_appendf(&buf, "path=%s; ", list->path);
-+ }
-+ if (list->expires) {
-+ char *date = http_date(list->expires);
-+ phpstr_appendf(&buf, "expires=%s; ", date);
-+ efree(date);
-+ }
-+
-+ FOREACH_HASH_KEYVAL(pos, &list->extras, key, val) {
-+ if (key.type == HASH_KEY_IS_STRING && key.len) {
-+ zval *tmp = http_zsep(IS_STRING, *val);
-+ append_encoded(&buf, key.str, key.len-1, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
-+ }
-+ }
-+
-+ if (list->flags & HTTP_COOKIE_SECURE) {
-+ phpstr_appends(&buf, "secure; ");
-+ }
-+ if (list->flags & HTTP_COOKIE_HTTPONLY) {
-+ phpstr_appends(&buf, "httpOnly; ");
-+ }
-+
-+ phpstr_fix(&buf);
-+ *str = PHPSTR_VAL(&buf);
-+ *len = PHPSTR_LEN(&buf);
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/http_date_api.c
-@@ -0,0 +1,357 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_date_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#include "php_http.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_date_api.h"
-+
-+static inline int check_day(const char *day, size_t len);
-+static inline int check_month(const char *month);
-+static inline int check_tzone(const char *tzone);
-+static inline time_t parse_date(const char *month);
-+
-+/* {{{ day/month names */
-+static const char *days[] = {
-+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-+};
-+static const char *wkdays[] = {
-+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
-+};
-+static const char *weekdays[] = {
-+ "Monday", "Tuesday", "Wednesday",
-+ "Thursday", "Friday", "Saturday", "Sunday"
-+};
-+static const char *months[] = {
-+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-+};
-+enum assume_next {
-+ DATE_MDAY,
-+ DATE_YEAR,
-+ DATE_TIME
-+};
-+#define DS -60
-+static const struct time_zone {
-+ const char *name;
-+ const int offset;
-+} time_zones[] = {
-+ {"GMT", 0}, /* Greenwich Mean */
-+ {"UTC", 0}, /* Universal (Coordinated) */
-+ {"WET", 0}, /* Western European */
-+ {"BST", 0 DS}, /* British Summer */
-+ {"WAT", 60}, /* West Africa */
-+ {"AST", 240}, /* Atlantic Standard */
-+ {"ADT", 240 DS},/* Atlantic Daylight */
-+ {"EST", 300}, /* Eastern Standard */
-+ {"EDT", 300 DS},/* Eastern Daylight */
-+ {"CST", 360}, /* Central Standard */
-+ {"CDT", 360 DS},/* Central Daylight */
-+ {"MST", 420}, /* Mountain Standard */
-+ {"MDT", 420 DS},/* Mountain Daylight */
-+ {"PST", 480}, /* Pacific Standard */
-+ {"PDT", 480 DS},/* Pacific Daylight */
-+ {"YST", 540}, /* Yukon Standard */
-+ {"YDT", 540 DS},/* Yukon Daylight */
-+ {"HST", 600}, /* Hawaii Standard */
-+ {"HDT", 600 DS},/* Hawaii Daylight */
-+ {"CAT", 600}, /* Central Alaska */
-+ {"AHST", 600}, /* Alaska-Hawaii Standard */
-+ {"NT", 660}, /* Nome */
-+ {"IDLW", 720}, /* International Date Line West */
-+ {"CET", -60}, /* Central European */
-+ {"MET", -60}, /* Middle European */
-+ {"MEWT", -60}, /* Middle European Winter */
-+ {"MEST", -60 DS},/* Middle European Summer */
-+ {"CEST", -60 DS},/* Central European Summer */
-+ {"MESZ", -60 DS},/* Middle European Summer */
-+ {"FWT", -60}, /* French Winter */
-+ {"FST", -60 DS},/* French Summer */
-+ {"EET", -120}, /* Eastern Europe, USSR Zone 1 */
-+ {"WAST", -420}, /* West Australian Standard */
-+ {"WADT", -420 DS},/* West Australian Daylight */
-+ {"CCT", -480}, /* China Coast, USSR Zone 7 */
-+ {"JST", -540}, /* Japan Standard, USSR Zone 8 */
-+ {"EAST", -600}, /* Eastern Australian Standard */
-+ {"EADT", -600 DS},/* Eastern Australian Daylight */
-+ {"GST", -600}, /* Guam Standard, USSR Zone 9 */
-+ {"NZT", -720}, /* New Zealand */
-+ {"NZST", -720}, /* New Zealand Standard */
-+ {"NZDT", -720 DS},/* New Zealand Daylight */
-+ {"IDLE", -720}, /* International Date Line East */
-+};
-+/* }}} */
-+
-+/* {{{ Day/Month/TZ checks for http_parse_date()
-+ Originally by libcurl, Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. */
-+static inline int check_day(const char *day, size_t len)
-+{
-+ int i;
-+ const char * const *check = (len > 3) ? &weekdays[0] : &wkdays[0];
-+ for (i = 0; i < 7; i++) {
-+ if (!strcmp(day, check[0])) {
-+ return i;
-+ }
-+ check++;
-+ }
-+ return -1;
-+}
-+
-+static inline int check_month(const char *month)
-+{
-+ int i;
-+ const char * const *check = &months[0];
-+ for (i = 0; i < 12; i++) {
-+ if (!strcmp(month, check[0])) {
-+ return i;
-+ }
-+ check++;
-+ }
-+ return -1;
-+}
-+
-+/* return the time zone offset between GMT and the input one, in number
-+ of seconds or -1 if the timezone wasn't found/legal */
-+
-+static inline int check_tzone(const char *tzone)
-+{
-+ unsigned i;
-+ const struct time_zone *check = time_zones;
-+ for (i = 0; i < sizeof(time_zones) / sizeof(time_zones[0]); i++) {
-+ if (!strcmp(tzone, check->name)) {
-+ return check->offset * 60;
-+ }
-+ check++;
-+ }
-+ return -1;
-+}
-+/* }}} */
-+
-+/* {{{ char *http_date(time_t) */
-+PHP_HTTP_API char *_http_date(time_t t TSRMLS_DC)
-+{
-+ char *date = NULL;
-+ struct tm *gmtime = NULL, tmbuf;
-+
-+ memset(&tmbuf, 0, sizeof(tmbuf));
-+ if ((gmtime = php_gmtime_r(&t, &tmbuf))) {
-+ spprintf(&date, 0,
-+ "%s, %02d %s %04d %02d:%02d:%02d GMT",
-+ days[gmtime->tm_wday], gmtime->tm_mday,
-+ months[gmtime->tm_mon], gmtime->tm_year + 1900,
-+ gmtime->tm_hour, gmtime->tm_min, gmtime->tm_sec
-+ );
-+ }
-+
-+ return date;
-+}
-+/* }}} */
-+
-+/* {{{ time_t http_parse_date(char *) */
-+PHP_HTTP_API time_t _http_parse_date_ex(const char *date, zend_bool silent TSRMLS_DC)
-+{
-+ time_t t = parse_date(date);
-+
-+ if (-1 == t && !silent) {
-+ http_error_ex(HE_NOTICE, HTTP_E_RUNTIME, "Could not parse date: %s", date);
-+ }
-+
-+ return t;
-+}
-+/* }}} */
-+
-+/* time_t parse_date(char *)
-+ Originally by libcurl, Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. */
-+static inline time_t parse_date(const char *date)
-+{
-+ time_t t = 0;
-+ int tz_offset = -1, year = -1, month = -1, monthday = -1, weekday = -1,
-+ hours = -1, minutes = -1, seconds = -1;
-+ struct tm tm;
-+ enum assume_next dignext = DATE_MDAY;
-+ const char *indate = date;
-+
-+ int part = 0; /* max 6 parts */
-+
-+ while (*date && (part < 6)) {
-+ int found = 0;
-+
-+ while (*date && !HTTP_IS_CTYPE(alnum, *date)) {
-+ date++;
-+ }
-+
-+ if (HTTP_IS_CTYPE(alpha, *date)) {
-+ /* a name coming up */
-+ char buf[32] = "";
-+ size_t len;
-+ sscanf(date, "%31[A-Za-z]", buf);
-+ len = strlen(buf);
-+
-+ if (weekday == -1) {
-+ weekday = check_day(buf, len);
-+ if (weekday != -1) {
-+ found = 1;
-+ }
-+ }
-+
-+ if (!found && (month == -1)) {
-+ month = check_month(buf);
-+ if (month != -1) {
-+ found = 1;
-+ }
-+ }
-+
-+ if (!found && (tz_offset == -1)) {
-+ /* this just must be a time zone string */
-+ tz_offset = check_tzone(buf);
-+ if (tz_offset != -1) {
-+ found = 1;
-+ }
-+ }
-+
-+ if (!found) {
-+ return -1; /* bad string */
-+ }
-+ date += len;
-+ }
-+ else if (HTTP_IS_CTYPE(digit, *date)) {
-+ /* a digit */
-+ int val;
-+ char *end;
-+ if ((seconds == -1) &&
-+ (3 == sscanf(date, "%02d:%02d:%02d", &hours, &minutes, &seconds))) {
-+ /* time stamp! */
-+ date += 8;
-+ found = 1;
-+ }
-+ else {
-+ val = (int) strtol(date, &end, 10);
-+
-+ if ((tz_offset == -1) && ((end - date) == 4) && (val < 1300) &&
-+ (indate < date) && ((date[-1] == '+' || date[-1] == '-'))) {
-+ /* four digits and a value less than 1300 and it is preceeded with
-+ a plus or minus. This is a time zone indication. */
-+ found = 1;
-+ tz_offset = (val / 100 * 60 + val % 100) * 60;
-+
-+ /* the + and - prefix indicates the local time compared to GMT,
-+ this we need ther reversed math to get what we want */
-+ tz_offset = date[-1] == '+' ? -tz_offset : tz_offset;
-+ }
-+
-+ if (((end - date) == 8) && (year == -1) && (month == -1) && (monthday == -1)) {
-+ /* 8 digits, no year, month or day yet. This is YYYYMMDD */
-+ found = 1;
-+ year = val / 10000;
-+ month = (val % 10000) / 100 - 1; /* month is 0 - 11 */
-+ monthday = val % 100;
-+ }
-+
-+ if (!found && (dignext == DATE_MDAY) && (monthday == -1)) {
-+ if ((val > 0) && (val < 32)) {
-+ monthday = val;
-+ found = 1;
-+ }
-+ dignext = DATE_YEAR;
-+ }
-+
-+ if (!found && (dignext == DATE_YEAR) && (year == -1)) {
-+ year = val;
-+ found = 1;
-+ if (year < 1900) {
-+ year += year > 70 ? 1900 : 2000;
-+ }
-+ if(monthday == -1) {
-+ dignext = DATE_MDAY;
-+ }
-+ }
-+
-+ if (!found) {
-+ return -1;
-+ }
-+
-+ date = end;
-+ }
-+ }
-+
-+ part++;
-+ }
-+
-+ if (-1 == seconds) {
-+ seconds = minutes = hours = 0; /* no time, make it zero */
-+ }
-+
-+ if ((-1 == monthday) || (-1 == month) || (-1 == year)) {
-+ /* lacks vital info, fail */
-+ return -1;
-+ }
-+
-+ if (sizeof(time_t) < 5) {
-+ /* 32 bit time_t can only hold dates to the beginning of 2038 */
-+ if (year > 2037) {
-+ return 0x7fffffff;
-+ }
-+ }
-+
-+ tm.tm_sec = seconds;
-+ tm.tm_min = minutes;
-+ tm.tm_hour = hours;
-+ tm.tm_mday = monthday;
-+ tm.tm_mon = month;
-+ tm.tm_year = year - 1900;
-+ tm.tm_wday = 0;
-+ tm.tm_yday = 0;
-+ tm.tm_isdst = 0;
-+
-+ t = mktime(&tm);
-+
-+ /* time zone adjust */
-+ if (t != -1) {
-+ struct tm *gmt, keeptime2;
-+ long delta;
-+ time_t t2;
-+
-+ if((gmt = php_gmtime_r(&t, &keeptime2))) {
-+ tm = *gmt; /* MSVC quirks */
-+ } else {
-+ return -1; /* illegal date/time */
-+ }
-+
-+ t2 = mktime(&tm);
-+
-+ /* Add the time zone diff (between the given timezone and GMT) and the
-+ diff between the local time zone and GMT. */
-+ delta = (tz_offset != -1 ? tz_offset : 0) + (t - t2);
-+
-+ if((delta > 0) && (t + delta < t)) {
-+ return -1; /* time_t overflow */
-+ }
-+
-+ t += delta;
-+ }
-+
-+ return t;
-+}
-+/* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_deflatestream_object.c
-@@ -0,0 +1,317 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_deflatestream_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_ZLIB)
-+
-+#include "php_http_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_deflatestream_object.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpDeflateStream, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpDeflateStream, method, 0)
-+#define HTTP_DEFLATE_ME(method, visibility) PHP_ME(HttpDeflateStream, method, HTTP_ARGS(HttpDeflateStream, method), visibility)
-+
-+HTTP_BEGIN_ARGS(__construct, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(update, 1)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(flush, 0)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(finish, 0)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+#define THIS_CE http_deflatestream_object_ce
-+zend_class_entry *http_deflatestream_object_ce;
-+zend_function_entry http_deflatestream_object_fe[] = {
-+ HTTP_DEFLATE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+ HTTP_DEFLATE_ME(update, ZEND_ACC_PUBLIC)
-+ HTTP_DEFLATE_ME(flush, ZEND_ACC_PUBLIC)
-+ HTTP_DEFLATE_ME(finish, ZEND_ACC_PUBLIC)
-+
-+ HTTP_DEFLATE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_deflatestream_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_deflatestream_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpDeflateStream, http_deflatestream_object, NULL, 0);
-+ http_deflatestream_object_handlers.clone_obj = _http_deflatestream_object_clone_obj;
-+
-+#ifndef WONKY
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_GZIP")-1, HTTP_DEFLATE_TYPE_GZIP TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_ZLIB")-1, HTTP_DEFLATE_TYPE_ZLIB TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_RAW")-1, HTTP_DEFLATE_TYPE_RAW TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("LEVEL_DEF")-1, HTTP_DEFLATE_LEVEL_DEF TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("LEVEL_MIN")-1, HTTP_DEFLATE_LEVEL_MIN TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("LEVEL_MAX")-1, HTTP_DEFLATE_LEVEL_MAX TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("STRATEGY_DEF")-1, HTTP_DEFLATE_STRATEGY_DEF TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("STRATEGY_FILT")-1, HTTP_DEFLATE_STRATEGY_FILT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("STRATEGY_HUFF")-1, HTTP_DEFLATE_STRATEGY_HUFF TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("STRATEGY_RLE")-1, HTTP_DEFLATE_STRATEGY_RLE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("STRATEGY_FIXED")-1, HTTP_DEFLATE_STRATEGY_FIXED TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_NONE")-1, HTTP_ENCODING_STREAM_FLUSH_NONE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_SYNC")-1, HTTP_ENCODING_STREAM_FLUSH_SYNC TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_FULL")-1, HTTP_ENCODING_STREAM_FLUSH_FULL TSRMLS_CC);
-+#endif
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_deflatestream_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_deflatestream_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_deflatestream_object_new_ex(zend_class_entry *ce, http_encoding_stream *s, http_deflatestream_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_deflatestream_object *o;
-+
-+ o = ecalloc(1, sizeof(http_deflatestream_object));
-+ o->zo.ce = ce;
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+ if (s) {
-+ o->stream = s;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_deflatestream_object, o);
-+ ov.handlers = &http_deflatestream_object_handlers;
-+
-+ return ov;
-+}
-+
-+zend_object_value _http_deflatestream_object_clone_obj(zval *this_ptr TSRMLS_DC)
-+{
-+ http_encoding_stream *s;
-+ zend_object_value new_ov;
-+ http_deflatestream_object *new_obj = NULL;
-+ getObject(http_deflatestream_object, old_obj);
-+
-+ s = ecalloc(1, sizeof(http_encoding_stream));
-+ s->flags = old_obj->stream->flags;
-+ deflateCopy(&s->stream, &old_obj->stream->stream);
-+ s->stream.opaque = phpstr_dup(s->stream.opaque);
-+
-+ new_ov = http_deflatestream_object_new_ex(old_obj->zo.ce, s, &new_obj);
-+ zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
-+
-+ return new_ov;
-+}
-+
-+void _http_deflatestream_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_deflatestream_object *o = (http_deflatestream_object *) object;
-+
-+ if (o->stream) {
-+ http_encoding_deflate_stream_free(&o->stream);
-+ }
-+ freeObject(o);
-+}
-+
-+/* {{{ proto void HttpDeflateStream::__construct([int flags = 0])
-+ Creates a new HttpDeflateStream object instance. */
-+PHP_METHOD(HttpDeflateStream, __construct)
-+{
-+ long flags = 0;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) {
-+ getObject(http_deflatestream_object, obj);
-+
-+ if (!obj->stream) {
-+ obj->stream = http_encoding_deflate_stream_init(NULL, flags & 0x0fffffff);
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "HttpDeflateStream cannot be initialized twice");
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpDeflateStream HttpDeflateStream::factory([int flags[, string class = "HttpDeflateStream"]])
-+ Creates a new HttpDeflateStream object instance. */
-+PHP_METHOD(HttpDeflateStream, factory)
-+{
-+ long flags = 0;
-+ char *cn = NULL;
-+ int cl = 0;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &flags, &cn, &cl)) {
-+ zend_object_value ov;
-+ http_encoding_stream *s = http_encoding_deflate_stream_init(NULL, flags & 0x0fffffff);
-+
-+ if (SUCCESS == http_object_new(&ov, cn, cl, _http_deflatestream_object_new_ex, http_deflatestream_object_ce, s, NULL)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpDeflateStream::update(string data)
-+ Passes more data through the deflate stream. */
-+PHP_METHOD(HttpDeflateStream, update)
-+{
-+ int data_len;
-+ size_t encoded_len = 0;
-+ char *data, *encoded = NULL;
-+ getObject(http_deflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (SUCCESS == http_encoding_deflate_stream_update(obj->stream, data, data_len, &encoded, &encoded_len)) {
-+ RETURN_STRINGL(encoded, encoded_len, 0);
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpDeflateStream::flush([string data])
-+ Flushes the deflate stream. */
-+PHP_METHOD(HttpDeflateStream, flush)
-+{
-+ int data_len = 0;
-+ size_t updated_len = 0, encoded_len = 0;
-+ char *updated = NULL, *encoded = NULL, *data = NULL;
-+ getObject(http_deflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (data_len) {
-+ if (SUCCESS != http_encoding_deflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ if (SUCCESS == http_encoding_deflate_stream_flush(obj->stream, &encoded, &encoded_len)) {
-+ if (updated_len) {
-+ updated = erealloc(updated, updated_len + encoded_len + 1);
-+ updated[updated_len + encoded_len] = '\0';
-+ memcpy(updated + updated_len, encoded, encoded_len);
-+ STR_FREE(encoded);
-+ updated_len += encoded_len;
-+ RETURN_STRINGL(updated, updated_len, 0);
-+ } else if (encoded) {
-+ RETVAL_STRINGL(encoded, encoded_len, 0);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+ } else {
-+ RETVAL_FALSE;
-+ }
-+ STR_FREE(updated);
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpDeflateStream::finish([string data])
-+ Finalizes the deflate stream. The deflate stream can be reused after finalizing. */
-+PHP_METHOD(HttpDeflateStream, finish)
-+{
-+ int data_len = 0;
-+ size_t updated_len = 0, encoded_len = 0;
-+ char *updated = NULL, *encoded = NULL, *data = NULL;
-+ getObject(http_deflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (data_len) {
-+ if (SUCCESS != http_encoding_deflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ if (SUCCESS == http_encoding_deflate_stream_finish(obj->stream, &encoded, &encoded_len)) {
-+ if (updated_len) {
-+ updated = erealloc(updated, updated_len + encoded_len + 1);
-+ updated[updated_len + encoded_len] = '\0';
-+ memcpy(updated + updated_len, encoded, encoded_len);
-+ STR_FREE(encoded);
-+ updated_len += encoded_len;
-+ RETVAL_STRINGL(updated, updated_len, 0);
-+ } else {
-+ STR_FREE(updated);
-+ RETVAL_STRINGL(encoded, encoded_len, 0);
-+ }
-+ } else {
-+ STR_FREE(updated);
-+ RETVAL_FALSE;
-+ }
-+
-+ http_encoding_deflate_stream_dtor(obj->stream);
-+ http_encoding_deflate_stream_init(obj->stream, obj->stream->flags);
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_ZLIB*/
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_encoding_api.c
-@@ -0,0 +1,796 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_encoding_api.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_send_api.h"
-+#include "php_http_headers_api.h"
-+
-+/* {{{ */
-+#ifdef HTTP_HAVE_ZLIB
-+PHP_MINIT_FUNCTION(http_encoding)
-+{
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_LEVEL_DEF", HTTP_DEFLATE_LEVEL_DEF);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_LEVEL_MIN", HTTP_DEFLATE_LEVEL_MIN);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_LEVEL_MAX", HTTP_DEFLATE_LEVEL_MAX);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_TYPE_ZLIB", HTTP_DEFLATE_TYPE_ZLIB);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_TYPE_GZIP", HTTP_DEFLATE_TYPE_GZIP);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_TYPE_RAW", HTTP_DEFLATE_TYPE_RAW);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_STRATEGY_DEF", HTTP_DEFLATE_STRATEGY_DEF);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_STRATEGY_FILT", HTTP_DEFLATE_STRATEGY_FILT);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_STRATEGY_HUFF", HTTP_DEFLATE_STRATEGY_HUFF);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_STRATEGY_RLE", HTTP_DEFLATE_STRATEGY_RLE);
-+ HTTP_LONG_CONSTANT("HTTP_DEFLATE_STRATEGY_FIXED", HTTP_DEFLATE_STRATEGY_FIXED);
-+
-+ HTTP_LONG_CONSTANT("HTTP_ENCODING_STREAM_FLUSH_NONE", HTTP_ENCODING_STREAM_FLUSH_NONE);
-+ HTTP_LONG_CONSTANT("HTTP_ENCODING_STREAM_FLUSH_SYNC", HTTP_ENCODING_STREAM_FLUSH_SYNC);
-+ HTTP_LONG_CONSTANT("HTTP_ENCODING_STREAM_FLUSH_FULL", HTTP_ENCODING_STREAM_FLUSH_FULL);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_RINIT_FUNCTION(http_encoding)
-+{
-+ if (HTTP_G->send.inflate.start_auto) {
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_start_internal(ZEND_STRL("http inflate"), _http_ob_inflatehandler, HTTP_INFLATE_BUFFER_SIZE, 0 TSRMLS_CC);
-+#else
-+ php_ob_set_internal_handler(_http_ob_inflatehandler, HTTP_INFLATE_BUFFER_SIZE, "http inflate", 0 TSRMLS_CC);
-+#endif
-+ }
-+ if (HTTP_G->send.deflate.start_auto) {
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_start_internal(ZEND_STRL("http deflate"), _http_ob_deflatehandler, HTTP_DEFLATE_BUFFER_SIZE, 0 TSRMLS_CC);
-+#else
-+ php_ob_set_internal_handler(_http_ob_deflatehandler, HTTP_DEFLATE_BUFFER_SIZE, "http deflate", 0 TSRMLS_CC);
-+#endif
-+ }
-+ return SUCCESS;
-+}
-+
-+PHP_RSHUTDOWN_FUNCTION(http_encoding)
-+{
-+ if (HTTP_G->send.deflate.stream) {
-+ http_encoding_deflate_stream_free((http_encoding_stream **) &HTTP_G->send.deflate.stream);
-+ }
-+ if (HTTP_G->send.inflate.stream) {
-+ http_encoding_inflate_stream_free((http_encoding_stream **) &HTTP_G->send.inflate.stream);
-+ }
-+ return SUCCESS;
-+}
-+#endif
-+/* }}} */
-+
-+/* {{{ eol_match(char **, int *) */
-+static inline int eol_match(char **line, int *eol_len)
-+{
-+ char *ptr = *line;
-+
-+ while (' ' == *ptr) ++ptr;
-+
-+ if (ptr == http_locate_eol(*line, eol_len)) {
-+ *line = ptr;
-+ return 1;
-+ } else {
-+ return 0;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ char *http_encoding_dechunk(char *, size_t, char **, size_t *) */
-+PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-+{
-+ int eol_len = 0;
-+ char *n_ptr = NULL;
-+ const char *e_ptr = encoded;
-+
-+ *decoded_len = 0;
-+ *decoded = ecalloc(1, encoded_len);
-+
-+ while ((encoded + encoded_len - e_ptr) > 0) {
-+ ulong chunk_len = 0, rest;
-+
-+ chunk_len = strtoul(e_ptr, &n_ptr, 16);
-+
-+ /* we could not read in chunk size */
-+ if (n_ptr == e_ptr) {
-+ /*
-+ * if this is the first turn and there doesn't seem to be a chunk
-+ * size at the begining of the body, do not fail on apparently
-+ * not encoded data and return a copy
-+ */
-+ if (e_ptr == encoded) {
-+ http_error(HE_NOTICE, HTTP_E_ENCODING, "Data does not seem to be chunked encoded");
-+ memcpy(*decoded, encoded, encoded_len);
-+ *decoded_len = encoded_len;
-+ return encoded + encoded_len;
-+ } else {
-+ efree(*decoded);
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Expected chunk size at pos %tu of %zu but got trash", n_ptr - encoded, encoded_len);
-+ return NULL;
-+ }
-+ }
-+
-+ /* reached the end */
-+ if (!chunk_len) {
-+ /* move over '0' chunked encoding terminator */
-+ while (*e_ptr == '0') ++e_ptr;
-+ break;
-+ }
-+
-+ /* there should be CRLF after the chunk size, but we'll ignore SP+ too */
-+ if (*n_ptr && !eol_match(&n_ptr, &eol_len)) {
-+ if (eol_len == 2) {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Expected CRLF at pos %tu of %zu but got 0x%02X 0x%02X", n_ptr - encoded, encoded_len, *n_ptr, *(n_ptr + 1));
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Expected LF at pos %tu of %zu but got 0x%02X", n_ptr - encoded, encoded_len, *n_ptr);
-+ }
-+ }
-+ n_ptr += eol_len;
-+
-+ /* chunk size pretends more data than we actually got, so it's probably a truncated message */
-+ if (chunk_len > (rest = encoded + encoded_len - n_ptr)) {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Truncated message: chunk size %lu exceeds remaining data size %lu at pos %tu of %zu", chunk_len, rest, n_ptr - encoded, encoded_len);
-+ chunk_len = rest;
-+ }
-+
-+ /* copy the chunk */
-+ memcpy(*decoded + *decoded_len, n_ptr, chunk_len);
-+ *decoded_len += chunk_len;
-+
-+ if (chunk_len == rest) {
-+ e_ptr = n_ptr + chunk_len;
-+ break;
-+ } else {
-+ /* advance to next chunk */
-+ e_ptr = n_ptr + chunk_len + eol_len;
-+ }
-+ }
-+
-+ return e_ptr;
-+}
-+/* }}} */
-+
-+/* {{{ int http_encoding_response_start(size_t) */
-+PHP_HTTP_API int _http_encoding_response_start(size_t content_length, zend_bool ignore_http_ohandler TSRMLS_DC)
-+{
-+ int response = HTTP_G->send.deflate.response;
-+#ifdef PHP_OUTPUT_NEWAPI
-+ int ohandler = php_output_handler_started(ZEND_STRL("ob_gzhandler") TSRMLS_CC) || php_output_handler_started(ZEND_STRL("zlib output compression") TSRMLS_CC);
-+#else
-+ int ohandler = php_ob_handler_used("ob_gzhandler" TSRMLS_CC) || php_ob_handler_used("zlib output compression" TSRMLS_CC);
-+#endif
-+
-+ if (!ohandler && !ignore_http_ohandler) {
-+#ifdef PHP_OUTPUT_NEWAPI
-+ ohandler = php_output_handler_started(ZEND_STRL("ob_defaltehandler") TSRMLS_CC) || php_output_handler_started(ZEND_STRL("http deflate") TSRMLS_CC);
-+#else
-+ ohandler = php_ob_handler_used("ob_deflatehandler" TSRMLS_CC) || php_ob_handler_used("http deflate" TSRMLS_CC);
-+#endif
-+ }
-+
-+ if (response && !ohandler) {
-+#ifdef HTTP_HAVE_ZLIB
-+ HashTable *selected;
-+ zval zsupported;
-+
-+ HTTP_G->send.deflate.encoding = 0;
-+
-+ INIT_PZVAL(&zsupported);
-+ array_init(&zsupported);
-+ add_next_index_stringl(&zsupported, "gzip", lenof("gzip"), 1);
-+ add_next_index_stringl(&zsupported, "x-gzip", lenof("x-gzip"), 1);
-+ add_next_index_stringl(&zsupported, "deflate", lenof("deflate"), 1);
-+
-+ if ((selected = http_negotiate_encoding(&zsupported))) {
-+ STATUS hs = FAILURE;
-+ char *encoding = NULL;
-+ ulong idx;
-+
-+ if (HASH_KEY_IS_STRING == zend_hash_get_current_key(selected, &encoding, &idx, 0) && encoding) {
-+ if (!strcmp(encoding, "gzip") || !strcmp(encoding, "x-gzip")) {
-+ if (SUCCESS == (hs = http_send_header_string("Content-Encoding: gzip"))) {
-+ HTTP_G->send.deflate.encoding = HTTP_ENCODING_GZIP;
-+ }
-+ } else if (!strcmp(encoding, "deflate")) {
-+ if (SUCCESS == (hs = http_send_header_string("Content-Encoding: deflate"))) {
-+ HTTP_G->send.deflate.encoding = HTTP_ENCODING_DEFLATE;
-+ }
-+ }
-+ if (SUCCESS == hs) {
-+ http_send_header_string("Vary: Accept-Encoding");
-+ }
-+ }
-+
-+ zend_hash_destroy(selected);
-+ FREE_HASHTABLE(selected);
-+ }
-+
-+ zval_dtor(&zsupported);
-+#else
-+ HTTP_G->send.deflate.encoding = 0;
-+ php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC);
-+#endif /* HTTP_HAVE_ZLIB */
-+ } else if (content_length && !ohandler) {
-+ /* emit a content-length header */
-+ phpstr header;
-+
-+ phpstr_init(&header);
-+ phpstr_appendf(&header, "Content-Length: %zu", content_length);
-+ phpstr_fix(&header);
-+ http_send_header_string_ex(PHPSTR_VAL(&header), PHPSTR_LEN(&header), 1);
-+ phpstr_dtor(&header);
-+ } else {
-+ HTTP_G->send.deflate.encoding = 0;
-+ }
-+
-+ return HTTP_G->send.deflate.encoding;
-+}
-+/* }}} */
-+
-+#ifdef HTTP_HAVE_ZLIB
-+
-+/* {{{ inline int http_inflate_rounds */
-+static inline int http_inflate_rounds(z_stream *Z, int flush, char **buf, size_t *len)
-+{
-+ int status = 0, round = 0;
-+ phpstr buffer;
-+
-+ *buf = NULL;
-+ *len = 0;
-+
-+ phpstr_init_ex(&buffer, Z->avail_in, PHPSTR_INIT_PREALLOC);
-+
-+ do {
-+ if (PHPSTR_NOMEM == phpstr_resize_ex(&buffer, buffer.size, 0, 1)) {
-+ status = Z_MEM_ERROR;
-+ } else {
-+ Z->avail_out = buffer.free;
-+ Z->next_out = (Bytef *) buffer.data + buffer.used;
-+#if 0
-+ fprintf(stderr, "\n%3d: %3d PRIOR: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
-+#endif
-+ status = inflate(Z, flush);
-+
-+ buffer.used += buffer.free - Z->avail_out;
-+ buffer.free = Z->avail_out;
-+#if 0
-+ fprintf(stderr, "%3d: %3d AFTER: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
-+#endif
-+ HTTP_INFLATE_BUFFER_SIZE_ALIGN(buffer.size);
-+ }
-+ } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < HTTP_INFLATE_ROUNDS);
-+
-+ if (status == Z_OK || status == Z_STREAM_END) {
-+ phpstr_shrink(&buffer);
-+ phpstr_fix(&buffer);
-+ *buf = buffer.data;
-+ *len = buffer.used;
-+ } else {
-+ phpstr_dtor(&buffer);
-+ }
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_deflate(int, char *, size_t, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status, level, wbits, strategy;
-+ z_stream Z;
-+
-+ HTTP_DEFLATE_LEVEL_SET(flags, level);
-+ HTTP_DEFLATE_WBITS_SET(flags, wbits);
-+ HTTP_DEFLATE_STRATEGY_SET(flags, strategy);
-+
-+ memset(&Z, 0, sizeof(z_stream));
-+ *encoded = NULL;
-+ *encoded_len = 0;
-+
-+ status = deflateInit2(&Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy);
-+ if (Z_OK == status) {
-+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
-+ *encoded = emalloc_rel(*encoded_len);
-+
-+ Z.next_in = (Bytef *) data;
-+ Z.next_out = (Bytef *) *encoded;
-+ Z.avail_in = data_len;
-+ Z.avail_out = *encoded_len;
-+
-+ status = deflate(&Z, Z_FINISH);
-+ deflateEnd(&Z);
-+
-+ if (Z_STREAM_END == status) {
-+ /* size buffer down to actual length */
-+ *encoded = erealloc_rel(*encoded, Z.total_out + 1);
-+ (*encoded)[*encoded_len = Z.total_out] = '\0';
-+ return SUCCESS;
-+ } else {
-+ STR_SET(*encoded, NULL);
-+ *encoded_len = 0;
-+ }
-+ }
-+
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not deflate data: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_inflate(char *, size_t, char **, size_t) */
-+PHP_HTTP_API STATUS _http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ z_stream Z;
-+ int status, wbits = HTTP_WINDOW_BITS_ANY;
-+
-+ memset(&Z, 0, sizeof(z_stream));
-+
-+retry_raw_inflate:
-+ status = inflateInit2(&Z, wbits);
-+ if (Z_OK == status) {
-+ Z.next_in = (Bytef *) data;
-+ Z.avail_in = data_len;
-+
-+ switch (status = http_inflate_rounds(&Z, Z_NO_FLUSH, decoded, decoded_len)) {
-+ case Z_STREAM_END:
-+ inflateEnd(&Z);
-+ return SUCCESS;
-+
-+ case Z_OK:
-+ status = Z_DATA_ERROR;
-+ break;
-+
-+ case Z_DATA_ERROR:
-+ /* raw deflated data? */
-+ if (HTTP_WINDOW_BITS_ANY == wbits) {
-+ inflateEnd(&Z);
-+ wbits = HTTP_WINDOW_BITS_RAW;
-+ goto retry_raw_inflate;
-+ }
-+ }
-+ inflateEnd(&Z);
-+ }
-+
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not inflate data: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *, int) */
-+PHP_HTTP_API http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s, int flags ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status, level, wbits, strategy, free_stream;
-+
-+ if ((free_stream = !s)) {
-+ s = pemalloc_rel(sizeof(http_encoding_stream), (flags & HTTP_ENCODING_STREAM_PERSISTENT));
-+ }
-+ memset(s, 0, sizeof(http_encoding_stream));
-+ s->flags = flags;
-+
-+ HTTP_DEFLATE_LEVEL_SET(flags, level);
-+ HTTP_DEFLATE_WBITS_SET(flags, wbits);
-+ HTTP_DEFLATE_STRATEGY_SET(flags, strategy);
-+
-+ if (Z_OK == (status = deflateInit2(&s->stream, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy))) {
-+ int p = (flags & HTTP_ENCODING_STREAM_PERSISTENT) ? PHPSTR_INIT_PERSISTENT:0;
-+
-+ if ((s->stream.opaque = phpstr_init_ex(NULL, HTTP_DEFLATE_BUFFER_SIZE, p))) {
-+ return s;
-+ }
-+ deflateEnd(&s->stream);
-+ status = Z_MEM_ERROR;
-+ }
-+
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to initialize deflate encoding stream: %s", zError(status));
-+ if (free_stream) {
-+ efree(s);
-+ }
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ http_encoding_stream *http_encoding_inflate_stream_init(http_encoding_stream *, int) */
-+PHP_HTTP_API http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s, int flags ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status, wbits, free_stream;
-+
-+ if ((free_stream = !s)) {
-+ s = pemalloc_rel(sizeof(http_encoding_stream), (flags & HTTP_ENCODING_STREAM_PERSISTENT));
-+ }
-+ memset(s, 0, sizeof(http_encoding_stream));
-+ s->flags = flags;
-+
-+ HTTP_INFLATE_WBITS_SET(flags, wbits);
-+
-+ if (Z_OK == (status = inflateInit2(&s->stream, wbits))) {
-+ int p = (flags & HTTP_ENCODING_STREAM_PERSISTENT) ? PHPSTR_INIT_PERSISTENT:0;
-+
-+ if ((s->stream.opaque = phpstr_init_ex(NULL, HTTP_DEFLATE_BUFFER_SIZE, p))) {
-+ return s;
-+ }
-+ inflateEnd(&s->stream);
-+ status = Z_MEM_ERROR;
-+ }
-+
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to initialize inflate stream: %s", zError(status));
-+ if (free_stream) {
-+ efree(s);
-+ }
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_deflate_stream_update(http_encoding_stream *, char *, size_t, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status;
-+
-+ /* append input to our buffer */
-+ phpstr_append(PHPSTR(s->stream.opaque), data, data_len);
-+
-+ s->stream.next_in = (Bytef *) PHPSTR_VAL(s->stream.opaque);
-+ s->stream.avail_in = PHPSTR_LEN(s->stream.opaque);
-+
-+ /* deflate */
-+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
-+ *encoded = emalloc_rel(*encoded_len);
-+ s->stream.avail_out = *encoded_len;
-+ s->stream.next_out = (Bytef *) *encoded;
-+
-+ switch (status = deflate(&s->stream, HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags))) {
-+ case Z_OK:
-+ case Z_STREAM_END:
-+ /* cut processed chunk off the buffer */
-+ if (s->stream.avail_in) {
-+ phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
-+ } else {
-+ phpstr_reset(PHPSTR(s->stream.opaque));
-+ }
-+
-+ /* size buffer down to actual size */
-+ *encoded_len -= s->stream.avail_out;
-+ *encoded = erealloc_rel(*encoded, *encoded_len + 1);
-+ (*encoded)[*encoded_len] = '\0';
-+ return SUCCESS;
-+ }
-+
-+ STR_SET(*encoded, NULL);
-+ *encoded_len = 0;
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to update deflate stream: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_inflate_stream_update(http_encoding_stream *, char *, size_t, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status;
-+
-+ /* append input to buffer */
-+ phpstr_append(PHPSTR(s->stream.opaque), data, data_len);
-+
-+retry_raw_inflate:
-+ s->stream.next_in = (Bytef *) PHPSTR_VAL(s->stream.opaque);
-+ s->stream.avail_in = PHPSTR_LEN(s->stream.opaque);
-+
-+ switch (status = http_inflate_rounds(&s->stream, HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags), decoded, decoded_len)) {
-+ case Z_OK:
-+ case Z_STREAM_END:
-+ /* cut off */
-+ if (s->stream.avail_in) {
-+ phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
-+ } else {
-+ phpstr_reset(PHPSTR(s->stream.opaque));
-+ }
-+ return SUCCESS;
-+
-+ case Z_DATA_ERROR:
-+ /* raw deflated data ? */
-+ if (!(s->flags & HTTP_INFLATE_TYPE_RAW) && !s->stream.total_out) {
-+ inflateEnd(&s->stream);
-+ s->flags |= HTTP_INFLATE_TYPE_RAW;
-+ inflateInit2(&s->stream, HTTP_WINDOW_BITS_RAW);
-+ goto retry_raw_inflate;
-+ }
-+ }
-+
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to update inflate stream: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_deflate_stream_flush(http_encoding_stream *, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status;
-+
-+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE;
-+ *encoded = emalloc_rel(*encoded_len);
-+
-+ s->stream.avail_in = 0;
-+ s->stream.next_in = NULL;
-+ s->stream.avail_out = *encoded_len;
-+ s->stream.next_out = (Bytef *) *encoded;
-+
-+ switch (status = deflate(&s->stream, Z_FULL_FLUSH)) {
-+ case Z_OK:
-+ case Z_STREAM_END:
-+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE - s->stream.avail_out;
-+ *encoded = erealloc_rel(*encoded, *encoded_len + 1);
-+ (*encoded)[*encoded_len] = '\0';
-+ return SUCCESS;
-+ }
-+
-+ STR_SET(*encoded, NULL);
-+ *encoded_len = 0;
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to flush deflate stream: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_inflate_straem_flush(http_encoding_stream *, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_flush(http_encoding_stream *s, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ /* noop */
-+ *decoded = estrndup("", *decoded_len = 0);
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_deflate_stream_finish(http_encoding_stream *, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status;
-+
-+ *encoded_len = HTTP_DEFLATE_BUFFER_SIZE;
-+ *encoded = emalloc_rel(*encoded_len);
-+
-+ /* deflate remaining input */
-+ s->stream.next_in = (Bytef *) PHPSTR_VAL(s->stream.opaque);
-+ s->stream.avail_in = PHPSTR_LEN(s->stream.opaque);
-+
-+ s->stream.avail_out = *encoded_len;
-+ s->stream.next_out = (Bytef *) *encoded;
-+
-+ do {
-+ status = deflate(&s->stream, Z_FINISH);
-+ } while (Z_OK == status);
-+
-+ if (Z_STREAM_END == status) {
-+ /* cut processed intp off */
-+ phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
-+
-+ /* size down */
-+ *encoded_len -= s->stream.avail_out;
-+ *encoded = erealloc_rel(*encoded, *encoded_len + 1);
-+ (*encoded)[*encoded_len] = '\0';
-+ return SUCCESS;
-+ }
-+
-+ STR_SET(*encoded, NULL);
-+ *encoded_len = 0;
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to finish deflate stream: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_encoding_inflate_stream_finish(http_encoding_stream *, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ int status;
-+
-+ if (!PHPSTR_LEN(s->stream.opaque)) {
-+ *decoded = NULL;
-+ *decoded_len = 0;
-+ return SUCCESS;
-+ }
-+
-+ *decoded_len = (PHPSTR_LEN(s->stream.opaque) + 1) * HTTP_INFLATE_ROUNDS;
-+ *decoded = emalloc_rel(*decoded_len);
-+
-+ /* inflate remaining input */
-+ s->stream.next_in = (Bytef *) PHPSTR_VAL(s->stream.opaque);
-+ s->stream.avail_in = PHPSTR_LEN(s->stream.opaque);
-+
-+ s->stream.avail_out = *decoded_len;
-+ s->stream.next_out = (Bytef *) *decoded;
-+
-+ if (Z_STREAM_END == (status = inflate(&s->stream, Z_FINISH))) {
-+ /* cut processed input off */
-+ phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
-+
-+ /* size down */
-+ *decoded_len -= s->stream.avail_out;
-+ *decoded = erealloc_rel(*decoded, *decoded_len + 1);
-+ (*decoded)[*decoded_len] = '\0';
-+ return SUCCESS;
-+ }
-+
-+ STR_SET(*decoded, NULL);
-+ *decoded_len = 0;
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to finish inflate stream: %s", zError(status));
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ void http_encoding_deflate_stream_dtor(http_encoding_stream *) */
-+PHP_HTTP_API void _http_encoding_deflate_stream_dtor(http_encoding_stream *s TSRMLS_DC)
-+{
-+ if (s) {
-+ if (s->stream.opaque) {
-+ phpstr_free((phpstr **) &s->stream.opaque);
-+ }
-+ deflateEnd(&s->stream);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_encoding_inflate_stream_dtor(http_encoding_stream *) */
-+PHP_HTTP_API void _http_encoding_inflate_stream_dtor(http_encoding_stream *s TSRMLS_DC)
-+{
-+ if (s) {
-+ if (s->stream.opaque) {
-+ phpstr_free((phpstr **) &s->stream.opaque);
-+ }
-+ inflateEnd(&s->stream);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_encoding_deflate_stream_free(http_encoding_stream **) */
-+PHP_HTTP_API void _http_encoding_deflate_stream_free(http_encoding_stream **s TSRMLS_DC)
-+{
-+ if (s) {
-+ http_encoding_deflate_stream_dtor(*s);
-+ if (*s) {
-+ pefree(*s, (*s)->flags & HTTP_ENCODING_STREAM_PERSISTENT);
-+ }
-+ *s = NULL;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_encoding_inflate_stream_free(http_encoding_stream **) */
-+PHP_HTTP_API void _http_encoding_inflate_stream_free(http_encoding_stream **s TSRMLS_DC)
-+{
-+ if (s) {
-+ http_encoding_inflate_stream_dtor(*s);
-+ if (*s) {
-+ pefree(*s, (*s)->flags & HTTP_ENCODING_STREAM_PERSISTENT);
-+ }
-+ *s = NULL;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_ob_deflatehandler(char *, uint, char **, uint *, int) */
-+void _http_ob_deflatehandler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
-+{
-+ int encoding;
-+
-+ *handled_output = NULL;
-+ *handled_output_len = 0;
-+
-+ if (mode & PHP_OUTPUT_HANDLER_START) {
-+ int flags;
-+
-+ if (HTTP_G->send.deflate.stream) {
-+ zend_error(E_ERROR, "ob_deflatehandler() can only be used once");
-+ return;
-+ }
-+
-+ HTTP_G->send.deflate.response = 1;
-+ encoding = http_encoding_response_start(0, 1);
-+ HTTP_G->send.deflate.response = 0;
-+
-+ switch (encoding) {
-+ case HTTP_ENCODING_GZIP:
-+ flags = HTTP_DEFLATE_TYPE_GZIP;
-+ break;
-+
-+ case HTTP_ENCODING_DEFLATE:
-+ flags = HTTP_DEFLATE_TYPE_ZLIB;
-+ break;
-+
-+ default:
-+ goto deflate_passthru_plain;
-+ }
-+
-+ flags |= (HTTP_G->send.deflate.start_flags &~ 0xf0);
-+ HTTP_G->send.deflate.stream = http_encoding_deflate_stream_init(NULL, flags);
-+ }
-+
-+ if (HTTP_G->send.deflate.stream) {
-+ if (output_len) {
-+ size_t tmp_len;
-+
-+ http_encoding_deflate_stream_update((http_encoding_stream *) HTTP_G->send.deflate.stream, output, output_len, handled_output, &tmp_len);
-+ *handled_output_len = tmp_len;
-+ }
-+
-+ if (mode & PHP_OUTPUT_HANDLER_END) {
-+ char *remaining = NULL;
-+ size_t remaining_len = 0;
-+
-+ http_encoding_deflate_stream_finish((http_encoding_stream *) HTTP_G->send.deflate.stream, &remaining, &remaining_len);
-+ http_encoding_deflate_stream_free((http_encoding_stream **) &HTTP_G->send.deflate.stream);
-+ if (remaining) {
-+ *handled_output = erealloc(*handled_output, *handled_output_len + remaining_len + 1);
-+ memcpy(*handled_output + *handled_output_len, remaining, remaining_len);
-+ (*handled_output)[*handled_output_len += remaining_len] = '\0';
-+ efree(remaining);
-+ }
-+ }
-+ } else {
-+deflate_passthru_plain:
-+ *handled_output = estrndup(output, *handled_output_len = output_len);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_ob_inflatehandler(char *, uint, char **, uint *, int) */
-+void _http_ob_inflatehandler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
-+{
-+ *handled_output = NULL;
-+ *handled_output_len = 0;
-+
-+ if (mode & PHP_OUTPUT_HANDLER_START) {
-+ if (HTTP_G->send.inflate.stream) {
-+ zend_error(E_ERROR, "ob_inflatehandler() can only be used once");
-+ return;
-+ }
-+ HTTP_G->send.inflate.stream = http_encoding_inflate_stream_init(NULL, (HTTP_G->send.inflate.start_flags &~ 0xf0));
-+ }
-+
-+ if (HTTP_G->send.inflate.stream) {
-+ if (output_len) {
-+ size_t tmp_len;
-+
-+ http_encoding_inflate_stream_update((http_encoding_stream *) HTTP_G->send.inflate.stream, output, output_len, handled_output, &tmp_len);
-+ *handled_output_len = tmp_len;
-+ }
-+
-+ if (mode & PHP_OUTPUT_HANDLER_END) {
-+ char *remaining = NULL;
-+ size_t remaining_len = 0;
-+
-+ http_encoding_inflate_stream_finish((http_encoding_stream *) HTTP_G->send.inflate.stream, &remaining, &remaining_len);
-+ http_encoding_inflate_stream_free((http_encoding_stream **) &HTTP_G->send.inflate.stream);
-+ if (remaining) {
-+ *handled_output = erealloc(*handled_output, *handled_output_len + remaining_len + 1);
-+ memcpy(*handled_output + *handled_output_len, remaining, remaining_len);
-+ (*handled_output)[*handled_output_len += remaining_len] = '\0';
-+ efree(remaining);
-+ }
-+ }
-+ } else {
-+ *handled_output = estrndup(output, *handled_output_len = output_len);
-+ }
-+}
-+/* }}} */
-+
-+#endif /* HTTP_HAVE_ZLIB */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_exception_object.c
-@@ -0,0 +1,186 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_exception_object.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#include "php_http.h"
-+
-+#ifdef ZEND_ENGINE_2
-+
-+#ifndef HTTP_DBG_EXCEPTIONS
-+# define HTTP_DBG_EXCEPTIONS 0
-+#endif
-+
-+#include "zend_interfaces.h"
-+#include "zend_exceptions.h"
-+#include "php_http_exception_object.h"
-+
-+zend_class_entry *http_exception_object_ce;
-+zend_class_entry *HTTP_EX_CE(runtime);
-+zend_class_entry *HTTP_EX_CE(header);
-+zend_class_entry *HTTP_EX_CE(malformed_headers);
-+zend_class_entry *HTTP_EX_CE(request_method);
-+zend_class_entry *HTTP_EX_CE(message_type);
-+zend_class_entry *HTTP_EX_CE(invalid_param);
-+zend_class_entry *HTTP_EX_CE(encoding);
-+zend_class_entry *HTTP_EX_CE(request);
-+zend_class_entry *HTTP_EX_CE(request_pool);
-+zend_class_entry *HTTP_EX_CE(socket);
-+zend_class_entry *HTTP_EX_CE(response);
-+zend_class_entry *HTTP_EX_CE(url);
-+zend_class_entry *HTTP_EX_CE(querystring);
-+
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpException, method, 0)
-+#define HTTP_EXCEPTION_ME(method, visibility) PHP_ME(HttpException, method, HTTP_ARGS(HttpException, method), visibility)
-+
-+HTTP_EMPTY_ARGS(__toString);
-+
-+zend_function_entry http_exception_object_fe[] = {
-+ HTTP_EXCEPTION_ME(__toString, ZEND_ACC_PUBLIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+
-+#if HTTP_DBG_EXCEPTIONS
-+static void http_exception_hook(zval *ex TSRMLS_DC)
-+{
-+ if (ex) {
-+ zval *m = zend_read_property(Z_OBJCE_P(ex), ex, "message", lenof("message"), 0 TSRMLS_CC);
-+ fprintf(stderr, "*** Threw exception '%s'\n", Z_STRVAL_P(m));
-+ } else {
-+ fprintf(stderr, "*** Threw NULL exception\n");
-+ }
-+}
-+#endif
-+
-+PHP_MINIT_FUNCTION(http_exception_object)
-+{
-+ HTTP_REGISTER_CLASS(HttpException, http_exception_object, ZEND_EXCEPTION_GET_DEFAULT(), 0);
-+
-+ zend_declare_property_null(HTTP_EX_DEF_CE, "innerException", lenof("innerException"), ZEND_ACC_PUBLIC TSRMLS_CC);
-+
-+ HTTP_REGISTER_EXCEPTION(HttpRuntimeException, HTTP_EX_CE(runtime), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpInvalidParamException, HTTP_EX_CE(invalid_param), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpHeaderException, HTTP_EX_CE(header), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpMalformedHeadersException, HTTP_EX_CE(malformed_headers), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpRequestMethodException, HTTP_EX_CE(request_method), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpMessageTypeException, HTTP_EX_CE(message_type), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpEncodingException, HTTP_EX_CE(encoding), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpRequestException, HTTP_EX_CE(request), HTTP_EX_DEF_CE);
-+
-+ zend_declare_property_long(HTTP_EX_CE(request), "curlCode", lenof("curlCode"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+
-+ HTTP_REGISTER_EXCEPTION(HttpRequestPoolException, HTTP_EX_CE(request_pool), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpSocketException, HTTP_EX_CE(socket), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpResponseException, HTTP_EX_CE(response), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpUrlException, HTTP_EX_CE(url), HTTP_EX_DEF_CE);
-+ HTTP_REGISTER_EXCEPTION(HttpQueryStringException, HTTP_EX_CE(querystring), HTTP_EX_DEF_CE);
-+
-+ HTTP_LONG_CONSTANT("HTTP_E_RUNTIME", HTTP_E_RUNTIME);
-+ HTTP_LONG_CONSTANT("HTTP_E_INVALID_PARAM", HTTP_E_INVALID_PARAM);
-+ HTTP_LONG_CONSTANT("HTTP_E_HEADER", HTTP_E_HEADER);
-+ HTTP_LONG_CONSTANT("HTTP_E_MALFORMED_HEADERS", HTTP_E_MALFORMED_HEADERS);
-+ HTTP_LONG_CONSTANT("HTTP_E_REQUEST_METHOD", HTTP_E_REQUEST_METHOD);
-+ HTTP_LONG_CONSTANT("HTTP_E_MESSAGE_TYPE", HTTP_E_MESSAGE_TYPE);
-+ HTTP_LONG_CONSTANT("HTTP_E_ENCODING", HTTP_E_ENCODING);
-+ HTTP_LONG_CONSTANT("HTTP_E_REQUEST", HTTP_E_REQUEST);
-+ HTTP_LONG_CONSTANT("HTTP_E_REQUEST_POOL", HTTP_E_REQUEST_POOL);
-+ HTTP_LONG_CONSTANT("HTTP_E_SOCKET", HTTP_E_SOCKET);
-+ HTTP_LONG_CONSTANT("HTTP_E_RESPONSE", HTTP_E_RESPONSE);
-+ HTTP_LONG_CONSTANT("HTTP_E_URL", HTTP_E_URL);
-+ HTTP_LONG_CONSTANT("HTTP_E_QUERYSTRING", HTTP_E_QUERYSTRING);
-+
-+#if HTTP_DBG_EXCEPTIONS
-+ zend_throw_exception_hook=http_exception_hook;
-+#endif
-+
-+ return SUCCESS;
-+}
-+
-+zend_class_entry *_http_exception_get_default()
-+{
-+ return http_exception_object_ce;
-+}
-+
-+zend_class_entry *_http_exception_get_for_code(long code)
-+{
-+ zend_class_entry *ex = http_exception_object_ce;
-+
-+ switch (code) {
-+ case HTTP_E_RUNTIME: ex = HTTP_EX_CE(runtime); break;
-+ case HTTP_E_INVALID_PARAM: ex = HTTP_EX_CE(invalid_param); break;
-+ case HTTP_E_HEADER: ex = HTTP_EX_CE(header); break;
-+ case HTTP_E_MALFORMED_HEADERS: ex = HTTP_EX_CE(malformed_headers); break;
-+ case HTTP_E_REQUEST_METHOD: ex = HTTP_EX_CE(request_method); break;
-+ case HTTP_E_MESSAGE_TYPE: ex = HTTP_EX_CE(message_type); break;
-+ case HTTP_E_ENCODING: ex = HTTP_EX_CE(encoding); break;
-+ case HTTP_E_REQUEST: ex = HTTP_EX_CE(request); break;
-+ case HTTP_E_REQUEST_POOL: ex = HTTP_EX_CE(request_pool); break;
-+ case HTTP_E_SOCKET: ex = HTTP_EX_CE(socket); break;
-+ case HTTP_E_RESPONSE: ex = HTTP_EX_CE(response); break;
-+ case HTTP_E_URL: ex = HTTP_EX_CE(url); break;
-+ case HTTP_E_QUERYSTRING: ex = HTTP_EX_CE(querystring); break;
-+ }
-+
-+ return ex;
-+}
-+
-+PHP_METHOD(HttpException, __toString)
-+{
-+ phpstr full_str;
-+ zend_class_entry *ce;
-+ zval *zobj = getThis(), *retval = NULL, *m, *f, *l;
-+
-+ phpstr_init(&full_str);
-+
-+ do {
-+ ce = Z_OBJCE_P(zobj);
-+
-+ m = zend_read_property(ce, zobj, "message", lenof("message"), 0 TSRMLS_CC);
-+ f = zend_read_property(ce, zobj, "file", lenof("file"), 0 TSRMLS_CC);
-+ l = zend_read_property(ce, zobj, "line", lenof("line"), 0 TSRMLS_CC);
-+
-+ if (m && f && l && Z_TYPE_P(m) == IS_STRING && Z_TYPE_P(f) == IS_STRING && Z_TYPE_P(l) == IS_LONG) {
-+ if (zobj != getThis()) {
-+ phpstr_appends(&full_str, " inner ");
-+ }
-+
-+ phpstr_appendf(&full_str, "exception '%.*s' with message '%.*s' in %.*s:%ld" PHP_EOL,
-+ ce->name_length, ce->name, Z_STRLEN_P(m), Z_STRVAL_P(m), Z_STRLEN_P(f), Z_STRVAL_P(f), Z_LVAL_P(l)
-+ );
-+ } else {
-+ break;
-+ }
-+
-+ zobj = zend_read_property(ce, zobj, "innerException", lenof("innerException"), 0 TSRMLS_CC);
-+ } while (Z_TYPE_P(zobj) == IS_OBJECT);
-+
-+ if (zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "gettraceasstring", &retval) && Z_TYPE_P(retval) == IS_STRING) {
-+ phpstr_appends(&full_str, "Stack trace:" PHP_EOL);
-+ phpstr_append(&full_str, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-+ zval_ptr_dtor(&retval);
-+ }
-+
-+ RETURN_PHPSTR_VAL(&full_str);
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_filter_api.c
-@@ -0,0 +1,534 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_filter_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#ifdef ZEND_ENGINE_2
-+
-+#include "php_streams.h"
-+#include "php_http_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_filter_api.h"
-+
-+PHP_MINIT_FUNCTION(http_filter)
-+{
-+ php_stream_filter_register_factory("http.*", &http_filter_factory TSRMLS_CC);
-+ return SUCCESS;
-+}
-+
-+/*
-+ -
-+*/
-+
-+#define HTTP_FILTER_PARAMS \
-+ php_stream *stream, \
-+ php_stream_filter *this, \
-+ php_stream_bucket_brigade *buckets_in, \
-+ php_stream_bucket_brigade *buckets_out, \
-+ size_t *bytes_consumed, int flags \
-+ TSRMLS_DC
-+#define HTTP_FILTER_OP(filter) \
-+ http_filter_op_ ##filter
-+#define HTTP_FILTER_OPS(filter) \
-+ php_stream_filter_ops HTTP_FILTER_OP(filter)
-+#define HTTP_FILTER_DTOR(filter) \
-+ http_filter_ ##filter## _dtor
-+#define HTTP_FILTER_DESTRUCTOR(filter) \
-+ void HTTP_FILTER_DTOR(filter)(php_stream_filter *this TSRMLS_DC)
-+#define HTTP_FILTER_FUNC(filter) \
-+ http_filter_ ##filter
-+#define HTTP_FILTER_FUNCTION(filter) \
-+ php_stream_filter_status_t HTTP_FILTER_FUNC(filter)(HTTP_FILTER_PARAMS)
-+#define HTTP_FILTER_BUFFER(filter) \
-+ http_filter_ ##filter## _buffer
-+
-+#define NEW_BUCKET(data, length) \
-+ { \
-+ char *__data; \
-+ php_stream_bucket *__buck; \
-+ \
-+ __data = pemalloc(length, this->is_persistent); \
-+ if (!__data) { \
-+ return PSFS_ERR_FATAL; \
-+ } \
-+ memcpy(__data, data, length); \
-+ \
-+ __buck = php_stream_bucket_new(stream, __data, length, 1, this->is_persistent TSRMLS_CC); \
-+ if (!__buck) { \
-+ pefree(__data, this->is_persistent); \
-+ return PSFS_ERR_FATAL; \
-+ } \
-+ \
-+ php_stream_bucket_append(buckets_out, __buck TSRMLS_CC); \
-+ }
-+
-+typedef struct _http_chunked_decode_filter_buffer_t {
-+ phpstr buffer;
-+ ulong hexlen;
-+} HTTP_FILTER_BUFFER(chunked_decode);
-+
-+#ifdef HTTP_HAVE_ZLIB
-+typedef http_encoding_stream HTTP_FILTER_BUFFER(deflate);
-+typedef http_encoding_stream HTTP_FILTER_BUFFER(inflate);
-+#endif /* HTTP_HAVE_ZLIB */
-+
-+
-+static HTTP_FILTER_FUNCTION(chunked_decode)
-+{
-+ int out_avail = 0;
-+ php_stream_bucket *ptr, *nxt;
-+ HTTP_FILTER_BUFFER(chunked_decode) *buffer = (HTTP_FILTER_BUFFER(chunked_decode) *) (this->abstract);
-+
-+ if (bytes_consumed) {
-+ *bytes_consumed = 0;
-+ }
-+
-+ /* new data available? */
-+ if (buckets_in->head) {
-+
-+ /* fetch available bucket data */
-+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
-+ nxt = ptr->next;
-+ if (bytes_consumed) {
-+ *bytes_consumed += ptr->buflen;
-+ }
-+
-+ if (PHPSTR_NOMEM == phpstr_append(PHPSTR(buffer), ptr->buf, ptr->buflen)) {
-+ return PSFS_ERR_FATAL;
-+ }
-+
-+ php_stream_bucket_unlink(ptr TSRMLS_CC);
-+ php_stream_bucket_delref(ptr TSRMLS_CC);
-+ }
-+ }
-+ if (!phpstr_fix(PHPSTR(buffer))) {
-+ return PSFS_ERR_FATAL;
-+ }
-+
-+ /* we have data in our buffer */
-+ while (PHPSTR_LEN(buffer)) {
-+
-+ /* we already know the size of the chunk and are waiting for data */
-+ if (buffer->hexlen) {
-+
-+ /* not enough data buffered */
-+ if (PHPSTR_LEN(buffer) < buffer->hexlen) {
-+
-+ /* flush anyway? */
-+ if (flags & PSFS_FLAG_FLUSH_INC) {
-+
-+ /* flush all data (should only be chunk data) */
-+ out_avail = 1;
-+ NEW_BUCKET(PHPSTR_VAL(buffer), PHPSTR_LEN(buffer));
-+
-+ /* waiting for less data now */
-+ buffer->hexlen -= PHPSTR_LEN(buffer);
-+ /* no more buffered data */
-+ phpstr_reset(PHPSTR(buffer));
-+ /* break */
-+ }
-+
-+ /* we have too less data and don't need to flush */
-+ else {
-+ break;
-+ }
-+ }
-+
-+ /* we seem to have all data of the chunk */
-+ else {
-+ out_avail = 1;
-+ NEW_BUCKET(PHPSTR_VAL(buffer), buffer->hexlen);
-+
-+ /* remove outgoing data from the buffer */
-+ phpstr_cut(PHPSTR(buffer), 0, buffer->hexlen);
-+ /* reset hexlen */
-+ buffer->hexlen = 0;
-+ /* continue */
-+ }
-+ }
-+
-+ /* we don't know the length of the chunk yet */
-+ else {
-+ size_t off = 0;
-+
-+ /* ignore preceeding CRLFs (too loose?) */
-+ while (off < PHPSTR_LEN(buffer) && (
-+ PHPSTR_VAL(buffer)[off] == '\n' ||
-+ PHPSTR_VAL(buffer)[off] == '\r')) {
-+ ++off;
-+ }
-+ if (off) {
-+ phpstr_cut(PHPSTR(buffer), 0, off);
-+ }
-+
-+ /* still data there? */
-+ if (PHPSTR_LEN(buffer)) {
-+ int eollen;
-+ const char *eolstr;
-+
-+ /* we need eol, so we can be sure we have all hex digits */
-+ phpstr_fix(PHPSTR(buffer));
-+ if ((eolstr = http_locate_eol(PHPSTR_VAL(buffer), &eollen))) {
-+ char *stop = NULL;
-+
-+ /* read in chunk size */
-+ buffer->hexlen = strtoul(PHPSTR_VAL(buffer), &stop, 16);
-+
-+ /* if strtoul() stops at the beginning of the buffered data
-+ there's domething oddly wrong, i.e. bad input */
-+ if (stop == PHPSTR_VAL(buffer)) {
-+ return PSFS_ERR_FATAL;
-+ }
-+
-+ /* cut out <chunk size hex><chunk extension><eol> */
-+ phpstr_cut(PHPSTR(buffer), 0, eolstr + eollen - PHPSTR_VAL(buffer));
-+ /* buffer->hexlen is 0 now or contains the size of the next chunk */
-+ /* continue */
-+ } else {
-+ /* we have not enough data buffered to read in chunk size */
-+ break;
-+ }
-+ }
-+ /* break */
-+ }
-+ }
-+
-+ /* flush before close, but only if we are already waiting for more data */
-+ if ((flags & PSFS_FLAG_FLUSH_CLOSE) && buffer->hexlen && PHPSTR_LEN(buffer)) {
-+ out_avail = 1;
-+ NEW_BUCKET(PHPSTR_VAL(buffer), PHPSTR_LEN(buffer));
-+ phpstr_reset(PHPSTR(buffer));
-+ buffer->hexlen = 0;
-+ }
-+
-+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
-+}
-+
-+static HTTP_FILTER_DESTRUCTOR(chunked_decode)
-+{
-+ HTTP_FILTER_BUFFER(chunked_decode) *b = (HTTP_FILTER_BUFFER(chunked_decode) *) (this->abstract);
-+
-+ phpstr_dtor(PHPSTR(b));
-+ pefree(b, this->is_persistent);
-+}
-+
-+static HTTP_FILTER_FUNCTION(chunked_encode)
-+{
-+ int out_avail = 0;
-+ php_stream_bucket *ptr, *nxt;
-+
-+ if (bytes_consumed) {
-+ *bytes_consumed = 0;
-+ }
-+
-+ /* new data available? */
-+ if (buckets_in->head) {
-+ phpstr buf;
-+ out_avail = 1;
-+
-+ phpstr_init(&buf);
-+
-+ /* fetch available bucket data */
-+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
-+ nxt = ptr->next;
-+ if (bytes_consumed) {
-+ *bytes_consumed += ptr->buflen;
-+ }
-+
-+ phpstr_appendf(&buf, "%x" HTTP_CRLF, ptr->buflen);
-+ phpstr_append(&buf, ptr->buf, ptr->buflen);
-+ phpstr_appends(&buf, HTTP_CRLF);
-+
-+ /* pass through */
-+ NEW_BUCKET(PHPSTR_VAL(&buf), PHPSTR_LEN(&buf));
-+ /* reset */
-+ phpstr_reset(&buf);
-+
-+ php_stream_bucket_unlink(ptr TSRMLS_CC);
-+ php_stream_bucket_delref(ptr TSRMLS_CC);
-+ }
-+
-+ /* free buffer */
-+ phpstr_dtor(&buf);
-+ }
-+
-+ /* terminate with "0" */
-+ if (flags & PSFS_FLAG_FLUSH_CLOSE) {
-+ out_avail = 1;
-+ NEW_BUCKET("0" HTTP_CRLF, lenof("0" HTTP_CRLF));
-+ }
-+
-+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
-+}
-+
-+static HTTP_FILTER_OPS(chunked_decode) = {
-+ HTTP_FILTER_FUNC(chunked_decode),
-+ HTTP_FILTER_DTOR(chunked_decode),
-+ "http.chunked_decode"
-+};
-+
-+static HTTP_FILTER_OPS(chunked_encode) = {
-+ HTTP_FILTER_FUNC(chunked_encode),
-+ NULL,
-+ "http.chunked_encode"
-+};
-+
-+#ifdef HTTP_HAVE_ZLIB
-+
-+static HTTP_FILTER_FUNCTION(deflate)
-+{
-+ int out_avail = 0;
-+ php_stream_bucket *ptr, *nxt;
-+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(deflate) *) this->abstract;
-+
-+ if (bytes_consumed) {
-+ *bytes_consumed = 0;
-+ }
-+
-+ /* new data available? */
-+ if (buckets_in->head) {
-+
-+ /* fetch available bucket data */
-+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
-+ char *encoded = NULL;
-+ size_t encoded_len = 0;
-+
-+ nxt = ptr->next;
-+ if (bytes_consumed) {
-+ *bytes_consumed += ptr->buflen;
-+ }
-+
-+ if (ptr->buflen) {
-+ http_encoding_deflate_stream_update(buffer, ptr->buf, ptr->buflen, &encoded, &encoded_len);
-+ if (encoded) {
-+ if (encoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(encoded, encoded_len);
-+ }
-+ efree(encoded);
-+ }
-+ }
-+
-+ php_stream_bucket_unlink(ptr TSRMLS_CC);
-+ php_stream_bucket_delref(ptr TSRMLS_CC);
-+ }
-+ }
-+
-+ /* flush & close */
-+ if (flags & PSFS_FLAG_FLUSH_INC) {
-+ char *encoded = NULL;
-+ size_t encoded_len = 0;
-+
-+ http_encoding_deflate_stream_flush(buffer, &encoded, &encoded_len);
-+ if (encoded) {
-+ if (encoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(encoded, encoded_len);
-+ }
-+ efree(encoded);
-+ }
-+ }
-+
-+ if (flags & PSFS_FLAG_FLUSH_CLOSE) {
-+ char *encoded = NULL;
-+ size_t encoded_len = 0;
-+
-+ http_encoding_deflate_stream_finish(buffer, &encoded, &encoded_len);
-+ if (encoded) {
-+ if (encoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(encoded, encoded_len);
-+ }
-+ efree(encoded);
-+ }
-+ }
-+
-+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
-+}
-+
-+static HTTP_FILTER_FUNCTION(inflate)
-+{
-+ int out_avail = 0;
-+ php_stream_bucket *ptr, *nxt;
-+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(inflate) *) this->abstract;
-+
-+ if (bytes_consumed) {
-+ *bytes_consumed = 0;
-+ }
-+
-+ /* new data available? */
-+ if (buckets_in->head) {
-+
-+ /* fetch available bucket data */
-+ for (ptr = buckets_in->head; ptr; ptr = nxt) {
-+ char *decoded = NULL;
-+ size_t decoded_len = 0;
-+
-+ nxt = ptr->next;
-+ if (bytes_consumed) {
-+ *bytes_consumed += ptr->buflen;
-+ }
-+
-+ if (ptr->buflen) {
-+ http_encoding_inflate_stream_update(buffer, ptr->buf, ptr->buflen, &decoded, &decoded_len);
-+ if (decoded) {
-+ if (decoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(decoded, decoded_len);
-+ }
-+ efree(decoded);
-+ }
-+ }
-+
-+ php_stream_bucket_unlink(ptr TSRMLS_CC);
-+ php_stream_bucket_delref(ptr TSRMLS_CC);
-+ }
-+ }
-+
-+ /* flush & close */
-+ if (flags & PSFS_FLAG_FLUSH_INC) {
-+ char *decoded = NULL;
-+ size_t decoded_len = 0;
-+
-+ http_encoding_inflate_stream_flush(buffer, &decoded, &decoded_len);
-+ if (decoded) {
-+ if (decoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(decoded, decoded_len);
-+ }
-+ efree(decoded);
-+ }
-+ }
-+
-+ if (flags & PSFS_FLAG_FLUSH_CLOSE) {
-+ char *decoded = NULL;
-+ size_t decoded_len = 0;
-+
-+ http_encoding_inflate_stream_finish(buffer, &decoded, &decoded_len);
-+ if (decoded) {
-+ if (decoded_len) {
-+ out_avail = 1;
-+ NEW_BUCKET(decoded, decoded_len);
-+ }
-+ efree(decoded);
-+ }
-+ }
-+
-+ return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
-+}
-+
-+static HTTP_FILTER_DESTRUCTOR(deflate)
-+{
-+ HTTP_FILTER_BUFFER(deflate) *buffer = (HTTP_FILTER_BUFFER(deflate) *) this->abstract;
-+ http_encoding_deflate_stream_free(&buffer);
-+}
-+
-+static HTTP_FILTER_DESTRUCTOR(inflate)
-+{
-+ HTTP_FILTER_BUFFER(inflate) *buffer = (HTTP_FILTER_BUFFER(inflate) *) this->abstract;
-+ http_encoding_inflate_stream_free(&buffer);
-+}
-+
-+static HTTP_FILTER_OPS(deflate) = {
-+ HTTP_FILTER_FUNC(deflate),
-+ HTTP_FILTER_DTOR(deflate),
-+ "http.deflate"
-+};
-+
-+static HTTP_FILTER_OPS(inflate) = {
-+ HTTP_FILTER_FUNC(inflate),
-+ HTTP_FILTER_DTOR(inflate),
-+ "http.inflate"
-+};
-+
-+#endif /* HTTP_HAVE_ZLIB */
-+
-+static php_stream_filter *http_filter_create(const char *name, zval *params, int p TSRMLS_DC)
-+{
-+ zval **tmp = ¶ms;
-+ php_stream_filter *f = NULL;
-+
-+ if (!strcasecmp(name, "http.chunked_decode")) {
-+ HTTP_FILTER_BUFFER(chunked_decode) *b = NULL;
-+
-+ if ((b = pecalloc(1, sizeof(HTTP_FILTER_BUFFER(chunked_decode)), p))) {
-+ phpstr_init_ex(PHPSTR(b), 4096, p ? PHPSTR_INIT_PERSISTENT : 0);
-+ if (!(f = php_stream_filter_alloc(&HTTP_FILTER_OP(chunked_decode), b, p))) {
-+ pefree(b, p);
-+ }
-+ }
-+ } else
-+
-+ if (!strcasecmp(name, "http.chunked_encode")) {
-+ f = php_stream_filter_alloc(&HTTP_FILTER_OP(chunked_encode), NULL, p);
-+#ifdef HTTP_HAVE_ZLIB
-+ } else
-+
-+ if (!strcasecmp(name, "http.inflate")) {
-+ int flags = p ? HTTP_ENCODING_STREAM_PERSISTENT : 0;
-+ HTTP_FILTER_BUFFER(inflate) *b = NULL;
-+
-+ if ((b = http_encoding_inflate_stream_init(NULL, flags))) {
-+ if (!(f = php_stream_filter_alloc(&HTTP_FILTER_OP(inflate), b, p))) {
-+ http_encoding_inflate_stream_free(&b);
-+ }
-+ }
-+ } else
-+
-+ if (!strcasecmp(name, "http.deflate")) {
-+ int flags = p ? HTTP_ENCODING_STREAM_PERSISTENT : 0;
-+ HTTP_FILTER_BUFFER(deflate) *b = NULL;
-+
-+ if (params) {
-+ switch (Z_TYPE_P(params)) {
-+ case IS_ARRAY:
-+ case IS_OBJECT:
-+ if (SUCCESS != zend_hash_find(HASH_OF(params), "flags", sizeof("flags"), (void *) &tmp)) {
-+ break;
-+ }
-+ default:
-+ {
-+ zval *num = http_zsep(IS_LONG, *tmp);
-+
-+ flags |= (Z_LVAL_P(num) & 0x0fffffff);
-+ zval_ptr_dtor(&num);
-+ }
-+ }
-+ }
-+ if ((b = http_encoding_deflate_stream_init(NULL, flags))) {
-+ if (!(f = php_stream_filter_alloc(&HTTP_FILTER_OP(deflate), b, p))) {
-+ http_encoding_deflate_stream_free(&b);
-+ }
-+ }
-+#endif /* HTTP_HAVE_ZLIB */
-+ }
-+
-+ return f;
-+}
-+
-+php_stream_filter_factory http_filter_factory = {
-+ http_filter_create
-+};
-+
-+#endif /* ZEND_ENGINE_2 */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/http_functions.c
-@@ -0,0 +1,1424 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_functions.c 300301 2010-06-09 08:30:34Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_CURL
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#include "php_ini.h"
-+#include "ext/standard/php_string.h"
-+#include "zend_operators.h"
-+
-+#ifdef HTTP_HAVE_SESSION
-+# include "ext/session/php_session.h"
-+#endif
-+
-+#include "php_http_api.h"
-+#include "php_http_cache_api.h"
-+#include "php_http_cookie_api.h"
-+#include "php_http_date_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_headers_api.h"
-+#include "php_http_message_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_method_api.h"
-+#include "php_http_persistent_handle_api.h"
-+#include "php_http_send_api.h"
-+#include "php_http_url_api.h"
-+
-+/* {{{ proto string http_date([int timestamp])
-+ Compose a valid HTTP date regarding RFC 1123 looking like: "Wed, 22 Dec 2004 11:34:47 GMT" */
-+PHP_FUNCTION(http_date)
-+{
-+ long t = -1;
-+ char *date;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &t) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (t == -1) {
-+ t = HTTP_G->request.time;
-+ }
-+
-+ if (!(date = http_date(t))) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Could not compose date of timestamp %ld", t);
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_STRING(date, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_build_url([mixed url[, mixed parts[, int flags = HTTP_URL_REPLACE|HTTP_URL_FROM_ENV[, array &new_url]]]])
-+ Build an URL. */
-+PHP_FUNCTION(http_build_url)
-+{
-+ char *url_str = NULL;
-+ size_t url_len = 0;
-+ long flags = HTTP_URL_REPLACE|HTTP_URL_FROM_ENV;
-+ zval *z_old_url = NULL, *z_new_url = NULL, *z_composed_url = NULL;
-+ php_url *old_url = NULL, *new_url = NULL, *composed_url = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z!/lz", &z_old_url, &z_new_url, &flags, &z_composed_url) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (z_new_url) {
-+ if (Z_TYPE_P(z_new_url) == IS_ARRAY || Z_TYPE_P(z_new_url) == IS_OBJECT) {
-+ new_url = http_url_from_struct(NULL, HASH_OF(z_new_url));
-+ } else {
-+ convert_to_string(z_new_url);
-+ if (!(new_url = php_url_parse_ex(Z_STRVAL_P(z_new_url), Z_STRLEN_P(z_new_url)))) {
-+ http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", Z_STRVAL_P(z_new_url));
-+ RETURN_FALSE;
-+ }
-+ }
-+ }
-+
-+ if (z_old_url) {
-+ if (Z_TYPE_P(z_old_url) == IS_ARRAY || Z_TYPE_P(z_old_url) == IS_OBJECT) {
-+ old_url = http_url_from_struct(NULL, HASH_OF(z_old_url));
-+ } else {
-+ convert_to_string(z_old_url);
-+ if (!(old_url = php_url_parse_ex(Z_STRVAL_P(z_old_url), Z_STRLEN_P(z_old_url)))) {
-+ if (new_url) {
-+ php_url_free(new_url);
-+ }
-+ http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", Z_STRVAL_P(z_old_url));
-+ RETURN_FALSE;
-+ }
-+ }
-+ }
-+
-+ if (z_composed_url) {
-+ http_build_url(flags, old_url, new_url, &composed_url, &url_str, &url_len);
-+ http_url_tostruct(composed_url, z_composed_url);
-+ php_url_free(composed_url);
-+ } else {
-+ http_build_url(flags, old_url, new_url, NULL, &url_str, &url_len);
-+ }
-+
-+ if (new_url) {
-+ php_url_free(new_url);
-+ }
-+ if (old_url) {
-+ php_url_free(old_url);
-+ }
-+
-+ RETURN_STRINGL(url_str, url_len, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_build_str(array query [, string prefix[, string arg_separator]])
-+ Opponent to parse_str(). */
-+PHP_FUNCTION(http_build_str)
-+{
-+ zval *formdata;
-+ char *prefix = NULL, *arg_sep = INI_STR("arg_separator.output");
-+ int prefix_len = 0, arg_sep_len = strlen(arg_sep);
-+ phpstr formstr;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|ss", &formdata, &prefix, &prefix_len, &arg_sep, &arg_sep_len) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!arg_sep_len) {
-+ arg_sep = HTTP_URL_ARGSEP;
-+ arg_sep_len = lenof(HTTP_URL_ARGSEP);
-+ }
-+
-+ phpstr_init(&formstr);
-+ if (SUCCESS != http_urlencode_hash_recursive(HASH_OF(formdata), &formstr, arg_sep, arg_sep_len, prefix, prefix_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!formstr.used) {
-+ phpstr_dtor(&formstr);
-+ RETURN_NULL();
-+ }
-+
-+ RETURN_PHPSTR_VAL(&formstr);
-+}
-+/* }}} */
-+
-+#define HTTP_DO_NEGOTIATE_DEFAULT(supported) \
-+ { \
-+ zval **value; \
-+ \
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(supported)); \
-+ if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(supported), (void *) &value)) { \
-+ RETVAL_ZVAL(*value, 1, 0); \
-+ } else { \
-+ RETVAL_NULL(); \
-+ } \
-+ }
-+
-+#define HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array) \
-+ HTTP_DO_NEGOTIATE_DEFAULT(supported); \
-+ if (rs_array) { \
-+ HashPosition pos; \
-+ zval **value_ptr; \
-+ \
-+ FOREACH_VAL(pos, supported, value_ptr) { \
-+ zval *value = http_zsep(IS_STRING, *value_ptr); \
-+ add_assoc_double(rs_array, Z_STRVAL_P(value), 1.0); \
-+ zval_ptr_dtor(&value); \
-+ } \
-+ }
-+
-+#define HTTP_DO_NEGOTIATE_HANDLE_RESULT(result, supported, rs_array) \
-+ { \
-+ char *key; \
-+ uint key_len; \
-+ ulong idx; \
-+ \
-+ if (zend_hash_num_elements(result) && HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(result, &key, &key_len, &idx, 1, NULL)) { \
-+ RETVAL_STRINGL(key, key_len-1, 0); \
-+ } else { \
-+ HTTP_DO_NEGOTIATE_DEFAULT(supported); \
-+ } \
-+ \
-+ if (rs_array) { \
-+ zend_hash_copy(Z_ARRVAL_P(rs_array), result, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); \
-+ } \
-+ \
-+ zend_hash_destroy(result); \
-+ FREE_HASHTABLE(result); \
-+ }
-+
-+#define HTTP_DO_NEGOTIATE(type, supported, rs_array) \
-+ { \
-+ HashTable *result; \
-+ if ((result = http_negotiate_ ##type(supported))) { \
-+ HTTP_DO_NEGOTIATE_HANDLE_RESULT(result, supported, rs_array); \
-+ } else { \
-+ HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array); \
-+ } \
-+ }
-+
-+/* {{{ proto string http_negotiate_language(array supported[, array &result])
-+ Negotiate the clients preferred language. */
-+PHP_FUNCTION(http_negotiate_language)
-+{
-+ zval *supported, *rs_array = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (rs_array) {
-+ zval_dtor(rs_array);
-+ array_init(rs_array);
-+ }
-+
-+ HTTP_DO_NEGOTIATE(language, supported, rs_array);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_negotiate_charset(array supported[, array &result])
-+ Negotiate the clients preferred charset. */
-+PHP_FUNCTION(http_negotiate_charset)
-+{
-+ zval *supported, *rs_array = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (rs_array) {
-+ zval_dtor(rs_array);
-+ array_init(rs_array);
-+ }
-+
-+ HTTP_DO_NEGOTIATE(charset, supported, rs_array);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_negotiate_content_type(array supported[, array &result])
-+ Negotiate the clients preferred content type. */
-+PHP_FUNCTION(http_negotiate_content_type)
-+{
-+ zval *supported, *rs_array = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (rs_array) {
-+ zval_dtor(rs_array);
-+ array_init(rs_array);
-+ }
-+
-+ HTTP_DO_NEGOTIATE(content_type, supported, rs_array);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_negotiate(mixed value, array supported[, array &result])
-+ Negotiate the user supplied value. */
-+PHP_FUNCTION(http_negotiate)
-+{
-+ zval *value, *supported, *rs_array = NULL;
-+ HashTable *rs;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|z", &value, &supported, &rs_array)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (rs_array) {
-+ zval_dtor(rs_array);
-+ array_init(rs_array);
-+ }
-+
-+ if ((rs = http_negotiate_z(value, Z_ARRVAL_P(supported), http_negotiate_default_func))) {
-+ HTTP_DO_NEGOTIATE_HANDLE_RESULT(rs, supported, rs_array);
-+ } else {
-+ HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_status(int status)
-+ Send HTTP status code. */
-+PHP_FUNCTION(http_send_status)
-+{
-+ long status = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+ if (status < 100 || status > 510) {
-+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status);
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_send_status(status));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_last_modified([int timestamp])
-+ Send a "Last-Modified" header with a valid HTTP date. */
-+PHP_FUNCTION(http_send_last_modified)
-+{
-+ long t = -1;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &t) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (t == -1) {
-+ t = HTTP_G->request.time;
-+ }
-+
-+ RETURN_SUCCESS(http_send_last_modified(t));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_content_type([string content_type = 'application/x-octetstream'])
-+ Send the Content-Type of the sent entity. This is particularly important if you use the http_send() API. */
-+PHP_FUNCTION(http_send_content_type)
-+{
-+ char *ct = "application/x-octetstream";
-+ int ct_len = lenof("application/x-octetstream");
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ct, &ct_len) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_send_content_type(ct, ct_len));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_content_disposition(string filename[, bool inline = false])
-+ Send the Content-Disposition. */
-+PHP_FUNCTION(http_send_content_disposition)
-+{
-+ char *filename;
-+ int f_len;
-+ zend_bool send_inline = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &f_len, &send_inline) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+ RETURN_SUCCESS(http_send_content_disposition(filename, f_len, send_inline));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_match_modified([int timestamp[, bool for_range = false]])
-+ Matches the given unix timestamp against the clients "If-Modified-Since" resp. "If-Unmodified-Since" HTTP headers. */
-+PHP_FUNCTION(http_match_modified)
-+{
-+ long t = -1;
-+ zend_bool for_range = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &t, &for_range) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ // current time if not supplied (senseless though)
-+ if (t == -1) {
-+ t = HTTP_G->request.time;
-+ }
-+
-+ if (for_range) {
-+ RETURN_BOOL(http_match_last_modified("HTTP_IF_UNMODIFIED_SINCE", t));
-+ }
-+ RETURN_BOOL(http_match_last_modified("HTTP_IF_MODIFIED_SINCE", t));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_match_etag(string etag[, bool for_range = false])
-+ Matches the given ETag against the clients "If-Match" resp. "If-None-Match" HTTP headers. */
-+PHP_FUNCTION(http_match_etag)
-+{
-+ int etag_len;
-+ char *etag;
-+ zend_bool for_range = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &etag, &etag_len, &for_range) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (for_range) {
-+ RETURN_BOOL(http_match_etag("HTTP_IF_MATCH", etag));
-+ }
-+ RETURN_BOOL(http_match_etag("HTTP_IF_NONE_MATCH", etag));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_cache_last_modified([int timestamp_or_expires]])
-+ Attempts to cache the sent entity by its last modification date. */
-+PHP_FUNCTION(http_cache_last_modified)
-+{
-+ long last_modified = 0, send_modified = 0, t;
-+ zval *zlm;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &last_modified) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
-+
-+ t = HTTP_G->request.time;
-+
-+ /* 0 or omitted */
-+ if (!last_modified) {
-+ /* does the client have? (att: caching "forever") */
-+ if ((zlm = http_get_server_var("HTTP_IF_MODIFIED_SINCE", 1))) {
-+ last_modified = send_modified = http_parse_date(Z_STRVAL_P(zlm));
-+ /* send current time */
-+ } else {
-+ send_modified = t;
-+ }
-+ /* negative value is supposed to be expiration time */
-+ } else if (last_modified < 0) {
-+ last_modified += t;
-+ send_modified = t;
-+ /* send supplied time explicitly */
-+ } else {
-+ send_modified = last_modified;
-+ }
-+
-+ RETURN_SUCCESS(http_cache_last_modified(last_modified, send_modified, HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL)));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_cache_etag([string etag])
-+ Attempts to cache the sent entity by its ETag, either supplied or generated by the hash algorithm specified by the INI setting "http.etag.mode". */
-+PHP_FUNCTION(http_cache_etag)
-+{
-+ char *etag = NULL;
-+ int etag_len = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &etag, &etag_len) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
-+
-+ RETURN_SUCCESS(http_cache_etag(etag, etag_len, HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL)));
-+}
-+/* }}} */
-+
-+/* {{{ proto string ob_etaghandler(string data, int mode)
-+ For use with ob_start(). Output buffer handler generating an ETag with the hash algorithm specified with the INI setting "http.etag.mode". */
-+PHP_FUNCTION(ob_etaghandler)
-+{
-+ char *data;
-+ int data_len;
-+ long mode;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) {
-+ RETURN_FALSE;
-+ }
-+
-+ Z_TYPE_P(return_value) = IS_STRING;
-+ http_ob_etaghandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode);
-+}
-+/* }}} */
-+
-+/* {{{ proto void http_throttle(double sec[, int bytes = 40960])
-+ Sets the throttle delay and send buffer size for use with http_send() API. */
-+PHP_FUNCTION(http_throttle)
-+{
-+ long chunk_size = HTTP_SENDBUF_SIZE;
-+ double interval;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|l", &interval, &chunk_size)) {
-+ return;
-+ }
-+
-+ HTTP_G->send.throttle_delay = interval;
-+ HTTP_G->send.buffer_size = chunk_size;
-+}
-+/* }}} */
-+
-+/* {{{ proto void http_redirect([string url[, array params[, bool session = false[, int status = 302]]]])
-+ Redirect to the given url. */
-+PHP_FUNCTION(http_redirect)
-+{
-+ int url_len = 0;
-+ size_t query_len = 0;
-+ zend_bool session = 0, free_params = 0;
-+ zval *params = NULL;
-+ long status = HTTP_REDIRECT;
-+ char *query = NULL, *url = NULL, *URI, *LOC, *RED = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sa!/bl", &url, &url_len, ¶ms, &session, &status) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+#ifdef HTTP_HAVE_SESSION
-+ /* append session info */
-+ if (session) {
-+ if (!params) {
-+ free_params = 1;
-+ MAKE_STD_ZVAL(params);
-+ array_init(params);
-+ }
-+ if (PS(session_status) == php_session_active) {
-+ if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Could not append session information");
-+ }
-+ }
-+ }
-+#endif
-+
-+ /* treat params array with http_build_query() */
-+ if (params) {
-+ if (SUCCESS != http_urlencode_hash_ex(Z_ARRVAL_P(params), 0, NULL, 0, &query, &query_len)) {
-+ if (free_params) {
-+ zval_dtor(params);
-+ FREE_ZVAL(params);
-+ }
-+ if (query) {
-+ efree(query);
-+ }
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ URI = http_absolute_url_ex(url, HTTP_URL_FROM_ENV);
-+
-+ if (query_len) {
-+ spprintf(&LOC, 0, "Location: %s?%s", URI, query);
-+ if (status != 300) {
-+ spprintf(&RED, 0, "Redirecting to <a href=\"%s?%s\">%s?%s</a>.\n", URI, query, URI, query);
-+ }
-+ } else {
-+ spprintf(&LOC, 0, "Location: %s", URI);
-+ if (status != 300) {
-+ spprintf(&RED, 0, "Redirecting to <a href=\"%s\">%s</a>.\n", URI, URI);
-+ }
-+ }
-+
-+ efree(URI);
-+ if (query) {
-+ efree(query);
-+ }
-+ if (free_params) {
-+ zval_dtor(params);
-+ FREE_ZVAL(params);
-+ }
-+
-+ switch (status) {
-+ case 300:
-+ RETVAL_SUCCESS(http_send_status_header(status, LOC));
-+ efree(LOC);
-+ return;
-+
-+ case HTTP_REDIRECT_PERM:
-+ case HTTP_REDIRECT_FOUND:
-+ case HTTP_REDIRECT_POST:
-+ case HTTP_REDIRECT_PROXY:
-+ case HTTP_REDIRECT_TEMP:
-+ break;
-+
-+ case 306:
-+ default:
-+ http_error_ex(HE_NOTICE, HTTP_E_RUNTIME, "Unsupported redirection status code: %ld", status);
-+ case HTTP_REDIRECT:
-+ if ( SG(request_info).request_method &&
-+ strcasecmp(SG(request_info).request_method, "HEAD") &&
-+ strcasecmp(SG(request_info).request_method, "GET")) {
-+ status = HTTP_REDIRECT_POST;
-+ } else {
-+ status = HTTP_REDIRECT_FOUND;
-+ }
-+ break;
-+ }
-+
-+ RETURN_SUCCESS(http_exit_ex(status, LOC, RED, 1));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_data(string data)
-+ Sends raw data with support for (multiple) range requests. */
-+PHP_FUNCTION(http_send_data)
-+{
-+ int data_len;
-+ char *data_buf;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data_buf, &data_len) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_send_data(data_buf, data_len));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_file(string file)
-+ Sends a file with support for (multiple) range requests. */
-+PHP_FUNCTION(http_send_file)
-+{
-+ char *file;
-+ int flen = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &flen) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+ if (!flen) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_send_file(file));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_send_stream(resource stream)
-+ Sends an already opened stream with support for (multiple) range requests. */
-+PHP_FUNCTION(http_send_stream)
-+{
-+ zval *zstream;
-+ php_stream *file;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ php_stream_from_zval(file, &zstream);
-+ RETURN_SUCCESS(http_send_stream(file));
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_chunked_decode(string encoded)
-+ Decodes a string that was HTTP-chunked encoded. */
-+PHP_FUNCTION(http_chunked_decode)
-+{
-+ char *encoded = NULL, *decoded = NULL;
-+ size_t decoded_len = 0;
-+ int encoded_len = 0;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoded, &encoded_len) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (NULL != http_encoding_dechunk(encoded, encoded_len, &decoded, &decoded_len)) {
-+ RETURN_STRINGL(decoded, (int) decoded_len, 0);
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto object http_parse_message(string message)
-+ Parses (a) http_message(s) into a simple recursive object structure. */
-+PHP_FUNCTION(http_parse_message)
-+{
-+ char *message;
-+ int message_len;
-+ http_message *msg = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &message, &message_len)) {
-+ RETURN_NULL();
-+ }
-+
-+ if ((msg = http_message_parse(message, message_len))) {
-+ object_init(return_value);
-+ http_message_tostruct_recursive(msg, return_value);
-+ http_message_free(&msg);
-+ } else {
-+ RETURN_NULL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto array http_parse_headers(string header)
-+ Parses HTTP headers into an associative array. */
-+PHP_FUNCTION(http_parse_headers)
-+{
-+ char *header;
-+ int header_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &header, &header_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ array_init(return_value);
-+ if (SUCCESS != http_parse_headers(header, return_value)) {
-+ zval_dtor(return_value);
-+ http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Failed to parse headers");
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}}*/
-+
-+/* {{{ proto object http_parse_cookie(string cookie[, int flags[, array allowed_extras]])
-+ Parses HTTP cookies like sent in a response into a struct. */
-+PHP_FUNCTION(http_parse_cookie)
-+{
-+ char *cookie, **allowed_extras = NULL;
-+ int i = 0, cookie_len;
-+ long flags = 0;
-+ zval *allowed_extras_array = NULL, **entry = NULL;
-+ HashPosition pos;
-+ http_cookie_list list;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|la!", &cookie, &cookie_len, &flags, &allowed_extras_array)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (allowed_extras_array) {
-+ allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
-+ FOREACH_VAL(pos, allowed_extras_array, entry) {
-+ zval *data = http_zsep(IS_STRING, *entry);
-+ allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
-+ zval_ptr_dtor(&data);
-+ }
-+ }
-+
-+ if (http_parse_cookie_ex(&list, cookie, flags, allowed_extras)) {
-+ object_init(return_value);
-+ http_cookie_list_tostruct(&list, return_value);
-+ http_cookie_list_dtor(&list);
-+ } else {
-+ RETVAL_FALSE;
-+ }
-+
-+ if (allowed_extras) {
-+ for (i = 0; allowed_extras[i]; ++i) {
-+ efree(allowed_extras[i]);
-+ }
-+ efree(allowed_extras);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_build_cookie(array cookie)
-+ Build a cookie string from an array/object like returned by http_parse_cookie(). */
-+PHP_FUNCTION(http_build_cookie)
-+{
-+ char *str = NULL;
-+ size_t len = 0;
-+ zval *strct;
-+ http_cookie_list list;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &strct)) {
-+ RETURN_FALSE;
-+ }
-+
-+ http_cookie_list_fromstruct(&list, strct);
-+ http_cookie_list_tostring(&list, &str, &len);
-+ http_cookie_list_dtor(&list);
-+
-+ RETURN_STRINGL(str, len, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto object http_parse_params(string param[, int flags = HTTP_PARAMS_DEFAULT])
-+ Parse parameter list. */
-+PHP_FUNCTION(http_parse_params)
-+{
-+ char *param;
-+ int param_len;
-+ zval *params;
-+ long flags = HTTP_PARAMS_DEFAULT;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", ¶m, ¶m_len, &flags)) {
-+ RETURN_FALSE;
-+ }
-+
-+ MAKE_STD_ZVAL(params);
-+ array_init(params);
-+ if (SUCCESS != http_parse_params(param, flags, Z_ARRVAL_P(params))) {
-+ zval_ptr_dtor(¶ms);
-+ RETURN_FALSE;
-+ }
-+
-+ object_init(return_value);
-+ add_property_zval(return_value, "params", params);
-+#ifdef ZEND_ENGINE_2
-+ zval_ptr_dtor(¶ms);
-+#endif
-+}
-+/* }}} */
-+
-+/* {{{ proto array http_get_request_headers(void)
-+ Get a list of incoming HTTP headers. */
-+PHP_FUNCTION(http_get_request_headers)
-+{
-+ NO_ARGS;
-+
-+ array_init(return_value);
-+ http_get_request_headers(Z_ARRVAL_P(return_value));
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_get_request_body(void)
-+ Get the raw request body (e.g. POST or PUT data). */
-+PHP_FUNCTION(http_get_request_body)
-+{
-+ char *body;
-+ size_t length;
-+
-+ NO_ARGS;
-+
-+ if (SUCCESS == http_get_request_body(&body, &length)) {
-+ RETURN_STRINGL(body, (int) length, 0);
-+ } else {
-+ RETURN_NULL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto resource http_get_request_body_stream(void)
-+ Create a stream to read the raw request body (e.g. POST or PUT data). This function can only be used once if the request method was another than POST. */
-+PHP_FUNCTION(http_get_request_body_stream)
-+{
-+ php_stream *s;
-+
-+ NO_ARGS;
-+
-+ if ((s = http_get_request_body_stream())) {
-+ php_stream_to_zval(s, return_value);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Failed to create request body stream");
-+ RETURN_NULL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_match_request_header(string header, string value[, bool match_case = false])
-+ Match an incoming HTTP header. */
-+PHP_FUNCTION(http_match_request_header)
-+{
-+ char *header, *value;
-+ int header_len, value_len;
-+ zend_bool match_case = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &header, &header_len, &value, &value_len, &match_case)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_BOOL(http_match_request_header_ex(header, value, match_case));
-+}
-+/* }}} */
-+
-+/* {{{ proto object http_persistent_handles_count() */
-+PHP_FUNCTION(http_persistent_handles_count)
-+{
-+ NO_ARGS;
-+ object_init(return_value);
-+ if (!http_persistent_handle_statall_ex(HASH_OF(return_value))) {
-+ zval_dtor(return_value);
-+ RETURN_NULL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void http_persistent_handles_clean([string name]) */
-+PHP_FUNCTION(http_persistent_handles_clean)
-+{
-+ char *name_str = NULL;
-+ int name_len = 0;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name_str, &name_len)) {
-+ http_persistent_handle_cleanup_ex(name_str, name_len, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_persistent_handles_ident([string ident]) */
-+PHP_FUNCTION(http_persistent_handles_ident)
-+{
-+ char *ident_str = NULL;
-+ int ident_len = 0;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ident_str, &ident_len)) {
-+ RETVAL_STRING(zend_ini_string(ZEND_STRS("http.persistent.handles.ident"), 0), 1);
-+ if (ident_str && ident_len) {
-+ zend_alter_ini_entry(ZEND_STRS("http.persistent.handles.ident"), ident_str, ident_len, ZEND_INI_USER, PHP_INI_STAGE_RUNTIME);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ HAVE_CURL */
-+#ifdef HTTP_HAVE_CURL
-+
-+#define RETVAL_RESPONSE_OR_BODY(request) \
-+ { \
-+ zval **bodyonly; \
-+ \
-+ /* check if only the body should be returned */ \
-+ if (options && (SUCCESS == zend_hash_find(Z_ARRVAL_P(options), "bodyonly", sizeof("bodyonly"), (void *) &bodyonly)) && i_zend_is_true(*bodyonly)) { \
-+ http_message *msg = http_message_parse(PHPSTR_VAL(&request.conv.response), PHPSTR_LEN(&request.conv.response)); \
-+ \
-+ if (msg) { \
-+ RETVAL_STRINGL(PHPSTR_VAL(&msg->body), PHPSTR_LEN(&msg->body), 1); \
-+ http_message_free(&msg); \
-+ } \
-+ } else { \
-+ RETVAL_STRINGL(request.conv.response.data, request.conv.response.used, 1); \
-+ } \
-+ }
-+
-+/* {{{ proto string http_get(string url[, array options[, array &info]])
-+ Performs an HTTP GET request on the supplied url. */
-+PHP_FUNCTION(http_get)
-+{
-+ zval *options = NULL, *info = NULL;
-+ char *URL;
-+ int URL_len;
-+ http_request request;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a/!z", &URL, &URL_len, &options, &info) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_GET, URL);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_head(string url[, array options[, array &info]])
-+ Performs an HTTP HEAD request on the supplied url. */
-+PHP_FUNCTION(http_head)
-+{
-+ zval *options = NULL, *info = NULL;
-+ char *URL;
-+ int URL_len;
-+ http_request request;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a/!z", &URL, &URL_len, &options, &info) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_HEAD, URL);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_post_data(string url, string data[, array options[, array &info]])
-+ Performs an HTTP POST request on the supplied url. */
-+PHP_FUNCTION(http_post_data)
-+{
-+ zval *options = NULL, *info = NULL;
-+ char *URL, *postdata;
-+ int postdata_len, URL_len;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &postdata, &postdata_len, &options, &info) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_POST, URL);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, postdata, postdata_len, 0);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_post_fields(string url, array data[, array files[, array options[, array &info]]])
-+ Performs an HTTP POST request on the supplied url. */
-+PHP_FUNCTION(http_post_fields)
-+{
-+ zval *options = NULL, *info = NULL, *fields = NULL, *files = NULL;
-+ char *URL;
-+ int URL_len;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa!|a!a/!z", &URL, &URL_len, &fields, &files, &options, &info) != SUCCESS) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!http_request_body_fill(&body, fields ? Z_ARRVAL_P(fields) : NULL, files ? Z_ARRVAL_P(files) : NULL)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_POST, URL);
-+ request.body = &body;
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_put_file(string url, string file[, array options[, array &info]])
-+ Performs an HTTP PUT request on the supplied url. */
-+PHP_FUNCTION(http_put_file)
-+{
-+ char *URL, *file;
-+ int URL_len, f_len;
-+ zval *options = NULL, *info = NULL;
-+ php_stream *stream;
-+ php_stream_statbuf ssb;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &file, &f_len, &options, &info)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!(stream = php_stream_open_wrapper_ex(file, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT))) {
-+ RETURN_FALSE;
-+ }
-+ if (php_stream_stat(stream, &ssb)) {
-+ php_stream_close(stream);
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_PUT, URL);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_UPLOADFILE, stream, ssb.sb.st_size, 1);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_put_stream(string url, resource stream[, array options[, array &info]])
-+ Performs an HTTP PUT request on the supplied url. */
-+PHP_FUNCTION(http_put_stream)
-+{
-+ zval *resource, *options = NULL, *info = NULL;
-+ char *URL;
-+ int URL_len;
-+ php_stream *stream;
-+ php_stream_statbuf ssb;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sr|a/!z", &URL, &URL_len, &resource, &options, &info)) {
-+ RETURN_FALSE;
-+ }
-+
-+ php_stream_from_zval(stream, &resource);
-+ if (php_stream_stat(stream, &ssb)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_PUT, URL);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_UPLOADFILE, stream, ssb.sb.st_size, 0);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_put_data(string url, string data[, array options[, array &info]])
-+ Performs an HTTP PUT request on the supplied url. */
-+PHP_FUNCTION(http_put_data)
-+{
-+ char *URL, *data;
-+ int URL_len, data_len;
-+ zval *options = NULL, *info = NULL;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &data, &data_len, &options, &info)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, HTTP_PUT, URL);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, data, data_len, 0);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_request(int method, string url[, string body[, array options[, array &info]]])
-+ Performs a custom HTTP request on the supplied url. */
-+PHP_FUNCTION(http_request)
-+{
-+ long meth;
-+ char *URL, *data = NULL;
-+ int URL_len, data_len = 0;
-+ zval *options = NULL, *info = NULL;
-+ http_request_body body;
-+ http_request request;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|sa/!z", &meth, &URL, &URL_len, &data, &data_len, &options, &info)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info) {
-+ zval_dtor(info);
-+ array_init(info);
-+ }
-+
-+ RETVAL_FALSE;
-+
-+ http_request_init_ex(&request, NULL, meth, URL);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, data, data_len, 0);
-+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
-+ http_request_exec(&request);
-+ if (info) {
-+ http_request_info(&request, Z_ARRVAL_P(info));
-+ }
-+ RETVAL_RESPONSE_OR_BODY(request);
-+ }
-+ http_request_dtor(&request);
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_request_body_encode(array fields, array files)
-+ Generate x-www-form-urlencoded resp. form-data encoded request body. */
-+PHP_FUNCTION(http_request_body_encode)
-+{
-+ zval *fields = NULL, *files = NULL;
-+ HashTable *fields_ht, *files_ht;
-+ http_request_body body;
-+ char *buf;
-+ size_t len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!", &fields, &files)) {
-+ RETURN_FALSE;
-+ }
-+
-+ fields_ht = (fields && Z_TYPE_P(fields) == IS_ARRAY) ? Z_ARRVAL_P(fields) : NULL;
-+ files_ht = (files && Z_TYPE_P(files) == IS_ARRAY) ? Z_ARRVAL_P(files) : NULL;
-+ if (http_request_body_fill(&body, fields_ht, files_ht) && (SUCCESS == http_request_body_encode(&body, &buf, &len))) {
-+ RETVAL_STRINGL(buf, len, 0);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Could not encode request body");
-+ RETVAL_FALSE;
-+ }
-+ http_request_body_dtor(&body);
-+}
-+#endif /* HTTP_HAVE_CURL */
-+/* }}} HAVE_CURL */
-+
-+/* {{{ proto int http_request_method_register(string method)
-+ Register a custom request method. */
-+PHP_FUNCTION(http_request_method_register)
-+{
-+ char *method;
-+ int method_len;
-+ ulong existing;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len)) {
-+ RETURN_FALSE;
-+ }
-+ if ((existing = http_request_method_exists(1, 0, method))) {
-+ RETURN_LONG((long) existing);
-+ }
-+
-+ RETVAL_LONG((long) http_request_method_register(method, method_len));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool http_request_method_unregister(mixed method)
-+ Unregister a previously registered custom request method. */
-+PHP_FUNCTION(http_request_method_unregister)
-+{
-+ zval *method;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &method)) {
-+ RETURN_FALSE;
-+ }
-+
-+ switch (Z_TYPE_P(method)) {
-+ case IS_OBJECT:
-+ convert_to_string(method);
-+ case IS_STRING:
-+ if (is_numeric_string(Z_STRVAL_P(method), Z_STRLEN_P(method), NULL, NULL, 1)) {
-+ convert_to_long(method);
-+ } else {
-+ int mn;
-+ if (!(mn = http_request_method_exists(1, 0, Z_STRVAL_P(method)))) {
-+ RETURN_FALSE;
-+ }
-+ zval_dtor(method);
-+ ZVAL_LONG(method, (long)mn);
-+ }
-+ case IS_LONG:
-+ RETURN_SUCCESS(http_request_method_unregister(Z_LVAL_P(method)));
-+ default:
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int http_request_method_exists(mixed method)
-+ Check if a request method is registered (or available by default). */
-+PHP_FUNCTION(http_request_method_exists)
-+{
-+ if (return_value_used) {
-+ zval *method;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &method)) {
-+ RETURN_FALSE;
-+ }
-+
-+ switch (Z_TYPE_P(method)) {
-+ case IS_OBJECT:
-+ convert_to_string(method);
-+ case IS_STRING:
-+ if (is_numeric_string(Z_STRVAL_P(method), Z_STRLEN_P(method), NULL, NULL, 1)) {
-+ convert_to_long(method);
-+ } else {
-+ RETURN_LONG((long) http_request_method_exists(1, 0, Z_STRVAL_P(method)));
-+ }
-+ case IS_LONG:
-+ RETURN_LONG((long) http_request_method_exists(0, (int) Z_LVAL_P(method), NULL));
-+ default:
-+ RETURN_FALSE;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_request_method_name(int method)
-+ Get the literal string representation of a standard or registered request method. */
-+PHP_FUNCTION(http_request_method_name)
-+{
-+ if (return_value_used) {
-+ long method;
-+
-+ if ((SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method)) || (method < 0)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_STRING(estrdup(http_request_method_name((int) method)), 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ */
-+#ifdef HTTP_HAVE_ZLIB
-+
-+/* {{{ proto string http_deflate(string data[, int flags = 0])
-+ Compress data with gzip, zlib AKA deflate or raw deflate encoding. */
-+PHP_FUNCTION(http_deflate)
-+{
-+ char *data;
-+ int data_len;
-+ long flags = 0;
-+
-+ RETVAL_NULL();
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags)) {
-+ char *encoded;
-+ size_t encoded_len;
-+
-+ if (SUCCESS == http_encoding_deflate(flags, data, data_len, &encoded, &encoded_len)) {
-+ RETURN_STRINGL(encoded, (int) encoded_len, 0);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string http_inflate(string data)
-+ Decompress data compressed with either gzip, deflate AKA zlib or raw deflate encoding. */
-+PHP_FUNCTION(http_inflate)
-+{
-+ char *data;
-+ int data_len;
-+
-+ RETVAL_NULL();
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
-+ char *decoded;
-+ size_t decoded_len;
-+
-+ if (SUCCESS == http_encoding_inflate(data, data_len, &decoded, &decoded_len)) {
-+ RETURN_STRINGL(decoded, (int) decoded_len, 0);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string ob_deflatehandler(string data, int mode)
-+ For use with ob_start(). The deflate output buffer handler can only be used once. */
-+PHP_FUNCTION(ob_deflatehandler)
-+{
-+ char *data;
-+ int data_len;
-+ long mode;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) {
-+ RETURN_FALSE;
-+ }
-+
-+ http_ob_deflatehandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode);
-+ Z_TYPE_P(return_value) = Z_STRVAL_P(return_value) ? IS_STRING : IS_NULL;
-+}
-+/* }}} */
-+
-+/* {{{ proto string ob_inflatehandler(string data, int mode)
-+ For use with ob_start(). Same restrictions as with ob_deflatehandler apply. */
-+PHP_FUNCTION(ob_inflatehandler)
-+{
-+ char *data;
-+ int data_len;
-+ long mode;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) {
-+ RETURN_FALSE;
-+ }
-+
-+ http_ob_inflatehandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode);
-+ Z_TYPE_P(return_value) = Z_STRVAL_P(return_value) ? IS_STRING : IS_NULL;
-+}
-+/* }}} */
-+
-+#endif /* HTTP_HAVE_ZLIB */
-+/* }}} */
-+
-+/* {{{ proto int http_support([int feature = 0])
-+ Check for feature that require external libraries. */
-+PHP_FUNCTION(http_support)
-+{
-+ long feature = 0;
-+
-+ RETVAL_LONG(0L);
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &feature)) {
-+ RETVAL_LONG(http_support(feature));
-+ }
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_headers_api.c
-@@ -0,0 +1,534 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_headers_api.c 300300 2010-06-09 07:29:35Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#include "php_http.h"
-+
-+#include "ext/standard/url.h"
-+#include "ext/standard/php_string.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_headers_api.h"
-+
-+#ifndef HTTP_DBG_NEG
-+# define HTTP_DBG_NEG 0
-+#endif
-+
-+/* {{{ static void http_grab_response_headers(void *, void *) */
-+static void http_grab_response_headers(void *data, void *arg TSRMLS_DC)
-+{
-+ phpstr_appendl(PHPSTR(arg), ((sapi_header_struct *)data)->header);
-+ phpstr_appends(PHPSTR(arg), HTTP_CRLF);
-+}
-+/* }}} */
-+
-+/* {{{ static int http_sort_q(const void *, const void *) */
-+static int http_sort_q(const void *a, const void *b TSRMLS_DC)
-+{
-+ Bucket *f, *s;
-+ zval result, *first, *second;
-+
-+ f = *((Bucket **) a);
-+ s = *((Bucket **) b);
-+
-+ first = *((zval **) f->pData);
-+ second= *((zval **) s->pData);
-+
-+ if (numeric_compare_function(&result, first, second TSRMLS_CC) != SUCCESS) {
-+ return 0;
-+ }
-+ return (Z_LVAL(result) > 0 ? -1 : (Z_LVAL(result) < 0 ? 1 : 0));
-+}
-+/* }}} */
-+
-+/* {{{ char *http_negotiate_language_func */
-+char *_http_negotiate_language_func(const char *test, double *quality, HashTable *supported TSRMLS_DC)
-+{
-+ zval **value;
-+ HashPosition pos;
-+ const char *dash_test;
-+
-+ FOREACH_HASH_VAL(pos, supported, value) {
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "strcasecmp('%s', '%s')\n", Z_STRVAL_PP(value), test);
-+#endif
-+ if (!strcasecmp(Z_STRVAL_PP(value), test)) {
-+ return Z_STRVAL_PP(value);
-+ }
-+ }
-+
-+ /* no distinct match found, so try primaries */
-+ if ((dash_test = strchr(test, '-'))) {
-+ FOREACH_HASH_VAL(pos, supported, value) {
-+ int len = dash_test - test;
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "strncasecmp('%s', '%s', %d)\n", Z_STRVAL_PP(value), test, len);
-+#endif
-+ if ( (!strncasecmp(Z_STRVAL_PP(value), test, len)) &&
-+ ( (Z_STRVAL_PP(value)[len] == '\0') ||
-+ (Z_STRVAL_PP(value)[len] == '-'))) {
-+ *quality *= .9;
-+ return Z_STRVAL_PP(value);
-+ }
-+ }
-+ }
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ char *http_negotiate_default_func */
-+char *_http_negotiate_default_func(const char *test, double *quality, HashTable *supported TSRMLS_DC)
-+{
-+ zval **value;
-+ HashPosition pos;
-+
-+ FOREACH_HASH_VAL(pos, supported, value) {
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "strcasecmp('%s', '%s')\n", Z_STRVAL_PP(value), test);
-+#endif
-+ if (!strcasecmp(Z_STRVAL_PP(value), test)) {
-+ return Z_STRVAL_PP(value);
-+ }
-+ }
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ HashTable *http_negotiate_z(zval *, HashTable *, negotiate_func_t) */
-+PHP_HTTP_API HashTable *_http_negotiate_z(zval *value, HashTable *supported, negotiate_func_t neg TSRMLS_DC)
-+{
-+ zval *accept = http_zsep(IS_STRING, value);
-+ HashTable *result = NULL;
-+
-+ if (Z_STRLEN_P(accept)) {
-+ zval ex_arr, ex_del;
-+
-+ INIT_PZVAL(&ex_del);
-+ INIT_PZVAL(&ex_arr);
-+ ZVAL_STRINGL(&ex_del, ",", 1, 0);
-+ array_init(&ex_arr);
-+
-+ php_explode(&ex_del, accept, &ex_arr, INT_MAX);
-+
-+ if (zend_hash_num_elements(Z_ARRVAL(ex_arr)) > 0) {
-+ int i = 0;
-+ HashPosition pos;
-+ zval **entry, array;
-+
-+ INIT_PZVAL(&array);
-+ array_init(&array);
-+
-+ FOREACH_HASH_VAL(pos, Z_ARRVAL(ex_arr), entry) {
-+ int ident_len;
-+ double quality;
-+ char *selected, *identifier, *freeme;
-+ const char *separator;
-+
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "Checking %s\n", Z_STRVAL_PP(entry));
-+#endif
-+
-+ if ((separator = strchr(Z_STRVAL_PP(entry), ';'))) {
-+ const char *ptr = separator;
-+
-+ while (*++ptr && !HTTP_IS_CTYPE(digit, *ptr) && '.' != *ptr);
-+
-+ quality = zend_strtod(ptr, NULL);
-+ identifier = estrndup(Z_STRVAL_PP(entry), ident_len = separator - Z_STRVAL_PP(entry));
-+ } else {
-+ quality = 1000.0 - i++;
-+ identifier = estrndup(Z_STRVAL_PP(entry), ident_len = Z_STRLEN_PP(entry));
-+ }
-+ freeme = identifier;
-+
-+ while (HTTP_IS_CTYPE(space, *identifier)) {
-+ ++identifier;
-+ --ident_len;
-+ }
-+ while (ident_len && HTTP_IS_CTYPE(space, identifier[ident_len - 1])) {
-+ identifier[--ident_len] = '\0';
-+ }
-+
-+ if ((selected = neg(identifier, &quality, supported TSRMLS_CC))) {
-+ /* don't overwrite previously set with higher quality */
-+ if (!zend_hash_exists(Z_ARRVAL(array), selected, strlen(selected) + 1)) {
-+ add_assoc_double(&array, selected, quality);
-+ }
-+ }
-+
-+ efree(freeme);
-+ }
-+
-+ result = Z_ARRVAL(array);
-+ zend_hash_sort(result, zend_qsort, http_sort_q, 0 TSRMLS_CC);
-+ }
-+
-+ zval_dtor(&ex_arr);
-+ }
-+
-+ zval_ptr_dtor(&accept);
-+
-+ return result;
-+}
-+/* }}} */
-+
-+/* {{{ HashTable *http_negotiate_q(const char *, HashTable *, negotiate_func_t) */
-+PHP_HTTP_API HashTable *_http_negotiate_q(const char *header, HashTable *supported, negotiate_func_t neg TSRMLS_DC)
-+{
-+ zval *accept;
-+
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "Reading header %s: ", header);
-+#endif
-+ if (!(accept = http_get_server_var(header, 1))) {
-+ return NULL;
-+ }
-+#if HTTP_DBG_NEG
-+ fprintf(stderr, "%s\n", Z_STRVAL_P(accept));
-+#endif
-+
-+ return http_negotiate_z(accept, supported, neg);
-+}
-+/* }}} */
-+
-+/* {{{ http_range_status http_get_request_ranges(HashTable *ranges, size_t) */
-+PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_t length TSRMLS_DC)
-+{
-+ zval *zrange;
-+ char *range, c;
-+ long begin = -1, end = -1, *ptr;
-+
-+ if ( !(zrange = http_get_server_var("HTTP_RANGE", 1)) ||
-+ (size_t) Z_STRLEN_P(zrange) < lenof("bytes=") || strncmp(Z_STRVAL_P(zrange), "bytes=", lenof("bytes="))) {
-+ return RANGE_NO;
-+ }
-+ range = Z_STRVAL_P(zrange) + lenof("bytes=");
-+ ptr = &begin;
-+
-+ do {
-+ switch (c = *(range++)) {
-+ case '0':
-+ /* allow 000... - shall we? */
-+ if (*ptr != -10) {
-+ *ptr *= 10;
-+ }
-+ break;
-+
-+ case '1': case '2': case '3':
-+ case '4': case '5': case '6':
-+ case '7': case '8': case '9':
-+ /*
-+ * If the value of the pointer is already set (non-negative)
-+ * then multiply its value by ten and add the current value,
-+ * else initialise the pointers value with the current value
-+ * --
-+ * This let us recognize empty fields when validating the
-+ * ranges, i.e. a "-10" for begin and "12345" for the end
-+ * was the following range request: "Range: bytes=0-12345";
-+ * While a "-1" for begin and "12345" for the end would
-+ * have been: "Range: bytes=-12345".
-+ */
-+ if (*ptr > 0) {
-+ *ptr *= 10;
-+ *ptr += c - '0';
-+ } else {
-+ *ptr = c - '0';
-+ }
-+ break;
-+
-+ case '-':
-+ ptr = &end;
-+ break;
-+
-+ case ' ':
-+ break;
-+
-+ case 0:
-+ case ',':
-+
-+ if (length) {
-+ /* validate ranges */
-+ switch (begin) {
-+ /* "0-12345" */
-+ case -10:
-+ switch (end) {
-+ /* "0-" */
-+ case -1:
-+ return RANGE_NO;
-+
-+ /* "0-0" */
-+ case -10:
-+ end = 0;
-+ break;
-+
-+ default:
-+ if (length <= (size_t) end) {
-+ return RANGE_ERR;
-+ }
-+ break;
-+ }
-+ begin = 0;
-+ break;
-+
-+ /* "-12345" */
-+ case -1:
-+ /* "-", "-0" or overflow */
-+ if (end == -1 || end == -10 || length <= (size_t) end) {
-+ return RANGE_ERR;
-+ }
-+ begin = length - end;
-+ end = length - 1;
-+ break;
-+
-+ /* "12345-(xxx)" */
-+ default:
-+ switch (end) {
-+ /* "12345-0" */
-+ case -10:
-+ return RANGE_ERR;
-+
-+ /* "12345-" */
-+ case -1:
-+ if (length <= (size_t) begin) {
-+ return RANGE_ERR;
-+ }
-+ end = length - 1;
-+ break;
-+
-+ /* "12345-67890" */
-+ default:
-+ if ( (length <= (size_t) begin) ||
-+ (length <= (size_t) end) ||
-+ (end < begin)) {
-+ return RANGE_ERR;
-+ }
-+ break;
-+ }
-+ break;
-+ }
-+ }
-+ {
-+ zval *zentry;
-+ MAKE_STD_ZVAL(zentry);
-+ array_init(zentry);
-+ add_index_long(zentry, 0, begin);
-+ add_index_long(zentry, 1, end);
-+ zend_hash_next_index_insert(ranges, &zentry, sizeof(zval *), NULL);
-+
-+ begin = -1;
-+ end = -1;
-+ ptr = &begin;
-+ }
-+ break;
-+
-+ default:
-+ return RANGE_NO;
-+ }
-+ } while (c != 0);
-+
-+ return RANGE_OK;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_parse_headers(char *, HashTable *, zend_bool) */
-+PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *headers, zend_bool prettify,
-+ http_info_callback callback_func, void **callback_data TSRMLS_DC)
-+{
-+ const char *colon = NULL, *line = NULL;
-+ zval array;
-+
-+ INIT_ZARR(array, headers);
-+
-+ /* skip leading ws */
-+ while (HTTP_IS_CTYPE(space, *header)) ++header;
-+ line = header;
-+
-+#define MORE_HEADERS (*(line-1) && !(*(line-1) == '\n' && (*line == '\n' || *line == '\r')))
-+ do {
-+ int value_len = 0;
-+
-+ switch (*line++) {
-+ case ':':
-+ if (!colon) {
-+ colon = line - 1;
-+ }
-+ break;
-+
-+ case 0:
-+ --value_len; /* we don't have CR so value length is one char less */
-+ case '\n':
-+ if ((!*(line - 1)) || ((*line != ' ') && (*line != '\t'))) {
-+ http_info i;
-+
-+ if (SUCCESS == http_info_parse(header, &i)) {
-+ /* response/request line */
-+ callback_func(callback_data, &headers, &i TSRMLS_CC);
-+ http_info_dtor(&i);
-+ Z_ARRVAL(array) = headers;
-+ } else if (colon) {
-+ /* "header: value" pair */
-+ if (header != colon) {
-+ int keylen = colon - header;
-+ const char *key = header;
-+
-+ /* skip leading ws */
-+ while (keylen && HTTP_IS_CTYPE(space, *key)) --keylen, ++key;
-+ /* skip trailing ws */
-+ while (keylen && HTTP_IS_CTYPE(space, key[keylen - 1])) --keylen;
-+
-+ if (keylen > 0) {
-+ zval **previous = NULL;
-+ char *value;
-+ char *keydup = estrndup(key, keylen);
-+
-+ if (prettify) {
-+ keydup = pretty_key(keydup, keylen, 1, 1);
-+ }
-+
-+ value_len += line - colon - 1;
-+
-+ /* skip leading ws */
-+ while (HTTP_IS_CTYPE(space, *(++colon))) --value_len;
-+ /* skip trailing ws */
-+ while (HTTP_IS_CTYPE(space, colon[value_len - 1])) --value_len;
-+
-+ if (value_len > 0) {
-+ value = estrndup(colon, value_len);
-+ } else {
-+ value = estrdup("");
-+ value_len = 0;
-+ }
-+
-+ /* if we already have got such a header make an array of those */
-+ if (SUCCESS == zend_hash_find(headers, keydup, keylen + 1, (void *) &previous)) {
-+ /* convert to array */
-+ if (Z_TYPE_PP(previous) != IS_ARRAY) {
-+ convert_to_array(*previous);
-+ }
-+ add_next_index_stringl(*previous, value, value_len, 0);
-+ } else {
-+ add_assoc_stringl(&array, keydup, value, value_len, 0);
-+ }
-+ efree(keydup);
-+ } else {
-+ /* empty key (" : ...") */
-+ return FAILURE;
-+ }
-+ } else {
-+ /* empty key (": ...") */
-+ return FAILURE;
-+ }
-+ } else if (MORE_HEADERS) {
-+ /* a line without a colon */
-+ return FAILURE;
-+ }
-+ colon = NULL;
-+ value_len = 0;
-+ header += line - header;
-+ }
-+ break;
-+ }
-+ } while (MORE_HEADERS);
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ void http_get_request_headers(HashTable *) */
-+PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC)
-+{
-+ HashKey key = initHashKey(0);
-+ zval **hsv, **header;
-+ HashPosition pos;
-+
-+ if (!HTTP_G->request.headers) {
-+ ALLOC_HASHTABLE(HTTP_G->request.headers);
-+ zend_hash_init(HTTP_G->request.headers, 0, NULL, ZVAL_PTR_DTOR, 0);
-+
-+#ifdef ZEND_ENGINE_2
-+ zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
-+#endif
-+
-+ if (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv) && Z_TYPE_PP(hsv) == IS_ARRAY) {
-+ FOREACH_KEY(pos, *hsv, key) {
-+ if (key.type == HASH_KEY_IS_STRING && key.len > 6 && !strncmp(key.str, "HTTP_", 5)) {
-+ key.len -= 5;
-+ key.str = pretty_key(estrndup(key.str + 5, key.len - 1), key.len - 1, 1, 1);
-+
-+ zend_hash_get_current_data_ex(Z_ARRVAL_PP(hsv), (void *) &header, &pos);
-+ ZVAL_ADDREF(*header);
-+ zend_hash_add(HTTP_G->request.headers, key.str, key.len, (void *) header, sizeof(zval *), NULL);
-+
-+ efree(key.str);
-+ }
-+ }
-+ }
-+ }
-+
-+ if (headers) {
-+ zend_hash_copy(headers, HTTP_G->request.headers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_get_response_headers(HashTable *) */
-+PHP_HTTP_API STATUS _http_get_response_headers(HashTable *headers_ht TSRMLS_DC)
-+{
-+ STATUS status;
-+ phpstr headers;
-+
-+ phpstr_init(&headers);
-+ zend_llist_apply_with_argument(&SG(sapi_headers).headers, http_grab_response_headers, &headers TSRMLS_CC);
-+ phpstr_fix(&headers);
-+
-+ status = http_parse_headers_ex(PHPSTR_VAL(&headers), headers_ht, 1);
-+ phpstr_dtor(&headers);
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ zend_bool http_match_request_header(char *, char *) */
-+PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const char *value, zend_bool match_case TSRMLS_DC)
-+{
-+ char *name;
-+ uint name_len = strlen(header);
-+ zend_bool result = 0;
-+ zval **data, *zvalue;
-+
-+ http_get_request_headers(NULL);
-+ name = pretty_key(estrndup(header, name_len), name_len, 1, 1);
-+ if (SUCCESS == zend_hash_find(HTTP_G->request.headers, name, name_len+1, (void *) &data)) {
-+ zvalue = http_zsep(IS_STRING, *data);
-+ result = (match_case ? strcmp(Z_STRVAL_P(zvalue), value) : strcasecmp(Z_STRVAL_P(zvalue), value)) ? 0 : 1;
-+ zval_ptr_dtor(&zvalue);
-+ }
-+ efree(name);
-+
-+ return result;
-+}
-+/* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_inflatestream_object.c
-@@ -0,0 +1,297 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_inflatestream_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_ZLIB)
-+
-+#include "php_http_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_inflatestream_object.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpInflateStream, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpInflateStream, method, 0)
-+#define HTTP_INFLATE_ME(method, visibility) PHP_ME(HttpInflateStream, method, HTTP_ARGS(HttpInflateStream, method), visibility)
-+
-+HTTP_BEGIN_ARGS(__construct, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(update, 1)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(flush, 0)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(finish, 0)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+#define THIS_CE http_inflatestream_object_ce
-+zend_class_entry *http_inflatestream_object_ce;
-+zend_function_entry http_inflatestream_object_fe[] = {
-+ HTTP_INFLATE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+ HTTP_INFLATE_ME(update, ZEND_ACC_PUBLIC)
-+ HTTP_INFLATE_ME(flush, ZEND_ACC_PUBLIC)
-+ HTTP_INFLATE_ME(finish, ZEND_ACC_PUBLIC)
-+
-+ HTTP_INFLATE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_inflatestream_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_inflatestream_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpInflateStream, http_inflatestream_object, NULL, 0);
-+ http_inflatestream_object_handlers.clone_obj = _http_inflatestream_object_clone_obj;
-+
-+#ifndef WONKY
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_NONE")-1, HTTP_ENCODING_STREAM_FLUSH_NONE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_SYNC")-1, HTTP_ENCODING_STREAM_FLUSH_SYNC TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("FLUSH_FULL")-1, HTTP_ENCODING_STREAM_FLUSH_FULL TSRMLS_CC);
-+#endif
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_inflatestream_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_inflatestream_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_inflatestream_object_new_ex(zend_class_entry *ce, http_encoding_stream *s, http_inflatestream_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_inflatestream_object *o;
-+
-+ o = ecalloc(1, sizeof(http_inflatestream_object));
-+ o->zo.ce = ce;
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+ if (s) {
-+ o->stream = s;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_inflatestream_object, o);
-+ ov.handlers = &http_inflatestream_object_handlers;
-+
-+ return ov;
-+}
-+
-+zend_object_value _http_inflatestream_object_clone_obj(zval *this_ptr TSRMLS_DC)
-+{
-+ http_encoding_stream *s;
-+ zend_object_value new_ov;
-+ http_inflatestream_object *new_obj = NULL;
-+ getObject(http_inflatestream_object, old_obj);
-+
-+ s = ecalloc(1, sizeof(http_encoding_stream));
-+ s->flags = old_obj->stream->flags;
-+ inflateCopy(&s->stream, &old_obj->stream->stream);
-+ s->stream.opaque = phpstr_dup(s->stream.opaque);
-+
-+ new_ov = http_inflatestream_object_new_ex(old_obj->zo.ce, s, &new_obj);
-+ zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
-+
-+ return new_ov;
-+}
-+
-+void _http_inflatestream_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_inflatestream_object *o = (http_inflatestream_object *) object;
-+
-+ if (o->stream) {
-+ http_encoding_inflate_stream_free(&o->stream);
-+ }
-+ freeObject(o);
-+}
-+
-+/* {{{ proto void HttpInflateStream::__construct([int flags = 0])
-+ Creates a new HttpInflateStream object instance. */
-+PHP_METHOD(HttpInflateStream, __construct)
-+{
-+ long flags = 0;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) {
-+ getObject(http_inflatestream_object, obj);
-+
-+ if (!obj->stream) {
-+ obj->stream = http_encoding_inflate_stream_init(NULL, flags & 0x0fffffff);
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "HttpInflateStream cannot be initialized twice");
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpInflateStream HttpInflateStream::factory([int flags[, string class = "HttpInflateStream"]])
-+ Creates a new HttpInflateStream object instance. */
-+PHP_METHOD(HttpInflateStream, factory)
-+{
-+ long flags = 0;
-+ char *cn = NULL;
-+ int cl = 0;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &flags, &cn, &cl)) {
-+ zend_object_value ov;
-+ http_encoding_stream *s = http_encoding_inflate_stream_init(NULL, flags & 0x0fffffff);
-+
-+ if (SUCCESS == http_object_new(&ov, cn, cl, _http_inflatestream_object_new_ex, http_inflatestream_object_ce, s, NULL)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpInflateStream::update(string data)
-+ Passes more data through the inflate stream. */
-+PHP_METHOD(HttpInflateStream, update)
-+{
-+ int data_len;
-+ size_t decoded_len = 0;
-+ char *data, *decoded = NULL;
-+ getObject(http_inflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!data_len) {
-+ RETURN_STRING("", 1);
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (SUCCESS == http_encoding_inflate_stream_update(obj->stream, data, data_len, &decoded, &decoded_len)) {
-+ RETURN_STRINGL(decoded, decoded_len, 0);
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpInflateStream::flush([string data])
-+ Flush the inflate stream. */
-+PHP_METHOD(HttpInflateStream, flush)
-+{
-+ int data_len = 0;
-+ size_t decoded_len = 0;
-+ char *decoded = NULL, *data = NULL;
-+ getObject(http_inflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ /* flushing the inflate stream is a no-op */
-+ if (!data_len) {
-+ RETURN_STRINGL("", 0, 1);
-+ } else if (SUCCESS == http_encoding_inflate_stream_update(obj->stream, data, data_len, &decoded, &decoded_len)) {
-+ RETURN_STRINGL(decoded, decoded_len, 0);
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpInflateStream::finish([string data])
-+ Finalizes the inflate stream. The inflate stream can be reused after finalizing. */
-+PHP_METHOD(HttpInflateStream, finish)
-+{
-+ int data_len = 0;
-+ size_t updated_len = 0, decoded_len = 0;
-+ char *updated = NULL, *decoded = NULL, *data = NULL;
-+ getObject(http_inflatestream_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (data_len) {
-+ if (SUCCESS != http_encoding_inflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
-+ RETURN_FALSE;
-+ }
-+ }
-+
-+ if (SUCCESS == http_encoding_inflate_stream_finish(obj->stream, &decoded, &decoded_len)) {
-+ if (updated_len) {
-+ updated = erealloc(updated, updated_len + decoded_len + 1);
-+ updated[updated_len + decoded_len] = '\0';
-+ memcpy(updated + updated_len, decoded, decoded_len);
-+ STR_FREE(decoded);
-+ updated_len += decoded_len;
-+ RETVAL_STRINGL(updated, updated_len, 0);
-+ } else if (decoded) {
-+ STR_FREE(updated);
-+ RETVAL_STRINGL(decoded, decoded_len, 0);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+ } else {
-+ STR_FREE(updated);
-+ RETVAL_FALSE;
-+ }
-+
-+ http_encoding_inflate_stream_dtor(obj->stream);
-+ http_encoding_inflate_stream_init(obj->stream, obj->stream->flags);
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_ZLIB*/
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_info_api.c
-@@ -0,0 +1,155 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_info_api.c 304921 2010-10-26 15:27:36Z iliaa $ */
-+
-+#include "php_http.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_info_api.h"
-+
-+PHP_HTTP_API void _http_info_default_callback(void **nothing, HashTable **headers, http_info *info TSRMLS_DC)
-+{
-+ zval array;
-+
-+ INIT_ZARR(array, *headers);
-+
-+ switch (info->type) {
-+ case IS_HTTP_REQUEST:
-+ add_assoc_string(&array, "Request Method", HTTP_INFO(info).request.method, 1);
-+ add_assoc_string(&array, "Request Url", HTTP_INFO(info).request.url, 1);
-+ break;
-+
-+ case IS_HTTP_RESPONSE:
-+ add_assoc_long(&array, "Response Code", (long) HTTP_INFO(info).response.code);
-+ if (HTTP_INFO(info).response.status) {
-+ add_assoc_string(&array, "Response Status", HTTP_INFO(info).response.status, 1);
-+ }
-+ break;
-+ }
-+}
-+
-+PHP_HTTP_API void _http_info_dtor(http_info *i)
-+{
-+ switch (i->type) {
-+ case IS_HTTP_REQUEST:
-+ STR_SET(HTTP_INFO(i).request.method, NULL);
-+ STR_SET(HTTP_INFO(i).request.url, NULL);
-+ break;
-+
-+ case IS_HTTP_RESPONSE:
-+ STR_SET(HTTP_INFO(i).response.status, NULL);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+PHP_HTTP_API STATUS _http_info_parse_ex(const char *pre_header, http_info *info, zend_bool silent TSRMLS_DC)
-+{
-+ const char *end, *http;
-+
-+ /* sane parameter */
-+ if ((!pre_header) || (!*pre_header)) {
-+ return FAILURE;
-+ }
-+
-+ /* where's the end of the line */
-+ if (!(end = http_locate_eol(pre_header, NULL))) {
-+ end = pre_header + strlen(pre_header);
-+ }
-+
-+ /* there must be HTTP/1.x in the line */
-+ if (!(http = http_locate_str(pre_header, end - pre_header, "HTTP/1.", lenof("HTTP/1.")))) {
-+ return FAILURE;
-+ }
-+
-+ /* and nothing than SPACE or NUL after HTTP/1.x */
-+ if ( (!HTTP_IS_CTYPE(digit, http[lenof("HTTP/1.")])) ||
-+ (http[lenof("HTTP/1.1")] && (!HTTP_IS_CTYPE(space, http[lenof("HTTP/1.1")])))) {
-+ if (!silent) {
-+ http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Invalid HTTP/1.x protocol identification");
-+ }
-+ return FAILURE;
-+ }
-+
-+#if 0
-+ {
-+ char *line = estrndup(pre_header, end - pre_header);
-+ fprintf(stderr, "http_parse_info('%s')\n", line);
-+ efree(line);
-+ }
-+#endif
-+
-+ info->http.version = zend_strtod(http + lenof("HTTP/"), NULL);
-+
-+ /* is response */
-+ if (pre_header == http) {
-+ char *status = NULL;
-+ const char *code = http + sizeof("HTTP/1.1");
-+
-+ info->type = IS_HTTP_RESPONSE;
-+ while (' ' == *code) ++code;
-+ if (code && end > code) {
-+ HTTP_INFO(info).response.code = strtol(code, &status, 10);
-+ } else {
-+ HTTP_INFO(info).response.code = 0;
-+ }
-+ if (status && end > status) {
-+ while (' ' == *status) ++status;
-+ HTTP_INFO(info).response.status = estrndup(status, end - status);
-+ } else {
-+ HTTP_INFO(info).response.status = NULL;
-+ }
-+
-+ return SUCCESS;
-+ }
-+
-+ /* is request */
-+ else if (!http[lenof("HTTP/1.x")] || http[lenof("HTTP/1.x")] == '\r' || http[lenof("HTTP/1.x")] == '\n') {
-+ const char *url = strchr(pre_header, ' ');
-+
-+ info->type = IS_HTTP_REQUEST;
-+ if (url && http > url) {
-+ HTTP_INFO(info).request.method = estrndup(pre_header, url - pre_header);
-+ while (' ' == *url) ++url;
-+ while (' ' == *(http-1)) --http;
-+ if (http > url) {
-+ HTTP_INFO(info).request.url = estrndup(url, http - url);
-+ } else {
-+ efree(HTTP_INFO(info).request.method);
-+ return FAILURE;
-+ }
-+ } else {
-+ HTTP_INFO(info).request.method = NULL;
-+ HTTP_INFO(info).request.url = NULL;
-+ }
-+
-+ return SUCCESS;
-+ }
-+
-+ /* some darn header containing HTTP/1.x */
-+ else {
-+ return FAILURE;
-+ }
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_message_api.c
-@@ -0,0 +1,739 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_message_api.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_CURL
-+#define HTTP_WANT_ZLIB
-+#include "php_http.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_headers_api.h"
-+#include "php_http_message_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_send_api.h"
-+#include "php_http_url_api.h"
-+
-+#define http_message_info_callback _http_message_info_callback
-+static void _http_message_info_callback(http_message **message, HashTable **headers, http_info *info TSRMLS_DC)
-+{
-+ http_message *old = *message;
-+
-+ /* advance message */
-+ if (old->type || zend_hash_num_elements(&old->hdrs) || PHPSTR_LEN(old)) {
-+ (*message) = http_message_new();
-+ (*message)->parent = old;
-+ (*headers) = &((*message)->hdrs);
-+ }
-+
-+ http_message_set_info(*message, info);
-+}
-+
-+#define http_message_init_type _http_message_init_type
-+static inline void _http_message_init_type(http_message *message, http_message_type type)
-+{
-+ message->http.version = .0;
-+
-+ switch (message->type = type) {
-+ case HTTP_MSG_RESPONSE:
-+ message->http.info.response.code = 0;
-+ message->http.info.response.status = NULL;
-+ break;
-+
-+ case HTTP_MSG_REQUEST:
-+ message->http.info.request.method = NULL;
-+ message->http.info.request.url = NULL;
-+ break;
-+
-+ case HTTP_MSG_NONE:
-+ default:
-+ break;
-+ }
-+}
-+
-+PHP_HTTP_API http_message *_http_message_init_ex(http_message *message, http_message_type type ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
-+{
-+ if (!message) {
-+ message = ecalloc_rel(1, sizeof(http_message));
-+ }
-+
-+ http_message_init_type(message, type);
-+ message->parent = NULL;
-+ phpstr_init(&message->body);
-+ zend_hash_init(&message->hdrs, 0, NULL, ZVAL_PTR_DTOR, 0);
-+
-+ return message;
-+}
-+
-+PHP_HTTP_API http_message *_http_message_init_env(http_message *message, http_message_type type TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
-+{
-+ int free_msg;
-+ http_info inf;
-+ zval *sval, tval;
-+ char *body_str;
-+ size_t body_len;
-+
-+ if ((free_msg = !message)) {
-+ message = http_message_init_rel(NULL, HTTP_MSG_NONE);
-+ }
-+
-+ memset(&inf, 0, sizeof(http_info));
-+ switch (inf.type = type) {
-+ case HTTP_MSG_REQUEST:
-+ if ((sval = http_get_server_var("SERVER_PROTOCOL", 1)) && !strncmp(Z_STRVAL_P(sval), "HTTP/", lenof("HTTP/"))) {
-+ inf.http.version = zend_strtod(Z_STRVAL_P(sval) + lenof("HTTP/"), NULL);
-+ } else {
-+ inf.http.version = 1.1;
-+ }
-+ if ((sval = http_get_server_var("REQUEST_METHOD", 1))) {
-+ inf.http.info.request.method = estrdup(Z_STRVAL_P(sval));
-+ }
-+ if ((sval = http_get_server_var("REQUEST_URI", 1))) {
-+ inf.http.info.request.url = estrdup(Z_STRVAL_P(sval));
-+ }
-+
-+ http_message_set_info(message, &inf);
-+ http_get_request_headers(&message->hdrs);
-+ if (SUCCESS == http_get_request_body_ex(&body_str, &body_len, 0)) {
-+ phpstr_from_string_ex(&message->body, body_str, body_len);
-+ }
-+ break;
-+
-+ case HTTP_MSG_RESPONSE:
-+ if (!SG(sapi_headers).http_status_line || SUCCESS != http_info_parse_ex(SG(sapi_headers).http_status_line, &inf, 0)) {
-+ inf.http.version = 1.1;
-+ inf.http.info.response.code = 200;
-+ inf.http.info.response.status = estrdup("Ok");
-+ }
-+
-+ http_message_set_info(message, &inf);
-+ http_get_response_headers(&message->hdrs);
-+#ifdef PHP_OUTPUT_NEWAPI
-+ if (SUCCESS == php_output_get_contents(&tval TSRMLS_CC)) {
-+#else
-+ if (SUCCESS == php_ob_get_buffer(&tval TSRMLS_CC)) {
-+#endif
-+ message->body.data = Z_STRVAL(tval);
-+ message->body.used = Z_STRLEN(tval);
-+ message->body.free = 1; /* "\0" */
-+ }
-+ break;
-+
-+ default:
-+ if (free_msg) {
-+ http_message_free(&message);
-+ } else {
-+ message = NULL;
-+ }
-+ break;
-+ }
-+ http_info_dtor(&inf);
-+
-+ return message;
-+}
-+
-+PHP_HTTP_API void _http_message_set_type(http_message *message, http_message_type type)
-+{
-+ /* just act if different */
-+ if (type != message->type) {
-+
-+ /* free request info */
-+ switch (message->type) {
-+ case HTTP_MSG_REQUEST:
-+ STR_FREE(message->http.info.request.method);
-+ STR_FREE(message->http.info.request.url);
-+ break;
-+
-+ case HTTP_MSG_RESPONSE:
-+ STR_FREE(message->http.info.response.status);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* init */
-+ http_message_init_type(message, type);
-+ }
-+}
-+
-+PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info)
-+{
-+ http_message_set_type(message, info->type);
-+ message->http.version = info->http.version;
-+ switch (message->type) {
-+ case IS_HTTP_REQUEST:
-+ STR_SET(HTTP_INFO(message).request.url, HTTP_INFO(info).request.url ? estrdup(HTTP_INFO(info).request.url) : NULL);
-+ STR_SET(HTTP_INFO(message).request.method, HTTP_INFO(info).request.method ? estrdup(HTTP_INFO(info).request.method) : NULL);
-+ break;
-+
-+ case IS_HTTP_RESPONSE:
-+ HTTP_INFO(message).response.code = HTTP_INFO(info).response.code;
-+ STR_SET(HTTP_INFO(message).response.status, HTTP_INFO(info).response.status ? estrdup(HTTP_INFO(info).response.status) : NULL);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+#define http_message_body_parse(m, ms, ml, c) _http_message_body_parse((m), (ms), (ml), (c) TSRMLS_CC)
-+static inline void _http_message_body_parse(http_message *msg, const char *message, size_t message_length, const char **continue_at TSRMLS_DC)
-+{
-+ zval *c;
-+ size_t remaining;
-+ const char *body;
-+
-+ *continue_at = NULL;
-+ if ((body = http_locate_body(message))) {
-+ remaining = message + message_length - body;
-+
-+ if ((c = http_message_header(msg, "Transfer-Encoding"))) {
-+ if (strstr(Z_STRVAL_P(c), "chunked")) {
-+ /* message has chunked transfer encoding */
-+ char *decoded;
-+ size_t decoded_len;
-+
-+ /* decode and replace Transfer-Encoding with Content-Length header */
-+ if ((*continue_at = http_encoding_dechunk(body, message + message_length - body, &decoded, &decoded_len))) {
-+ zval *len;
-+ char *tmp;
-+ int tmp_len;
-+
-+ tmp_len = (int) spprintf(&tmp, 0, "%zu", decoded_len);
-+ MAKE_STD_ZVAL(len);
-+ ZVAL_STRINGL(len, tmp, tmp_len, 0);
-+
-+ ZVAL_ADDREF(c);
-+ zend_hash_update(&msg->hdrs, "X-Original-Transfer-Encoding", sizeof("X-Original-Transfer-Encoding"), (void *) &c, sizeof(zval *), NULL);
-+ zend_hash_del(&msg->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding"));
-+ zend_hash_del(&msg->hdrs, "Content-Length", sizeof("Content-Length"));
-+ zend_hash_update(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &len, sizeof(zval *), NULL);
-+
-+ phpstr_from_string_ex(PHPSTR(msg), decoded, decoded_len);
-+ efree(decoded);
-+ }
-+ }
-+ zval_ptr_dtor(&c);
-+ }
-+
-+ if (!*continue_at && (c = http_message_header(msg, "Content-Length"))) {
-+ /* message has content-length header */
-+ ulong len = strtoul(Z_STRVAL_P(c), NULL, 10);
-+ if (len > remaining) {
-+ http_error_ex(HE_NOTICE, HTTP_E_MALFORMED_HEADERS, "The Content-Length header pretends a larger body than actually received (expected %lu bytes; got %lu bytes)", len, remaining);
-+ len = remaining;
-+ }
-+ phpstr_from_string_ex(PHPSTR(msg), body, len);
-+ *continue_at = body + len;
-+ zval_ptr_dtor(&c);
-+ }
-+
-+ if (!*continue_at && (c = http_message_header(msg, "Content-Range"))) {
-+ /* message has content-range header */
-+ ulong total = 0, start = 0, end = 0, len = 0;
-+
-+ if (!strncasecmp(Z_STRVAL_P(c), "bytes", lenof("bytes")) &&
-+ ( Z_STRVAL_P(c)[lenof("bytes")] == ':' ||
-+ Z_STRVAL_P(c)[lenof("bytes")] == ' ' ||
-+ Z_STRVAL_P(c)[lenof("bytes")] == '=')) {
-+ char *total_at = NULL, *end_at = NULL;
-+ char *start_at = Z_STRVAL_P(c) + sizeof("bytes");
-+
-+ start = strtoul(start_at, &end_at, 10);
-+ if (end_at) {
-+ end = strtoul(end_at + 1, &total_at, 10);
-+ if (total_at && strncmp(total_at + 1, "*", 1)) {
-+ total = strtoul(total_at + 1, NULL, 10);
-+ }
-+ if ((len = (end + 1 - start)) > remaining) {
-+ http_error_ex(HE_NOTICE, HTTP_E_MALFORMED_HEADERS, "The Content-Range header pretends a larger body than actually received (expected %lu bytes; got %lu bytes)", len, remaining);
-+ len = remaining;
-+ }
-+ if (end >= start && (!total || end < total)) {
-+ phpstr_from_string_ex(PHPSTR(msg), body, len);
-+ *continue_at = body + len;
-+ }
-+ }
-+ }
-+
-+ if (!*continue_at) {
-+ http_error_ex(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Invalid Content-Range header: %s", Z_STRVAL_P(c));
-+ }
-+ zval_ptr_dtor(&c);
-+ }
-+
-+ if (!*continue_at) {
-+ /* no headers that indicate content length */
-+ if (HTTP_MSG_TYPE(RESPONSE, msg)) {
-+ phpstr_from_string_ex(PHPSTR(msg), body, remaining);
-+ } else {
-+ *continue_at = body;
-+ }
-+ }
-+
-+#ifdef HTTP_HAVE_ZLIB
-+ /* check for compressed data */
-+ if ((c = http_message_header(msg, "Content-Encoding"))) {
-+ char *decoded = NULL;
-+ size_t decoded_len = 0;
-+
-+ if ( !strcasecmp(Z_STRVAL_P(c), "gzip") ||
-+ !strcasecmp(Z_STRVAL_P(c), "x-gzip") ||
-+ !strcasecmp(Z_STRVAL_P(c), "deflate")) {
-+ http_encoding_inflate(PHPSTR_VAL(msg), PHPSTR_LEN(msg), &decoded, &decoded_len);
-+ }
-+
-+ if (decoded) {
-+ zval *len, **original_len;
-+ char *tmp;
-+ int tmp_len;
-+
-+ tmp_len = (int) spprintf(&tmp, 0, "%zu", decoded_len);
-+ MAKE_STD_ZVAL(len);
-+ ZVAL_STRINGL(len, tmp, tmp_len, 0);
-+
-+ ZVAL_ADDREF(c);
-+ zend_hash_update(&msg->hdrs, "X-Original-Content-Encoding", sizeof("X-Original-Content-Encoding"), (void *) &c, sizeof(zval *), NULL);
-+ zend_hash_del(&msg->hdrs, "Content-Encoding", sizeof("Content-Encoding"));
-+ if (SUCCESS == zend_hash_find(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &original_len)) {
-+ ZVAL_ADDREF(*original_len);
-+ zend_hash_update(&msg->hdrs, "X-Original-Content-Length", sizeof("X-Original-Content-Length"), (void *) original_len, sizeof(zval *), NULL);
-+ zend_hash_update(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &len, sizeof(zval *), NULL);
-+ } else {
-+ zend_hash_update(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void *) &len, sizeof(zval *), NULL);
-+ }
-+
-+ phpstr_dtor(PHPSTR(msg));
-+ PHPSTR(msg)->data = decoded;
-+ PHPSTR(msg)->used = decoded_len;
-+ PHPSTR(msg)->free = 1;
-+ }
-+
-+ zval_ptr_dtor(&c);
-+ }
-+#endif /* HTTP_HAVE_ZLIB */
-+ }
-+}
-+
-+PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t message_length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ const char *continue_at;
-+ zend_bool free_msg = msg ? 0 : 1;
-+
-+ if ((!message) || (message_length < HTTP_MSG_MIN_SIZE)) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Empty or too short HTTP message: '%s'", message);
-+ return NULL;
-+ }
-+
-+ msg = http_message_init_rel(msg, 0);
-+
-+ if (SUCCESS != http_parse_headers_cb(message, &msg->hdrs, 1, (http_info_callback) http_message_info_callback, (void *) &msg)) {
-+ if (free_msg) {
-+ http_message_free(&msg);
-+ }
-+ http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Failed to parse message headers");
-+ return NULL;
-+ }
-+
-+ http_message_body_parse(msg, message, message_length, &continue_at);
-+
-+ /* check for following messages */
-+ if (continue_at && (continue_at < (message + message_length))) {
-+ while (HTTP_IS_CTYPE(space, *continue_at)) ++continue_at;
-+ if (continue_at < (message + message_length)) {
-+ http_message *next = NULL, *most = NULL;
-+
-+ /* set current message to parent of most parent following messages and return deepest */
-+ if ((most = next = http_message_parse_rel(NULL, continue_at, message + message_length - continue_at))) {
-+ while (most->parent) most = most->parent;
-+ most->parent = msg;
-+ msg = next;
-+ }
-+ }
-+ }
-+
-+ return msg;
-+}
-+
-+PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_t *length)
-+{
-+ phpstr str;
-+ HashKey key = initHashKey(0);
-+ zval **header;
-+ char *data;
-+ HashPosition pos1;
-+
-+ phpstr_init_ex(&str, 4096, 0);
-+
-+ switch (msg->type) {
-+ case HTTP_MSG_REQUEST:
-+ phpstr_appendf(&str, HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, HTTP_CRLF));
-+ break;
-+
-+ case HTTP_MSG_RESPONSE:
-+ phpstr_appendf(&str, HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, HTTP_CRLF));
-+ break;
-+
-+ case HTTP_MSG_NONE:
-+ default:
-+ break;
-+ }
-+
-+ FOREACH_HASH_KEYVAL(pos1, &msg->hdrs, key, header) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ HashPosition pos2;
-+ zval **single_header;
-+
-+ switch (Z_TYPE_PP(header)) {
-+ case IS_BOOL:
-+ phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_BVAL_PP(header)?"true":"false");
-+ break;
-+
-+ case IS_LONG:
-+ phpstr_appendf(&str, "%s: %ld" HTTP_CRLF, key.str, Z_LVAL_PP(header));
-+ break;
-+
-+ case IS_DOUBLE:
-+ phpstr_appendf(&str, "%s: %f" HTTP_CRLF, key.str, Z_DVAL_PP(header));
-+ break;
-+
-+ case IS_STRING:
-+ phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_STRVAL_PP(header));
-+ break;
-+
-+ case IS_ARRAY:
-+ FOREACH_VAL(pos2, *header, single_header) {
-+ switch (Z_TYPE_PP(single_header)) {
-+ case IS_BOOL:
-+ phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_BVAL_PP(single_header)?"true":"false");
-+ break;
-+
-+ case IS_LONG:
-+ phpstr_appendf(&str, "%s: %ld" HTTP_CRLF, key.str, Z_LVAL_PP(single_header));
-+ break;
-+
-+ case IS_DOUBLE:
-+ phpstr_appendf(&str, "%s: %f" HTTP_CRLF, key.str, Z_DVAL_PP(single_header));
-+ break;
-+
-+ case IS_STRING:
-+ phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_STRVAL_PP(single_header));
-+ break;
-+ }
-+ }
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (PHPSTR_LEN(msg)) {
-+ phpstr_appends(&str, HTTP_CRLF);
-+ phpstr_append(&str, PHPSTR_VAL(msg), PHPSTR_LEN(msg));
-+ phpstr_appends(&str, HTTP_CRLF);
-+ }
-+
-+ data = phpstr_data(&str, string, length);
-+ if (!string) {
-+ efree(data);
-+ }
-+
-+ phpstr_dtor(&str);
-+}
-+
-+PHP_HTTP_API void _http_message_serialize(http_message *message, char **string, size_t *length)
-+{
-+ char *buf;
-+ size_t len;
-+ phpstr str;
-+
-+ phpstr_init(&str);
-+
-+ do {
-+ http_message_tostring(message, &buf, &len);
-+ phpstr_prepend(&str, buf, len);
-+ efree(buf);
-+ } while ((message = message->parent));
-+
-+ buf = phpstr_data(&str, string, length);
-+ if (!string) {
-+ efree(buf);
-+ }
-+
-+ phpstr_dtor(&str);
-+}
-+
-+PHP_HTTP_API http_message *_http_message_reverse(http_message *msg)
-+{
-+ int i, c;
-+
-+ http_message_count(c, msg);
-+
-+ if (c > 1) {
-+ http_message *tmp = msg, **arr = ecalloc(c, sizeof(http_message *));
-+
-+ for (i = 0; i < c; ++i) {
-+ arr[i] = tmp;
-+ tmp = tmp->parent;
-+ }
-+ arr[0]->parent = NULL;
-+ for (i = 0; i < c-1; ++i) {
-+ arr[i+1]->parent = arr[i];
-+ }
-+
-+ msg = arr[c-1];
-+ efree(arr);
-+ }
-+
-+ return msg;
-+}
-+
-+PHP_HTTP_API http_message *_http_message_interconnect(http_message *m1, http_message *m2)
-+{
-+ if (m1 && m2) {
-+ int i = 0, c1, c2;
-+ http_message *t1 = m1, *t2 = m2, *p1, *p2;
-+
-+ http_message_count(c1, m1);
-+ http_message_count(c2, m2);
-+
-+ while (i++ < (c1 - c2)) {
-+ t1 = t1->parent;
-+ }
-+ while (i++ <= c1) {
-+ p1 = t1->parent;
-+ p2 = t2->parent;
-+ t1->parent = t2;
-+ t2->parent = p1;
-+ t1 = p1;
-+ t2 = p2;
-+ }
-+ } else if (!m1 && m2) {
-+ m1 = m2;
-+ }
-+ return m1;
-+}
-+
-+PHP_HTTP_API void _http_message_tostruct_recursive(http_message *msg, zval *obj TSRMLS_DC)
-+{
-+ zval strct;
-+ zval *headers;
-+
-+ INIT_ZARR(strct, HASH_OF(obj));
-+
-+ add_assoc_long(&strct, "type", msg->type);
-+ add_assoc_double(&strct, "httpVersion", msg->http.version);
-+ switch (msg->type)
-+ {
-+ case HTTP_MSG_RESPONSE:
-+ add_assoc_long(&strct, "responseCode", msg->http.info.response.code);
-+ add_assoc_string(&strct, "responseStatus", STR_PTR(msg->http.info.response.status), 1);
-+ break;
-+
-+ case HTTP_MSG_REQUEST:
-+ add_assoc_string(&strct, "requestMethod", STR_PTR(msg->http.info.request.method), 1);
-+ add_assoc_string(&strct, "requestUrl", STR_PTR(msg->http.info.request.url), 1);
-+ break;
-+
-+ case HTTP_MSG_NONE:
-+ /* avoid compiler warning */
-+ break;
-+ }
-+
-+ MAKE_STD_ZVAL(headers);
-+ array_init(headers);
-+ zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ add_assoc_zval(&strct, "headers", headers);
-+
-+ add_assoc_stringl(&strct, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg), 1);
-+
-+ if (msg->parent) {
-+ zval *parent;
-+
-+ MAKE_STD_ZVAL(parent);
-+ if (Z_TYPE_P(obj) == IS_ARRAY) {
-+ array_init(parent);
-+ } else {
-+ object_init(parent);
-+ }
-+ add_assoc_zval(&strct, "parentMessage", parent);
-+ http_message_tostruct_recursive(msg->parent, parent);
-+ } else {
-+ add_assoc_null(&strct, "parentMessage");
-+ }
-+}
-+
-+PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC)
-+{
-+ STATUS rs = FAILURE;
-+
-+ switch (message->type) {
-+ case HTTP_MSG_RESPONSE:
-+ {
-+ HashKey key = initHashKey(0);
-+ zval **val;
-+ HashPosition pos;
-+
-+ FOREACH_HASH_KEYVAL(pos, &message->hdrs, key, val) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ http_send_header_zval_ex(key.str, key.len-1, val, 1);
-+ }
-+ }
-+ rs = SUCCESS == http_send_status(message->http.info.response.code) &&
-+ SUCCESS == http_send_data(PHPSTR_VAL(message), PHPSTR_LEN(message)) ?
-+ SUCCESS : FAILURE;
-+ break;
-+ }
-+
-+ case HTTP_MSG_REQUEST:
-+ {
-+#ifdef HTTP_HAVE_CURL
-+ char *uri = NULL;
-+ http_request request;
-+ zval **zhost, *options, *headers;
-+
-+ MAKE_STD_ZVAL(options);
-+ MAKE_STD_ZVAL(headers);
-+ array_init(options);
-+ array_init(headers);
-+ zend_hash_copy(Z_ARRVAL_P(headers), &message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ add_assoc_zval(options, "headers", headers);
-+
-+ /* check host header */
-+ if (SUCCESS == zend_hash_find(&message->hdrs, "Host", sizeof("Host"), (void *) &zhost) && Z_TYPE_PP(zhost) == IS_STRING) {
-+ char *colon = NULL;
-+ php_url parts, *url = php_url_parse(message->http.info.request.url);
-+
-+ memset(&parts, 0, sizeof(php_url));
-+
-+ /* check for port */
-+ if ((colon = strchr(Z_STRVAL_PP(zhost), ':'))) {
-+ parts.port = atoi(colon + 1);
-+ parts.host = estrndup(Z_STRVAL_PP(zhost), (Z_STRVAL_PP(zhost) - colon - 1));
-+ } else {
-+ parts.host = estrndup(Z_STRVAL_PP(zhost), Z_STRLEN_PP(zhost));
-+ }
-+
-+ http_build_url(HTTP_URL_REPLACE, url, &parts, NULL, &uri, NULL);
-+ php_url_free(url);
-+ efree(parts.host);
-+ } else {
-+ uri = http_absolute_url(message->http.info.request.url);
-+ }
-+
-+ if ((request.meth = http_request_method_exists(1, 0, message->http.info.request.method))) {
-+ http_request_body body;
-+
-+ http_request_init_ex(&request, NULL, request.meth, uri);
-+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, PHPSTR_VAL(message), PHPSTR_LEN(message), 0);
-+ if (SUCCESS == (rs = http_request_prepare(&request, Z_ARRVAL_P(options)))) {
-+ http_request_exec(&request);
-+ }
-+ http_request_dtor(&request);
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD,
-+ "Cannot send HttpMessage. Request method %s not supported",
-+ message->http.info.request.method);
-+ }
-+ efree(uri);
-+ zval_ptr_dtor(&options);
-+#else
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "HTTP requests not supported - ext/http was not linked against libcurl.");
-+#endif
-+ break;
-+ }
-+
-+ case HTTP_MSG_NONE:
-+ default:
-+ http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is neither of type HTTP_MSG_REQUEST nor HTTP_MSG_RESPONSE");
-+ break;
-+ }
-+
-+ return rs;
-+}
-+
-+PHP_HTTP_API http_message *_http_message_dup(http_message *orig TSRMLS_DC)
-+{
-+ http_message *temp, *copy = NULL;
-+ http_info info;
-+
-+ if (orig) {
-+ info.type = orig->type;
-+ info.http = orig->http;
-+
-+ copy = temp = http_message_new();
-+ http_message_set_info(temp, &info);
-+ zend_hash_copy(&temp->hdrs, &orig->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ phpstr_append(&temp->body, orig->body.data, orig->body.used);
-+
-+ while (orig->parent) {
-+ info.type = orig->parent->type;
-+ info.http = orig->parent->http;
-+
-+ temp->parent = http_message_new();
-+ http_message_set_info(temp->parent, &info);
-+ zend_hash_copy(&temp->parent->hdrs, &orig->parent->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ phpstr_append(&temp->parent->body, orig->parent->body.data, orig->parent->body.used);
-+
-+ temp = temp->parent;
-+ orig = orig->parent;
-+ }
-+ }
-+
-+ return copy;
-+}
-+
-+PHP_HTTP_API void _http_message_dtor(http_message *message)
-+{
-+ if (message) {
-+ zend_hash_destroy(&message->hdrs);
-+ phpstr_dtor(PHPSTR(message));
-+
-+ switch (message->type) {
-+ case HTTP_MSG_REQUEST:
-+ STR_SET(message->http.info.request.method, NULL);
-+ STR_SET(message->http.info.request.url, NULL);
-+ break;
-+
-+ case HTTP_MSG_RESPONSE:
-+ STR_SET(message->http.info.response.status, NULL);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+}
-+
-+PHP_HTTP_API void _http_message_free(http_message **message)
-+{
-+ if (*message) {
-+ if ((*message)->parent) {
-+ http_message_free(&(*message)->parent);
-+ }
-+ http_message_dtor(*message);
-+ efree(*message);
-+ *message = NULL;
-+ }
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_message_object.c
-@@ -0,0 +1,1555 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_message_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_CURL
-+#define HTTP_WANT_MAGIC
-+#include "php_http.h"
-+
-+#ifdef ZEND_ENGINE_2
-+
-+#include "zend_interfaces.h"
-+#include "ext/standard/url.h"
-+#include "php_variables.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_send_api.h"
-+#include "php_http_url_api.h"
-+#include "php_http_message_api.h"
-+#include "php_http_message_object.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_response_object.h"
-+#include "php_http_request_method_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+#include "php_http_headers_api.h"
-+
-+#if defined(HTTP_HAVE_SPL) && !defined(WONKY)
-+/* SPL doesn't install its headers */
-+extern PHPAPI zend_class_entry *spl_ce_Countable;
-+#endif
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpMessage, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpMessage, method, 0)
-+#define HTTP_MESSAGE_ME(method, visibility) PHP_ME(HttpMessage, method, HTTP_ARGS(HttpMessage, method), visibility)
-+
-+HTTP_BEGIN_ARGS(__construct, 0)
-+ HTTP_ARG_VAL(message, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(message, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(fromEnv, 1)
-+ HTTP_ARG_VAL(type, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getBody);
-+HTTP_BEGIN_ARGS(setBody, 1)
-+ HTTP_ARG_VAL(body, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(getHeader, 1)
-+ HTTP_ARG_VAL(header, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getHeaders);
-+HTTP_BEGIN_ARGS(setHeaders, 1)
-+ HTTP_ARG_VAL(headers, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addHeaders, 1)
-+ HTTP_ARG_VAL(headers, 0)
-+ HTTP_ARG_VAL(append, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getType);
-+HTTP_BEGIN_ARGS(setType, 1)
-+ HTTP_ARG_VAL(type, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getInfo);
-+HTTP_BEGIN_ARGS(setInfo, 1)
-+ HTTP_ARG_VAL(http_info, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getResponseCode);
-+HTTP_BEGIN_ARGS(setResponseCode, 1)
-+ HTTP_ARG_VAL(response_code, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getResponseStatus);
-+HTTP_BEGIN_ARGS(setResponseStatus, 1)
-+ HTTP_ARG_VAL(response_status, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getRequestMethod);
-+HTTP_BEGIN_ARGS(setRequestMethod, 1)
-+ HTTP_ARG_VAL(request_method, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getRequestUrl);
-+HTTP_BEGIN_ARGS(setRequestUrl, 1)
-+ HTTP_ARG_VAL(url, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getHttpVersion);
-+HTTP_BEGIN_ARGS(setHttpVersion, 1)
-+ HTTP_ARG_VAL(http_version, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(guessContentType, 1)
-+ HTTP_ARG_VAL(magic_file, 0)
-+ HTTP_ARG_VAL(magic_mode, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getParentMessage);
-+HTTP_EMPTY_ARGS(send);
-+HTTP_EMPTY_ARGS(__toString);
-+HTTP_BEGIN_ARGS(toString, 0)
-+ HTTP_ARG_VAL(include_parent, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(toMessageTypeObject);
-+
-+HTTP_EMPTY_ARGS(count);
-+
-+HTTP_EMPTY_ARGS(serialize);
-+HTTP_BEGIN_ARGS(unserialize, 1)
-+ HTTP_ARG_VAL(serialized, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(rewind);
-+HTTP_EMPTY_ARGS(valid);
-+HTTP_EMPTY_ARGS(key);
-+HTTP_EMPTY_ARGS(current);
-+HTTP_EMPTY_ARGS(next);
-+
-+HTTP_EMPTY_ARGS(detach);
-+HTTP_BEGIN_ARGS(prepend, 1)
-+ HTTP_ARG_OBJ(HttpMessage, message, 0)
-+HTTP_END_ARGS;
-+HTTP_EMPTY_ARGS(reverse);
-+
-+#define http_message_object_read_prop _http_message_object_read_prop
-+static zval *_http_message_object_read_prop(zval *object, zval *member, int type ZEND_LITERAL_KEY_DC TSRMLS_DC);
-+#define http_message_object_write_prop _http_message_object_write_prop
-+static void _http_message_object_write_prop(zval *object, zval *member, zval *value ZEND_LITERAL_KEY_DC TSRMLS_DC);
-+#define http_message_object_get_prop_ptr _http_message_object_get_prop_ptr
-+static zval **_http_message_object_get_prop_ptr(zval *object, zval *member ZEND_LITERAL_KEY_DC TSRMLS_DC);
-+#define http_message_object_get_props _http_message_object_get_props
-+static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC);
-+
-+#define THIS_CE http_message_object_ce
-+zend_class_entry *http_message_object_ce;
-+zend_function_entry http_message_object_fe[] = {
-+ HTTP_MESSAGE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+ HTTP_MESSAGE_ME(getBody, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setBody, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getHeader, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getHeaders, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setHeaders, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(addHeaders, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getType, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setType, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getInfo, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setInfo, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getResponseCode, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setResponseCode, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getResponseStatus, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setResponseStatus, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getRequestMethod, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setRequestMethod, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getRequestUrl, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setRequestUrl, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getHttpVersion, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(setHttpVersion, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(guessContentType, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(getParentMessage, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(send, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(toString, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(toMessageTypeObject, ZEND_ACC_PUBLIC)
-+
-+ /* implements Countable */
-+ HTTP_MESSAGE_ME(count, ZEND_ACC_PUBLIC)
-+
-+ /* implements Serializable */
-+ HTTP_MESSAGE_ME(serialize, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(unserialize, ZEND_ACC_PUBLIC)
-+
-+ /* implements Iterator */
-+ HTTP_MESSAGE_ME(rewind, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(valid, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(current, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(key, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(next, ZEND_ACC_PUBLIC)
-+
-+ ZEND_MALIAS(HttpMessage, __toString, toString, HTTP_ARGS(HttpMessage, __toString), ZEND_ACC_PUBLIC)
-+
-+ HTTP_MESSAGE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+ ZEND_MALIAS(HttpMessage, fromString, factory, HTTP_ARGS(HttpMessage, factory), ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+ HTTP_MESSAGE_ME(fromEnv, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+
-+ HTTP_MESSAGE_ME(detach, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(prepend, ZEND_ACC_PUBLIC)
-+ HTTP_MESSAGE_ME(reverse, ZEND_ACC_PUBLIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_message_object_handlers;
-+
-+static HashTable http_message_object_prophandlers;
-+
-+typedef void (*http_message_object_prophandler_func)(http_message_object *o, zval *v TSRMLS_DC);
-+
-+typedef struct _http_message_object_prophandler {
-+ http_message_object_prophandler_func read;
-+ http_message_object_prophandler_func write;
-+} http_message_object_prophandler;
-+
-+static STATUS http_message_object_add_prophandler(const char *prop_str, size_t prop_len, http_message_object_prophandler_func read, http_message_object_prophandler_func write) {
-+ http_message_object_prophandler h = { read, write };
-+ return zend_hash_add(&http_message_object_prophandlers, prop_str, prop_len, (void *) &h, sizeof(h), NULL);
-+}
-+static STATUS http_message_object_get_prophandler(const char *prop_str, size_t prop_len, http_message_object_prophandler **handler) {
-+ return zend_hash_find(&http_message_object_prophandlers, prop_str, prop_len, (void *) handler);
-+}
-+static void http_message_object_prophandler_get_type(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ RETVAL_LONG(obj->message->type);
-+}
-+static void http_message_object_prophandler_set_type(http_message_object *obj, zval *value TSRMLS_DC) {
-+ zval *cpy = http_zsep(IS_LONG, value);
-+ http_message_set_type(obj->message, Z_LVAL_P(cpy));
-+ zval_ptr_dtor(&cpy);
-+}
-+static void http_message_object_prophandler_get_body(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ phpstr_fix(PHPSTR(obj->message));
-+ RETVAL_PHPSTR(PHPSTR(obj->message), 0, 1);
-+}
-+static void http_message_object_prophandler_set_body(http_message_object *obj, zval *value TSRMLS_DC) {
-+ zval *cpy = http_zsep(IS_STRING, value);
-+ phpstr_dtor(PHPSTR(obj->message));
-+ phpstr_from_string_ex(PHPSTR(obj->message), Z_STRVAL_P(cpy), Z_STRLEN_P(cpy));
-+ zval_ptr_dtor(&cpy);
-+}
-+static void http_message_object_prophandler_get_request_method(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(REQUEST, obj->message) && obj->message->http.info.request.method) {
-+ RETVAL_STRING(obj->message->http.info.request.method, 1);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+}
-+static void http_message_object_prophandler_set_request_method(http_message_object *obj, zval *value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(REQUEST, obj->message)) {
-+ zval *cpy = http_zsep(IS_STRING, value);
-+ STR_SET(obj->message->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
-+ zval_ptr_dtor(&cpy);
-+ }
-+}
-+static void http_message_object_prophandler_get_request_url(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(REQUEST, obj->message) && obj->message->http.info.request.url) {
-+ RETVAL_STRING(obj->message->http.info.request.url, 1);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+}
-+static void http_message_object_prophandler_set_request_url(http_message_object *obj, zval *value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(REQUEST, obj->message)) {
-+ zval *cpy = http_zsep(IS_STRING, value);
-+ STR_SET(obj->message->http.info.request.url, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
-+ zval_ptr_dtor(&cpy);
-+ }
-+}
-+static void http_message_object_prophandler_get_response_status(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(RESPONSE, obj->message) && obj->message->http.info.response.status) {
-+ RETVAL_STRING(obj->message->http.info.response.status, 1);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+}
-+static void http_message_object_prophandler_set_response_status(http_message_object *obj, zval *value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(RESPONSE, obj->message)) {
-+ zval *cpy = http_zsep(IS_STRING, value);
-+ STR_SET(obj->message->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
-+ zval_ptr_dtor(&cpy);
-+ }
-+}
-+static void http_message_object_prophandler_get_response_code(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(RESPONSE, obj->message)) {
-+ RETVAL_LONG(obj->message->http.info.response.code);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+}
-+static void http_message_object_prophandler_set_response_code(http_message_object *obj, zval *value TSRMLS_DC) {
-+ if (HTTP_MSG_TYPE(RESPONSE, obj->message)) {
-+ zval *cpy = http_zsep(IS_LONG, value);
-+ obj->message->http.info.response.code = Z_LVAL_P(cpy);
-+ zval_ptr_dtor(&cpy);
-+ }
-+}
-+static void http_message_object_prophandler_get_http_version(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ RETVAL_DOUBLE(obj->message->http.version);
-+}
-+static void http_message_object_prophandler_set_http_version(http_message_object *obj, zval *value TSRMLS_DC) {
-+ zval *cpy = http_zsep(IS_DOUBLE, value);
-+ obj->message->http.version = Z_DVAL_P(cpy);
-+ zval_ptr_dtor(&cpy);
-+}
-+static void http_message_object_prophandler_get_headers(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ array_init(return_value);
-+ zend_hash_copy(Z_ARRVAL_P(return_value), &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+}
-+static void http_message_object_prophandler_set_headers(http_message_object *obj, zval *value TSRMLS_DC) {
-+ zval *cpy = http_zsep(IS_ARRAY, value);
-+ zend_hash_clean(&obj->message->hdrs);
-+ zend_hash_copy(&obj->message->hdrs, Z_ARRVAL_P(cpy), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ zval_ptr_dtor(&cpy);
-+}
-+static void http_message_object_prophandler_get_parent_message(http_message_object *obj, zval *return_value TSRMLS_DC) {
-+ if (obj->message->parent) {
-+ RETVAL_OBJVAL(obj->parent, 1);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+}
-+static void http_message_object_prophandler_set_parent_message(http_message_object *obj, zval *value TSRMLS_DC) {
-+ if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), http_message_object_ce TSRMLS_CC)) {
-+ if (obj->message->parent) {
-+ zval tmp;
-+ tmp.value.obj = obj->parent;
-+ Z_OBJ_DELREF(tmp);
-+ }
-+ Z_OBJ_ADDREF_P(value);
-+ obj->parent = value->value.obj;
-+ }
-+}
-+
-+PHP_MINIT_FUNCTION(http_message_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpMessage, http_message_object, NULL, 0);
-+
-+#ifndef WONKY
-+# ifdef HTTP_HAVE_SPL
-+ zend_class_implements(http_message_object_ce TSRMLS_CC, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator);
-+# else
-+ zend_class_implements(http_message_object_ce TSRMLS_CC, 2, zend_ce_serializable, zend_ce_iterator);
-+# endif
-+#else
-+ zend_class_implements(http_message_object_ce TSRMLS_CC, 1, zend_ce_iterator);
-+#endif
-+
-+ http_message_object_handlers.clone_obj = _http_message_object_clone_obj;
-+ http_message_object_handlers.read_property = http_message_object_read_prop;
-+ http_message_object_handlers.write_property = http_message_object_write_prop;
-+ http_message_object_handlers.get_properties = http_message_object_get_props;
-+ http_message_object_handlers.get_property_ptr_ptr = http_message_object_get_prop_ptr;
-+
-+ zend_hash_init(&http_message_object_prophandlers, 9, NULL, NULL, 1);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("type")-1, HTTP_MSG_NONE, ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("type")-1, http_message_object_prophandler_get_type, http_message_object_prophandler_set_type);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("body")-1, "", ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("body")-1, http_message_object_prophandler_get_body, http_message_object_prophandler_set_body);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("requestMethod")-1, "", ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("requestMethod")-1, http_message_object_prophandler_get_request_method, http_message_object_prophandler_set_request_method);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("requestUrl")-1, "", ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("requestUrl")-1, http_message_object_prophandler_get_request_url, http_message_object_prophandler_set_request_url);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("responseStatus")-1, "", ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("responseStatus")-1, http_message_object_prophandler_get_response_status, http_message_object_prophandler_set_response_status);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("responseCode")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("responseCode")-1, http_message_object_prophandler_get_response_code, http_message_object_prophandler_set_response_code);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("httpVersion")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("httpVersion")-1, http_message_object_prophandler_get_http_version, http_message_object_prophandler_set_http_version);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("headers")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("headers")-1, http_message_object_prophandler_get_headers, http_message_object_prophandler_set_headers);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("parentMessage")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-+ http_message_object_add_prophandler(ZEND_STRS("parentMessage")-1, http_message_object_prophandler_get_parent_message, http_message_object_prophandler_set_parent_message);
-+
-+#ifndef WONKY
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_NONE")-1, HTTP_MSG_NONE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_REQUEST")-1, HTTP_MSG_REQUEST TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_RESPONSE")-1, HTTP_MSG_RESPONSE TSRMLS_CC);
-+#endif
-+
-+ HTTP_LONG_CONSTANT("HTTP_MSG_NONE", HTTP_MSG_NONE);
-+ HTTP_LONG_CONSTANT("HTTP_MSG_REQUEST", HTTP_MSG_REQUEST);
-+ HTTP_LONG_CONSTANT("HTTP_MSG_RESPONSE", HTTP_MSG_RESPONSE);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_MSHUTDOWN_FUNCTION(http_message_object)
-+{
-+ zend_hash_destroy(&http_message_object_prophandlers);
-+
-+ return SUCCESS;
-+}
-+
-+void _http_message_object_reverse(zval *this_ptr, zval *return_value TSRMLS_DC)
-+{
-+ int i;
-+ getObject(http_message_object, obj);
-+
-+ /* count */
-+ http_message_count(i, obj->message);
-+
-+ if (i > 1) {
-+ zval o;
-+ zend_object_value *ovalues = NULL;
-+ http_message_object **objects = NULL;
-+ int last = i - 1;
-+
-+ objects = ecalloc(i, sizeof(http_message_object *));
-+ ovalues = ecalloc(i, sizeof(zend_object_value));
-+
-+ /* we are the first message */
-+ objects[0] = obj;
-+ ovalues[0] = getThis()->value.obj;
-+
-+ /* fetch parents */
-+ INIT_PZVAL(&o);
-+ o.type = IS_OBJECT;
-+ for (i = 1; obj->parent.handle; ++i) {
-+ o.value.obj = obj->parent;
-+ ovalues[i] = o.value.obj;
-+ objects[i] = obj = zend_object_store_get_object(&o TSRMLS_CC);
-+ }
-+
-+ /* reorder parents */
-+ for (last = --i; i; --i) {
-+ objects[i]->message->parent = objects[i-1]->message;
-+ objects[i]->parent = ovalues[i-1];
-+ }
-+ objects[0]->message->parent = NULL;
-+ objects[0]->parent.handle = 0;
-+ objects[0]->parent.handlers = NULL;
-+
-+ /* add ref (why?) */
-+ Z_OBJ_ADDREF_P(getThis());
-+ RETVAL_OBJVAL(ovalues[last], 1);
-+
-+ efree(objects);
-+ efree(ovalues);
-+ } else {
-+ RETURN_ZVAL(getThis(), 1, 0);
-+ }
-+}
-+
-+void _http_message_object_prepend_ex(zval *this_ptr, zval *prepend, zend_bool top TSRMLS_DC)
-+{
-+ zval m;
-+ http_message *save_parent_msg = NULL;
-+ zend_object_value save_parent_obj = {0, NULL};
-+ getObject(http_message_object, obj);
-+ getObjectEx(http_message_object, prepend_obj, prepend);
-+
-+ INIT_PZVAL(&m);
-+ m.type = IS_OBJECT;
-+
-+ if (!top) {
-+ save_parent_obj = obj->parent;
-+ save_parent_msg = obj->message->parent;
-+ } else {
-+ /* iterate to the most parent object */
-+ while (obj->parent.handle) {
-+ m.value.obj = obj->parent;
-+ obj = zend_object_store_get_object(&m TSRMLS_CC);
-+ }
-+ }
-+
-+ /* prepend */
-+ obj->parent = prepend->value.obj;
-+ obj->message->parent = prepend_obj->message;
-+
-+ /* add ref */
-+ zend_objects_store_add_ref(prepend TSRMLS_CC);
-+ while (prepend_obj->parent.handle) {
-+ m.value.obj = prepend_obj->parent;
-+ zend_objects_store_add_ref(&m TSRMLS_CC);
-+ prepend_obj = zend_object_store_get_object(&m TSRMLS_CC);
-+ }
-+
-+ if (!top) {
-+ prepend_obj->parent = save_parent_obj;
-+ prepend_obj->message->parent = save_parent_msg;
-+ }
-+}
-+
-+zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_message_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg, http_message_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_message_object *o;
-+
-+ o = ecalloc(1, sizeof(http_message_object));
-+ o->zo.ce = ce;
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+ if (msg) {
-+ o->message = msg;
-+ if (msg->parent) {
-+ o->parent = http_message_object_new_ex(ce, msg->parent, NULL);
-+ }
-+ }
-+
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_message_object, o);
-+ ov.handlers = &http_message_object_handlers;
-+
-+ return ov;
-+}
-+
-+zend_object_value _http_message_object_clone_obj(zval *this_ptr TSRMLS_DC)
-+{
-+ zend_object_value new_ov;
-+ http_message_object *new_obj = NULL;
-+ getObject(http_message_object, old_obj);
-+
-+ new_ov = http_message_object_new_ex(old_obj->zo.ce, http_message_dup(old_obj->message), &new_obj);
-+ zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
-+
-+ return new_ov;
-+}
-+
-+void _http_message_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_message_object *o = (http_message_object *) object;
-+
-+ if (o->iterator) {
-+ zval_ptr_dtor(&o->iterator);
-+ o->iterator = NULL;
-+ }
-+ if (o->message) {
-+ http_message_dtor(o->message);
-+ efree(o->message);
-+ }
-+ if (o->parent.handle) {
-+ zval p;
-+
-+ INIT_PZVAL(&p);
-+ p.type = IS_OBJECT;
-+ p.value.obj = o->parent;
-+ zend_objects_store_del_ref(&p TSRMLS_CC);
-+ }
-+ freeObject(o);
-+}
-+
-+static zval **_http_message_object_get_prop_ptr(zval *object, zval *member ZEND_LITERAL_KEY_DC TSRMLS_DC) {
-+ getObjectEx(http_message_object, obj, object);
-+ http_message_object_prophandler *handler;
-+
-+ if (SUCCESS == http_message_object_get_prophandler(Z_STRVAL_P(member), Z_STRLEN_P(member), &handler)) {
-+ zend_error(E_ERROR, "Cannot access HttpMessage properties by reference or array key/index");
-+ return NULL;
-+ }
-+
-+ return zend_get_std_object_handlers()->get_property_ptr_ptr(object, member ZEND_LITERAL_KEY_CC TSRMLS_CC);
-+}
-+
-+static zval *_http_message_object_read_prop(zval *object, zval *member, int type ZEND_LITERAL_KEY_DC TSRMLS_DC)
-+{
-+ getObjectEx(http_message_object, obj, object);
-+ http_message_object_prophandler *handler;
-+ zval *return_value;
-+
-+ if (SUCCESS == http_message_object_get_prophandler(Z_STRVAL_P(member), Z_STRLEN_P(member), &handler)) {
-+ if (type == BP_VAR_W) {
-+ zend_error(E_ERROR, "Cannot access HttpMessage properties by reference or array key/index");
-+ return NULL;
-+ }
-+
-+ ALLOC_ZVAL(return_value);
-+#ifdef Z_SET_REFCOUNT
-+ Z_SET_REFCOUNT_P(return_value, 0);
-+ Z_UNSET_ISREF_P(return_value);
-+#else
-+ return_value->refcount = 0;
-+ return_value->is_ref = 0;
-+#endif
-+
-+ handler->read(obj, return_value TSRMLS_CC);
-+
-+ } else {
-+ return_value = zend_get_std_object_handlers()->read_property(object, member, type ZEND_LITERAL_KEY_CC TSRMLS_CC);
-+ }
-+
-+ return return_value;
-+}
-+
-+static void _http_message_object_write_prop(zval *object, zval *member, zval *value ZEND_LITERAL_KEY_DC TSRMLS_DC)
-+{
-+ getObjectEx(http_message_object, obj, object);
-+ http_message_object_prophandler *handler;
-+
-+ if (SUCCESS == http_message_object_get_prophandler(Z_STRVAL_P(member), Z_STRLEN_P(member), &handler)) {
-+ handler->write(obj, value TSRMLS_CC);
-+ } else {
-+ zend_get_std_object_handlers()->write_property(object, member, value ZEND_LITERAL_KEY_CC TSRMLS_CC);
-+ }
-+}
-+
-+static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC)
-+{
-+ zval *headers;
-+ getObjectEx(http_message_object, obj, object);
-+ http_message *msg = obj->message;
-+ zval array, *parent;
-+#ifdef ZEND_ENGINE_2_4
-+ HashTable *props = zend_get_std_object_handlers()->get_properties(object TSRMLS_CC);
-+#else
-+ HashTable *props = OBJ_PROP(obj);
-+#endif
-+ INIT_ZARR(array, props);
-+
-+#define ASSOC_PROP(array, ptype, name, val) \
-+ { \
-+ char *m_prop_name; \
-+ int m_prop_len; \
-+ zend_mangle_property_name(&m_prop_name, &m_prop_len, "*", 1, name, lenof(name), 0); \
-+ add_assoc_ ##ptype## _ex(&array, m_prop_name, sizeof(name)+3, val); \
-+ efree(m_prop_name); \
-+ }
-+#define ASSOC_STRING(array, name, val) ASSOC_STRINGL(array, name, val, strlen(val))
-+#define ASSOC_STRINGL(array, name, val, len) \
-+ { \
-+ char *m_prop_name; \
-+ int m_prop_len; \
-+ zend_mangle_property_name(&m_prop_name, &m_prop_len, "*", 1, name, lenof(name), 0); \
-+ add_assoc_stringl_ex(&array, m_prop_name, sizeof(name)+3, val, len, 1); \
-+ efree(m_prop_name); \
-+ }
-+
-+ ASSOC_PROP(array, long, "type", msg->type);
-+ ASSOC_PROP(array, double, "httpVersion", msg->http.version);
-+
-+ switch (msg->type) {
-+ case HTTP_MSG_REQUEST:
-+ ASSOC_PROP(array, long, "responseCode", 0);
-+ ASSOC_STRINGL(array, "responseStatus", "", 0);
-+ ASSOC_STRING(array, "requestMethod", STR_PTR(msg->http.info.request.method));
-+ ASSOC_STRING(array, "requestUrl", STR_PTR(msg->http.info.request.url));
-+ break;
-+
-+ case HTTP_MSG_RESPONSE:
-+ ASSOC_PROP(array, long, "responseCode", msg->http.info.response.code);
-+ ASSOC_STRING(array, "responseStatus", STR_PTR(msg->http.info.response.status));
-+ ASSOC_STRINGL(array, "requestMethod", "", 0);
-+ ASSOC_STRINGL(array, "requestUrl", "", 0);
-+ break;
-+
-+ case HTTP_MSG_NONE:
-+ default:
-+ ASSOC_PROP(array, long, "responseCode", 0);
-+ ASSOC_STRINGL(array, "responseStatus", "", 0);
-+ ASSOC_STRINGL(array, "requestMethod", "", 0);
-+ ASSOC_STRINGL(array, "requestUrl", "", 0);
-+ break;
-+ }
-+
-+ MAKE_STD_ZVAL(headers);
-+ array_init(headers);
-+ zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ ASSOC_PROP(array, zval, "headers", headers);
-+ ASSOC_STRINGL(array, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg));
-+
-+ MAKE_STD_ZVAL(parent);
-+ if (msg->parent) {
-+ ZVAL_OBJVAL(parent, obj->parent, 1);
-+ } else {
-+ ZVAL_NULL(parent);
-+ }
-+ ASSOC_PROP(array, zval, "parentMessage", parent);
-+
-+ return props;
-+}
-+
-+/* ### USERLAND ### */
-+
-+/* {{{ proto void HttpMessage::__construct([string message])
-+ Create a new HttpMessage object instance. */
-+PHP_METHOD(HttpMessage, __construct)
-+{
-+ int length = 0;
-+ char *message = NULL;
-+
-+ getObject(http_message_object, obj);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &message, &length) && message && length) {
-+ http_message *msg = obj->message;
-+
-+ http_message_dtor(msg);
-+ if ((obj->message = http_message_parse_ex(msg, message, length))) {
-+ if (obj->message->parent) {
-+ obj->parent = http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, NULL);
-+ }
-+ } else {
-+ obj->message = http_message_init(msg);
-+ }
-+ }
-+ if (!obj->message) {
-+ obj->message = http_message_new();
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto static HttpMessage HttpMessage::factory([string raw_message[, string class_name = "HttpMessage"]])
-+ Create a new HttpMessage object instance. */
-+PHP_METHOD(HttpMessage, factory)
-+{
-+ char *string = NULL, *cn = NULL;
-+ int length = 0, cl = 0;
-+ http_message *msg = NULL;
-+ zend_object_value ov;
-+ http_message_object *obj = NULL;
-+
-+ RETVAL_NULL();
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &string, &length, &cn, &cl)) {
-+ if (length) {
-+ msg = http_message_parse(string, length);
-+ }
-+ if ((msg || !length) && SUCCESS == http_object_new(&ov, cn, cl, _http_message_object_new_ex, http_message_object_ce, msg, &obj)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ }
-+ if (obj && !obj->message) {
-+ obj->message = http_message_new();
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto static HttpMessage HttpMessage::fromEnv(int type[, string class_name = "HttpMessage"])
-+ Create a new HttpMessage object from environment representing either current request or response */
-+PHP_METHOD(HttpMessage, fromEnv)
-+{
-+ char *cn = NULL;
-+ int cl = 0;
-+ long type;
-+ http_message_object *obj = NULL;
-+ zend_object_value ov;
-+
-+ RETVAL_NULL();
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &type, &cn, &cl)) {
-+ if (SUCCESS == http_object_new(&ov, cn, cl, _http_message_object_new_ex, http_message_object_ce, http_message_init_env(NULL, type), &obj)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ }
-+ if (obj && !obj->message) {
-+ obj->message = http_message_new();
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getBody()
-+ Get the body of the parsed HttpMessage. */
-+PHP_METHOD(HttpMessage, getBody)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ RETURN_PHPSTR(&obj->message->body, PHPSTR_FREE_NOT, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::setBody(string body)
-+ Set the body of the HttpMessage. NOTE: Don't forget to update any headers accordingly. */
-+PHP_METHOD(HttpMessage, setBody)
-+{
-+ char *body;
-+ int len;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &body, &len)) {
-+ phpstr_dtor(PHPSTR(obj->message));
-+ phpstr_from_string_ex(PHPSTR(obj->message), body, len);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getHeader(string header)
-+ Get message header. */
-+PHP_METHOD(HttpMessage, getHeader)
-+{
-+ zval *header;
-+ char *orig_header, *nice_header;
-+ int header_len;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &orig_header, &header_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ nice_header = pretty_key(estrndup(orig_header, header_len), header_len, 1, 1);
-+ if ((header = http_message_header_ex(obj->message, nice_header, header_len + 1, 0))) {
-+ RETVAL_ZVAL(header, 1, 1);
-+ }
-+ efree(nice_header);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpMessage::getHeaders()
-+ Get Message Headers. */
-+PHP_METHOD(HttpMessage, getHeaders)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+
-+ array_init(return_value);
-+ array_copy(&obj->message->hdrs, Z_ARRVAL_P(return_value));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::setHeaders(array headers)
-+ Sets new headers. */
-+PHP_METHOD(HttpMessage, setHeaders)
-+{
-+ zval *new_headers = NULL;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!", &new_headers)) {
-+ return;
-+ }
-+
-+ zend_hash_clean(&obj->message->hdrs);
-+ if (new_headers) {
-+ array_copy(Z_ARRVAL_P(new_headers), &obj->message->hdrs);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::addHeaders(array headers[, bool append = false])
-+ Add headers. If append is true, headers with the same name will be separated, else overwritten. */
-+PHP_METHOD(HttpMessage, addHeaders)
-+{
-+ zval *new_headers;
-+ zend_bool append = 0;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &new_headers, &append)) {
-+ return;
-+ }
-+
-+ array_join(Z_ARRVAL_P(new_headers), &obj->message->hdrs, append, ARRAY_JOIN_STRONLY|ARRAY_JOIN_PRETTIFY);
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpMessage::getType()
-+ Get Message Type. (HTTP_MSG_NONE|HTTP_MSG_REQUEST|HTTP_MSG_RESPONSE) */
-+PHP_METHOD(HttpMessage, getType)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ RETURN_LONG(obj->message->type);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::setType(int type)
-+ Set Message Type. (HTTP_MSG_NONE|HTTP_MSG_REQUEST|HTTP_MSG_RESPONSE) */
-+PHP_METHOD(HttpMessage, setType)
-+{
-+ long type;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type)) {
-+ return;
-+ }
-+ http_message_set_type(obj->message, type);
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getInfo(void)
-+ Get the HTTP request/response line */
-+PHP_METHOD(HttpMessage, getInfo)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+
-+ switch (obj->message->type) {
-+ case HTTP_MSG_REQUEST:
-+ Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, HTTP_INFO_REQUEST_FMT_ARGS(&obj->message->http, ""));
-+ break;
-+ case HTTP_MSG_RESPONSE:
-+ Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, HTTP_INFO_RESPONSE_FMT_ARGS(&obj->message->http, ""));
-+ break;
-+ default:
-+ RETURN_NULL();
-+ break;
-+ }
-+ Z_TYPE_P(return_value) = IS_STRING;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setInfo(string http_info)
-+ Set type and request or response info with a standard HTTP request or response line */
-+PHP_METHOD(HttpMessage, setInfo)
-+{
-+ char *str;
-+ int len;
-+ http_info inf;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) && SUCCESS == http_info_parse_ex(str, &inf, 0)) {
-+ getObject(http_message_object, obj);
-+
-+ http_message_set_info(obj->message, &inf);
-+ http_info_dtor(&inf);
-+ RETURN_TRUE;
-+ }
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpMessage::getResponseCode()
-+ Get the Response Code of the Message. */
-+PHP_METHOD(HttpMessage, getResponseCode)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE);
-+ RETURN_LONG(obj->message->http.info.response.code);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setResponseCode(int code)
-+ Set the response code of an HTTP Response Message. */
-+PHP_METHOD(HttpMessage, setResponseCode)
-+{
-+ long code;
-+ getObject(http_message_object, obj);
-+
-+ HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
-+ RETURN_FALSE;
-+ }
-+ if (code < 100 || code > 599) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid response code (100-599): %ld", code);
-+ RETURN_FALSE;
-+ }
-+
-+ obj->message->http.info.response.code = code;
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getResponseStatus()
-+ Get the Response Status of the message (i.e. the string following the response code). */
-+PHP_METHOD(HttpMessage, getResponseStatus)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE);
-+ if (obj->message->http.info.response.status) {
-+ RETURN_STRING(obj->message->http.info.response.status, 1);
-+ } else {
-+ RETURN_EMPTY_STRING();
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setResponseStatus(string status)
-+ Set the Response Status of the HTTP message (i.e. the string following the response code). */
-+PHP_METHOD(HttpMessage, setResponseStatus)
-+{
-+ char *status;
-+ int status_len;
-+ getObject(http_message_object, obj);
-+
-+ HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &status, &status_len)) {
-+ RETURN_FALSE;
-+ }
-+ STR_SET(obj->message->http.info.response.status, estrndup(status, status_len));
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getRequestMethod()
-+ Get the Request Method of the Message. */
-+PHP_METHOD(HttpMessage, getRequestMethod)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE);
-+ if (obj->message->http.info.request.method) {
-+ RETURN_STRING(obj->message->http.info.request.method, 1);
-+ } else {
-+ RETURN_EMPTY_STRING();
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setRequestMethod(string method)
-+ Set the Request Method of the HTTP Message. */
-+PHP_METHOD(HttpMessage, setRequestMethod)
-+{
-+ char *method;
-+ int method_len;
-+ getObject(http_message_object, obj);
-+
-+ HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len)) {
-+ RETURN_FALSE;
-+ }
-+ if (method_len < 1) {
-+ http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestMethod to an empty string");
-+ RETURN_FALSE;
-+ }
-+ if (!http_request_method_exists(1, 0, method)) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unknown request method: %s", method);
-+ RETURN_FALSE;
-+ }
-+
-+ STR_SET(obj->message->http.info.request.method, estrndup(method, method_len));
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getRequestUrl()
-+ Get the Request URL of the Message. */
-+PHP_METHOD(HttpMessage, getRequestUrl)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+ HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE);
-+ if (obj->message->http.info.request.url) {
-+ RETURN_STRING(obj->message->http.info.request.url, 1);
-+ } else {
-+ RETURN_EMPTY_STRING();
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setRequestUrl(string url)
-+ Set the Request URL of the HTTP Message. */
-+PHP_METHOD(HttpMessage, setRequestUrl)
-+{
-+ char *URI;
-+ int URIlen;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &URI, &URIlen)) {
-+ RETURN_FALSE;
-+ }
-+ HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE);
-+ if (URIlen < 1) {
-+ http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestUrl to an empty string");
-+ RETURN_FALSE;
-+ }
-+
-+ STR_SET(obj->message->http.info.request.url, estrndup(URI, URIlen));
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::getHttpVersion()
-+ Get the HTTP Protocol Version of the Message. */
-+PHP_METHOD(HttpMessage, getHttpVersion)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ char *version;
-+ getObject(http_message_object, obj);
-+
-+ spprintf(&version, 0, "%1.1F", obj->message->http.version);
-+ RETURN_STRING(version, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::setHttpVersion(string version)
-+ Set the HTTP Protocol version of the Message. */
-+PHP_METHOD(HttpMessage, setHttpVersion)
-+{
-+ zval *zv;
-+ char *version;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &zv)) {
-+ return;
-+ }
-+
-+ convert_to_double(zv);
-+ spprintf(&version, 0, "%1.1F", Z_DVAL_P(zv));
-+ if (strcmp(version, "1.0") && strcmp(version, "1.1")) {
-+ efree(version);
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid HTTP protocol version (1.0 or 1.1): %g", Z_DVAL_P(zv));
-+ RETURN_FALSE;
-+ }
-+ efree(version);
-+ obj->message->http.version = Z_DVAL_P(zv);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::guessContentType(string magic_file[, int magic_mode = MAGIC_MIME])
-+ Attempts to guess the content type of supplied payload through libmagic. */
-+PHP_METHOD(HttpMessage, guessContentType)
-+{
-+#ifdef HTTP_HAVE_MAGIC
-+ char *magic_file, *ct = NULL;
-+ int magic_file_len;
-+ long magic_mode = MAGIC_MIME;
-+
-+ RETVAL_FALSE;
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &magic_file, &magic_file_len, &magic_mode)) {
-+ getObject(http_message_object, obj);
-+ if ((ct = http_guess_content_type(magic_file, magic_mode, PHPSTR_VAL(&obj->message->body), PHPSTR_LEN(&obj->message->body), SEND_DATA))) {
-+ RETVAL_STRING(ct, 0);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+#else
-+ http_error(HE_THROW, HTTP_E_RUNTIME, "Cannot guess Content-Type; libmagic not available");
-+ RETURN_FALSE;
-+#endif
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpMessage::getParentMessage()
-+ Get parent Message. */
-+PHP_METHOD(HttpMessage, getParentMessage)
-+{
-+ SET_EH_THROW_HTTP();
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+
-+ if (obj->message->parent) {
-+ RETVAL_OBJVAL(obj->parent, 1);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "HttpMessage does not have a parent message");
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::send()
-+ Send the Message according to its type as Response or Request. */
-+PHP_METHOD(HttpMessage, send)
-+{
-+ getObject(http_message_object, obj);
-+
-+ NO_ARGS;
-+
-+ RETURN_SUCCESS(http_message_send(obj->message));
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::toString([bool include_parent = false])
-+ Get the string representation of the Message. */
-+PHP_METHOD(HttpMessage, toString)
-+{
-+ if (return_value_used) {
-+ char *string;
-+ size_t length;
-+ zend_bool include_parent = 0;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &include_parent)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (include_parent) {
-+ http_message_serialize(obj->message, &string, &length);
-+ } else {
-+ http_message_tostring(obj->message, &string, &length);
-+ }
-+ RETURN_STRINGL(string, length, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpRequest|HttpResponse HttpMessage::toMessageTypeObject(void)
-+ Creates an object regarding to the type of the message. Returns either an HttpRequest or HttpResponse object on success, or NULL on failure. */
-+PHP_METHOD(HttpMessage, toMessageTypeObject)
-+{
-+ SET_EH_THROW_HTTP();
-+
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_message_object, obj);
-+
-+ switch (obj->message->type) {
-+ case HTTP_MSG_REQUEST:
-+ {
-+#ifdef HTTP_HAVE_CURL
-+ int method;
-+ char *url;
-+ zval post, body, *array, *headers, *host = http_message_header(obj->message, "Host");
-+ php_url hurl, *purl = php_url_parse(STR_PTR(obj->message->http.info.request.url));
-+
-+ MAKE_STD_ZVAL(array);
-+ array_init(array);
-+
-+ memset(&hurl, 0, sizeof(php_url));
-+ if (host) {
-+ hurl.host = Z_STRVAL_P(host);
-+ zval_ptr_dtor(&host);
-+ }
-+ http_build_url(HTTP_URL_REPLACE, purl, &hurl, NULL, &url, NULL);
-+ php_url_free(purl);
-+ add_assoc_string(array, "url", url, 0);
-+
-+ if ( obj->message->http.info.request.method &&
-+ ((method = http_request_method_exists(1, 0, obj->message->http.info.request.method)) ||
-+ (method = http_request_method_register(obj->message->http.info.request.method, strlen(obj->message->http.info.request.method))))) {
-+ add_assoc_long(array, "method", method);
-+ }
-+
-+ if (10 == (int) (obj->message->http.version * 10)) {
-+ add_assoc_long(array, "protocol", CURL_HTTP_VERSION_1_0);
-+ }
-+
-+ MAKE_STD_ZVAL(headers);
-+ array_init(headers);
-+ array_copy(&obj->message->hdrs, Z_ARRVAL_P(headers));
-+ add_assoc_zval(array, "headers", headers);
-+
-+ object_init_ex(return_value, http_request_object_ce);
-+ zend_call_method_with_1_params(&return_value, http_request_object_ce, NULL, "setoptions", NULL, array);
-+ zval_ptr_dtor(&array);
-+
-+ if (PHPSTR_VAL(obj->message) && PHPSTR_LEN(obj->message)) {
-+ phpstr_fix(PHPSTR(obj->message));
-+ INIT_PZVAL(&body);
-+ ZVAL_STRINGL(&body, PHPSTR_VAL(obj->message), PHPSTR_LEN(obj->message), 0);
-+ if (method != HTTP_POST) {
-+ zend_call_method_with_1_params(&return_value, http_request_object_ce, NULL, "setbody", NULL, &body);
-+ } else {
-+ INIT_PZVAL(&post);
-+ array_init(&post);
-+
-+ zval_copy_ctor(&body);
-+ sapi_module.treat_data(PARSE_STRING, Z_STRVAL(body), &post TSRMLS_CC);
-+ zend_call_method_with_1_params(&return_value, http_request_object_ce, NULL, "setpostfields", NULL, &post);
-+ zval_dtor(&post);
-+ }
-+ }
-+#else
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot transform HttpMessage to HttpRequest (missing curl support)");
-+#endif
-+ break;
-+ }
-+
-+ case HTTP_MSG_RESPONSE:
-+ {
-+#ifndef WONKY
-+ HashPosition pos1, pos2;
-+ HashKey key = initHashKey(0);
-+ zval **header, **h, *body;
-+
-+ if (obj->message->http.info.response.code) {
-+ http_send_status(obj->message->http.info.response.code);
-+ }
-+
-+ object_init_ex(return_value, http_response_object_ce);
-+
-+ FOREACH_HASH_KEYVAL(pos1, &obj->message->hdrs, key, header) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ zval *zkey;
-+
-+ MAKE_STD_ZVAL(zkey);
-+ ZVAL_STRINGL(zkey, key.str, key.len - 1, 1);
-+
-+ switch (Z_TYPE_PP(header)) {
-+ case IS_ARRAY:
-+ case IS_OBJECT:
-+ FOREACH_HASH_VAL(pos2, HASH_OF(*header), h) {
-+ ZVAL_ADDREF(*h);
-+ zend_call_method_with_2_params(&return_value, http_response_object_ce, NULL, "setheader", NULL, zkey, *h);
-+ zval_ptr_dtor(h);
-+ }
-+ break;
-+
-+ default:
-+ ZVAL_ADDREF(*header);
-+ zend_call_method_with_2_params(&return_value, http_response_object_ce, NULL, "setheader", NULL, zkey, *header);
-+ zval_ptr_dtor(header);
-+ break;
-+ }
-+ zval_ptr_dtor(&zkey);
-+ }
-+ }
-+
-+ MAKE_STD_ZVAL(body);
-+ ZVAL_STRINGL(body, PHPSTR_VAL(obj->message), PHPSTR_LEN(obj->message), 1);
-+ zend_call_method_with_1_params(&return_value, http_response_object_ce, NULL, "setdata", NULL, body);
-+ zval_ptr_dtor(&body);
-+#else
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot transform HttpMessage to HttpResponse (need PHP 5.1+)");
-+#endif
-+ break;
-+ }
-+
-+ default:
-+ http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is neither of type HttpMessage::TYPE_REQUEST nor HttpMessage::TYPE_RESPONSE");
-+ break;
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpMessage::count()
-+ Implements Countable::count(). Returns the number of parent messages + 1. */
-+PHP_METHOD(HttpMessage, count)
-+{
-+ NO_ARGS {
-+ long i;
-+ getObject(http_message_object, obj);
-+
-+ http_message_count(i, obj->message);
-+ RETURN_LONG(i);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpMessage::serialize()
-+ Implements Serializable::serialize(). Returns the serialized representation of the HttpMessage. */
-+PHP_METHOD(HttpMessage, serialize)
-+{
-+ NO_ARGS {
-+ char *string;
-+ size_t length;
-+ getObject(http_message_object, obj);
-+
-+ http_message_serialize(obj->message, &string, &length);
-+ RETURN_STRINGL(string, length, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::unserialize(string serialized)
-+ Implements Serializable::unserialize(). Re-constructs the HttpMessage based upon the serialized string. */
-+PHP_METHOD(HttpMessage, unserialize)
-+{
-+ int length;
-+ char *serialized;
-+ getObject(http_message_object, obj);
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &length)) {
-+ http_message *msg;
-+
-+ http_message_dtor(obj->message);
-+ if ((msg = http_message_parse_ex(obj->message, serialized, (size_t) length))) {
-+ obj->message = msg;
-+ } else {
-+ http_message_init(obj->message);
-+ http_error(HE_ERROR, HTTP_E_RUNTIME, "Could not unserialize HttpMessage");
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpMessage::detach(void)
-+ Returns a clone of an HttpMessage object detached from any parent messages. */
-+PHP_METHOD(HttpMessage, detach)
-+{
-+ http_info info;
-+ http_message *msg;
-+ getObject(http_message_object, obj);
-+
-+ NO_ARGS;
-+
-+ info.type = obj->message->type;
-+ memcpy(&HTTP_INFO(&info), &HTTP_INFO(obj->message), sizeof(struct http_info));
-+
-+ msg = http_message_new();
-+ http_message_set_info(msg, &info);
-+
-+ zend_hash_copy(&msg->hdrs, &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ phpstr_append(&msg->body, PHPSTR_VAL(obj->message), PHPSTR_LEN(obj->message));
-+
-+ RETVAL_OBJVAL(http_message_object_new_ex(Z_OBJCE_P(getThis()), msg, NULL), 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::prepend(HttpMessage message[, bool top = true])
-+ Prepends message(s) to the HTTP message. Throws HttpInvalidParamException if the message is located within the same message chain. */
-+PHP_METHOD(HttpMessage, prepend)
-+{
-+ zval *prepend;
-+ zend_bool top = 1;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, http_message_object_ce, &top)) {
-+ http_message *msg[2];
-+ getObject(http_message_object, obj);
-+ getObjectEx(http_message_object, prepend_obj, prepend);
-+
-+ /* safety check */
-+ for (msg[0] = obj->message; msg[0]; msg[0] = msg[0]->parent) {
-+ for (msg[1] = prepend_obj->message; msg[1]; msg[1] = msg[1]->parent) {
-+ if (msg[0] == msg[1]) {
-+ http_error(HE_THROW, HTTP_E_INVALID_PARAM, "Cannot prepend a message located within the same message chain");
-+ return;
-+ }
-+ }
-+ }
-+
-+ http_message_object_prepend_ex(getThis(), prepend, top);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpMessage::reverse()
-+ Reorders the message chain in reverse order. Returns the most parent HttpMessage object. */
-+PHP_METHOD(HttpMessage, reverse)
-+{
-+ NO_ARGS {
-+ http_message_object_reverse(getThis(), return_value);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::rewind(void)
-+ Implements Iterator::rewind(). */
-+PHP_METHOD(HttpMessage, rewind)
-+{
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+
-+ if (obj->iterator) {
-+ zval_ptr_dtor(&obj->iterator);
-+ }
-+ ZVAL_ADDREF(getThis());
-+ obj->iterator = getThis();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpMessage::valid(void)
-+ Implements Iterator::valid(). */
-+PHP_METHOD(HttpMessage, valid)
-+{
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+
-+ RETURN_BOOL(obj->iterator != NULL);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpMessage::next(void)
-+ Implements Iterator::next(). */
-+PHP_METHOD(HttpMessage, next)
-+{
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+ if (obj->iterator) {
-+ getObjectEx(http_message_object, itr, obj->iterator);
-+
-+ if (itr && itr->parent.handle) {
-+ zval *old = obj->iterator;
-+ MAKE_STD_ZVAL(obj->iterator);
-+ ZVAL_OBJVAL(obj->iterator, itr->parent, 1);
-+ zval_ptr_dtor(&old);
-+ } else {
-+ zval_ptr_dtor(&obj->iterator);
-+ obj->iterator = NULL;
-+ }
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpMessage::key(void)
-+ Implements Iterator::key(). */
-+PHP_METHOD(HttpMessage, key)
-+{
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+
-+ RETURN_LONG(obj->iterator ? obj->iterator->value.obj.handle:0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpMessage::current(void)
-+ Implements Iterator::current(). */
-+PHP_METHOD(HttpMessage, current)
-+{
-+ NO_ARGS {
-+ getObject(http_message_object, obj);
-+
-+ if (obj->iterator) {
-+ RETURN_ZVAL(obj->iterator, 1, 0);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_persistent_handle_api.c
-@@ -0,0 +1,388 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_persistent_handle_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#include "php_http.h"
-+#include "php_http_api.h"
-+
-+#include "php_http_persistent_handle_api.h"
-+
-+#ifndef HTTP_DEBUG_PHANDLES
-+# define HTTP_DEBUG_PHANDLES 0
-+#endif
-+#if HTTP_DEBUG_PHANDLES
-+# undef inline
-+# define inline
-+#endif
-+
-+static HashTable http_persistent_handles_hash;
-+#ifdef ZTS
-+# define LOCK() tsrm_mutex_lock(http_persistent_handles_lock)
-+# define UNLOCK() tsrm_mutex_unlock(http_persistent_handles_lock)
-+static MUTEX_T http_persistent_handles_lock;
-+#else
-+# define LOCK()
-+# define UNLOCK()
-+#endif
-+
-+typedef struct _http_persistent_handle_list_t {
-+ HashTable free;
-+ ulong used;
-+} http_persistent_handle_list;
-+
-+typedef struct _http_persistent_handle_provider_t {
-+ http_persistent_handle_list list; /* "ident" => array(handles) entries */
-+ http_persistent_handle_ctor ctor;
-+ http_persistent_handle_dtor dtor;
-+ http_persistent_handle_copy copy;
-+} http_persistent_handle_provider;
-+
-+static inline http_persistent_handle_list *http_persistent_handle_list_init(http_persistent_handle_list *list)
-+{
-+ int free_list;
-+
-+ if ((free_list = !list)) {
-+ list = pemalloc(sizeof(http_persistent_handle_list), 1);
-+ }
-+
-+ list->used = 0;
-+
-+ if (SUCCESS != zend_hash_init(&list->free, 0, NULL, NULL, 1)) {
-+ if (free_list) {
-+ pefree(list, 1);
-+ }
-+ list = NULL;
-+ }
-+
-+ return list;
-+}
-+
-+static inline void http_persistent_handle_list_dtor(http_persistent_handle_list *list, http_persistent_handle_dtor dtor)
-+{
-+ HashPosition pos;
-+ void **handle;
-+
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "LSTDTOR: %p\n", list);
-+#endif
-+ FOREACH_HASH_VAL(pos, &list->free, handle) {
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "DESTROY: %p\n", *handle);
-+#endif
-+
-+ dtor(*handle);
-+ }
-+ zend_hash_destroy(&list->free);
-+}
-+
-+static inline void http_persistent_handle_list_free(http_persistent_handle_list **list, http_persistent_handle_dtor dtor)
-+{
-+ http_persistent_handle_list_dtor(*list, dtor);
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "LSTFREE: %p\n", *list);
-+#endif
-+ pefree(*list, 1);
-+ *list = NULL;
-+}
-+
-+static inline http_persistent_handle_list *http_persistent_handle_list_find(http_persistent_handle_provider *provider TSRMLS_DC)
-+{
-+ http_persistent_handle_list **list, *new_list;
-+
-+ if (SUCCESS == zend_hash_quick_find(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) {
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "LSTFIND: %p\n", *list);
-+#endif
-+ return *list;
-+ }
-+
-+ if ((new_list = http_persistent_handle_list_init(NULL))) {
-+ if (SUCCESS == zend_hash_quick_add(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &new_list, sizeof(http_persistent_handle_list *), (void *) &list)) {
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "LSTFIND: %p (new)\n", *list);
-+#endif
-+ return *list;
-+ }
-+ http_persistent_handle_list_free(&new_list, provider->dtor);
-+ }
-+
-+ return NULL;
-+}
-+
-+static inline STATUS http_persistent_handle_do_acquire(http_persistent_handle_provider *provider, void **handle TSRMLS_DC)
-+{
-+ ulong index;
-+ void **handle_ptr;
-+ http_persistent_handle_list *list;
-+
-+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
-+ zend_hash_internal_pointer_end(&list->free);
-+ if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&list->free, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(&list->free, (void *) &handle_ptr)) {
-+ *handle = *handle_ptr;
-+ zend_hash_index_del(&list->free, index);
-+ } else {
-+ *handle = provider->ctor();
-+ }
-+
-+ if (*handle) {
-+ ++provider->list.used;
-+ ++list->used;
-+ return SUCCESS;
-+ }
-+ } else {
-+ *handle = NULL;
-+ }
-+
-+ return FAILURE;
-+}
-+
-+static inline STATUS http_persistent_handle_do_release(http_persistent_handle_provider *provider, void **handle TSRMLS_DC)
-+{
-+ http_persistent_handle_list *list;
-+
-+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
-+ if (provider->list.used >= HTTP_G->persistent.handles.limit) {
-+ provider->dtor(*handle);
-+ } else {
-+ if (SUCCESS != zend_hash_next_index_insert(&list->free, (void *) handle, sizeof(void *), NULL)) {
-+ return FAILURE;
-+ }
-+ }
-+
-+ *handle = NULL;
-+ --provider->list.used;
-+ --list->used;
-+ return SUCCESS;
-+ }
-+
-+ return FAILURE;
-+}
-+
-+static inline STATUS http_persistent_handle_do_accrete(http_persistent_handle_provider *provider, void *old_handle, void **new_handle TSRMLS_DC)
-+{
-+ http_persistent_handle_list *list;
-+
-+ if (provider->copy && (*new_handle = provider->copy(old_handle))) {
-+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
-+ ++list->used;
-+ }
-+ ++provider->list.used;
-+ return SUCCESS;
-+ }
-+ return FAILURE;
-+}
-+
-+static void http_persistent_handles_hash_dtor(void *p)
-+{
-+ http_persistent_handle_provider *provider = (http_persistent_handle_provider *) p;
-+ http_persistent_handle_list **list, *list_tmp;
-+ HashPosition pos;
-+
-+ FOREACH_HASH_VAL(pos, &provider->list.free, list) {
-+ /* fix shutdown crash in PHP4 */
-+ list_tmp = *list;
-+ http_persistent_handle_list_free(&list_tmp, provider->dtor);
-+ }
-+
-+ zend_hash_destroy(&provider->list.free);
-+}
-+
-+PHP_MINIT_FUNCTION(http_persistent_handle)
-+{
-+ zend_hash_init(&http_persistent_handles_hash, 0, NULL, http_persistent_handles_hash_dtor, 1);
-+#ifdef ZTS
-+ http_persistent_handles_lock = tsrm_mutex_alloc();
-+#endif
-+ return SUCCESS;
-+}
-+
-+PHP_MSHUTDOWN_FUNCTION(http_persistent_handle)
-+{
-+ zend_hash_destroy(&http_persistent_handles_hash);
-+#ifdef ZTS
-+ tsrm_mutex_free(http_persistent_handles_lock);
-+#endif
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor, http_persistent_handle_copy copy)
-+{
-+ STATUS status = FAILURE;
-+ http_persistent_handle_provider provider;
-+
-+ LOCK();
-+ if (http_persistent_handle_list_init(&provider.list)) {
-+ provider.ctor = ctor;
-+ provider.dtor = dtor;
-+ provider.copy = copy;
-+
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "PROVIDE: %s\n", name_str);
-+#endif
-+
-+ if (SUCCESS == zend_hash_add(&http_persistent_handles_hash, HTTP_ZAPI_CONST_CAST(char *) name_str, name_len+1, (void *) &provider, sizeof(http_persistent_handle_provider), NULL)) {
-+ status = SUCCESS;
-+ }
-+ }
-+ UNLOCK();
-+
-+ return status;
-+}
-+
-+PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, size_t name_len, void **handle TSRMLS_DC)
-+{
-+ STATUS status = FAILURE;
-+ http_persistent_handle_provider *provider;
-+
-+ *handle = NULL;
-+ LOCK();
-+ if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, HTTP_ZAPI_CONST_CAST(char *) name_str, name_len+1, (void *) &provider)) {
-+ status = http_persistent_handle_do_acquire(provider, handle TSRMLS_CC);
-+ }
-+ UNLOCK();
-+
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "ACQUIRE: %p (%s)\n", *handle, name_str);
-+#endif
-+
-+ return status;
-+}
-+
-+PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, size_t name_len, void **handle TSRMLS_DC)
-+{
-+ STATUS status = FAILURE;
-+ http_persistent_handle_provider *provider;
-+#if HTTP_DEBUG_PHANDLES
-+ void *handle_tmp = *handle;
-+#endif
-+
-+ LOCK();
-+ if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, HTTP_ZAPI_CONST_CAST(char *) name_str, name_len+1, (void *) &provider)) {
-+ status = http_persistent_handle_do_release(provider, handle TSRMLS_CC);
-+ }
-+ UNLOCK();
-+
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "RELEASE: %p (%s)\n", handle_tmp, name_str);
-+#endif
-+
-+ return status;
-+}
-+
-+PHP_HTTP_API STATUS _http_persistent_handle_accrete_ex(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC)
-+{
-+ STATUS status = FAILURE;
-+ http_persistent_handle_provider *provider;
-+
-+ *new_handle = NULL;
-+ LOCK();
-+ if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, HTTP_ZAPI_CONST_CAST(char *) name_str, name_len+1, (void *) &provider)) {
-+ status = http_persistent_handle_do_accrete(provider, old_handle, new_handle TSRMLS_CC);
-+ }
-+ UNLOCK();
-+
-+#if HTTP_DEBUG_PHANDLES
-+ fprintf(stderr, "ACCRETE: %p > %p (%s)\n", old_handle, *new_handle, name_str);
-+#endif
-+
-+ return status;
-+}
-+
-+PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC)
-+{
-+ http_persistent_handle_provider *provider;
-+ http_persistent_handle_list *list, **listp;
-+ HashPosition pos1, pos2;
-+
-+ LOCK();
-+ if (name_str && name_len) {
-+ if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, HTTP_ZAPI_CONST_CAST(char *) name_str, name_len+1, (void *) &provider)) {
-+ if (current_ident_only) {
-+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
-+ http_persistent_handle_list_dtor(list, provider->dtor);
-+ http_persistent_handle_list_init(list);
-+ }
-+ } else {
-+ FOREACH_HASH_VAL(pos1, &provider->list.free, listp) {
-+ http_persistent_handle_list_dtor(*listp, provider->dtor);
-+ http_persistent_handle_list_init(*listp);
-+ }
-+ }
-+ }
-+ } else {
-+ FOREACH_HASH_VAL(pos1, &http_persistent_handles_hash, provider) {
-+ if (current_ident_only) {
-+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
-+ http_persistent_handle_list_dtor(list, provider->dtor);
-+ http_persistent_handle_list_init(list);
-+ }
-+ } else {
-+ FOREACH_HASH_VAL(pos2, &provider->list.free, listp) {
-+ http_persistent_handle_list_dtor(*listp, provider->dtor);
-+ http_persistent_handle_list_init(*listp);
-+ }
-+ }
-+ }
-+ }
-+ UNLOCK();
-+}
-+
-+PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht TSRMLS_DC)
-+{
-+ zval *zentry[2];
-+ HashPosition pos1, pos2;
-+ HashKey key1 = initHashKey(0), key2 = initHashKey(0);
-+ http_persistent_handle_provider *provider;
-+ http_persistent_handle_list **list;
-+
-+ LOCK();
-+ if (zend_hash_num_elements(&http_persistent_handles_hash)) {
-+ if (!ht) {
-+ ALLOC_HASHTABLE(ht);
-+ zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
-+ }
-+
-+ FOREACH_HASH_KEYVAL(pos1, &http_persistent_handles_hash, key1, provider) {
-+ MAKE_STD_ZVAL(zentry[0]);
-+ array_init(zentry[0]);
-+
-+ FOREACH_HASH_KEYVAL(pos2, &provider->list.free, key2, list) {
-+ MAKE_STD_ZVAL(zentry[1]);
-+ array_init(zentry[1]);
-+ add_assoc_long_ex(zentry[1], ZEND_STRS("used"), (*list)->used);
-+ add_assoc_long_ex(zentry[1], ZEND_STRS("free"), zend_hash_num_elements(&(*list)->free));
-+
-+ /* use zend_hash_* not add_assoc_* (which is zend_symtable_*) as we want a string even for numbers */
-+ zend_hash_add(Z_ARRVAL_P(zentry[0]), key2.str, key2.len, &zentry[1], sizeof(zval *), NULL);
-+ }
-+
-+ zend_hash_add(ht, key1.str, key1.len, &zentry[0], sizeof(zval *), NULL);
-+ }
-+ } else if (ht) {
-+ ht = NULL;
-+ }
-+ UNLOCK();
-+
-+ return ht;
-+}
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_querystring_api.c
-@@ -0,0 +1,220 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_querystring_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#include "php_http.h"
-+
-+#include "php_variables.h"
-+#ifdef HTTP_HAVE_ICONV
-+# undef PHP_ATOM_INC
-+# include "ext/iconv/php_iconv.h"
-+# include "ext/standard/url.h"
-+#endif
-+
-+#include "php_http_api.h"
-+#include "php_http_url_api.h"
-+#include "php_http_querystring_api.h"
-+
-+#ifdef ZEND_ENGINE_2
-+#define THIS_CE http_querystring_object_ce
-+extern zend_class_entry *http_querystring_object_ce;
-+#endif
-+
-+
-+#define http_querystring_modify_array_ex(q, t, k, kl, i, pe) _http_querystring_modify_array_ex((q), (t), (k), (kl), (i), (pe) TSRMLS_CC)
-+static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC);
-+#define http_querystring_modify_array(q, p) _http_querystring_modify_array((q), (p) TSRMLS_CC)
-+static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC);
-+
-+
-+#ifdef HTTP_HAVE_ICONV
-+PHP_HTTP_API int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
-+{
-+ HashPosition pos;
-+ zval **entry = NULL;
-+ char *xlate_str = NULL, *xkey;
-+ size_t xlate_len = 0, xlen;
-+ HashKey key = initHashKey(0);
-+
-+ FOREACH_KEYVAL(pos, param, key, entry) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
-+ http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe);
-+ return FAILURE;
-+ }
-+ }
-+
-+ if (Z_TYPE_PP(entry) == IS_STRING) {
-+ if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ efree(xkey);
-+ }
-+ http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
-+ return FAILURE;
-+ }
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
-+ } else {
-+ add_index_stringl(array, key.num, xlate_str, xlate_len, 0);
-+ }
-+ } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
-+ zval *subarray;
-+
-+ MAKE_STD_ZVAL(subarray);
-+ array_init(subarray);
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ add_assoc_zval_ex(array, xkey, xlen+1, subarray);
-+ } else {
-+ add_index_zval(array, key.num, subarray);
-+ }
-+ if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ efree(xkey);
-+ }
-+ return FAILURE;
-+ }
-+ }
-+
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ efree(xkey);
-+ }
-+ }
-+ return SUCCESS;
-+}
-+#endif /* HAVE_ICONV */
-+
-+PHP_HTTP_API void _http_querystring_update(zval *qarray, zval *qstring TSRMLS_DC)
-+{
-+ char *s = NULL;
-+ size_t l = 0;
-+
-+ if (Z_TYPE_P(qarray) != IS_ARRAY) {
-+ convert_to_array(qarray);
-+ }
-+ if (SUCCESS == http_urlencode_hash_ex(Z_ARRVAL_P(qarray), 0, NULL, 0, &s, &l)) {
-+ zval_dtor(qstring);
-+ ZVAL_STRINGL(qstring, s, l, 0);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to update query string");
-+ }
-+}
-+
-+PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
-+{
-+ if (Z_TYPE_P(params) == IS_ARRAY) {
-+ return http_querystring_modify_array(qarray, params);
-+ } else if (Z_TYPE_P(params) == IS_OBJECT) {
-+#ifdef ZEND_ENGINE_2
-+ if (instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) {
-+ return http_querystring_modify_array(qarray, zend_read_property(THIS_CE, params, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC));
-+ } else {
-+#endif
-+ return http_querystring_modify_array(qarray, params);
-+#ifdef ZEND_ENGINE_2
-+ }
-+#endif
-+ } else {
-+ int rv;
-+ zval array;
-+ zval *qstring = http_zsep(IS_STRING, params);
-+
-+ INIT_PZVAL(&array);
-+ array_init(&array);
-+
-+ sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(qstring)), &array TSRMLS_CC);
-+ zval_ptr_dtor(&qstring);
-+
-+ rv = http_querystring_modify_array(qarray, &array);
-+ zval_dtor(&array);
-+ return rv;
-+ }
-+}
-+
-+static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
-+{
-+ int rv = 0;
-+ HashKey key = initHashKey(0);
-+ HashPosition pos;
-+ zval **params_entry = NULL;
-+
-+ FOREACH_HASH_KEYVAL(pos, HASH_OF(params), key, params_entry) {
-+ /* only public properties */
-+ if ((key.type != HASH_KEY_IS_STRING || *key.str) && http_querystring_modify_array_ex(qarray, key.type, key.str, key.len, key.num, *params_entry)) {
-+ rv = 1;
-+ }
-+ }
-+
-+ return rv;
-+}
-+
-+static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
-+{
-+ zval **qarray_entry;
-+
-+ /* ensure array type */
-+ if (Z_TYPE_P(qarray) != IS_ARRAY) {
-+ convert_to_array(qarray);
-+ }
-+
-+ /* delete */
-+ if (Z_TYPE_P(params_entry) == IS_NULL) {
-+ if (key_type == HASH_KEY_IS_STRING) {
-+ return (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), key, keylen));
-+ } else {
-+ return (SUCCESS == zend_hash_index_del(Z_ARRVAL_P(qarray), idx));
-+ }
-+ }
-+
-+ /* update */
-+ if ( ((key_type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key, keylen, (void *) &qarray_entry))) ||
-+ ((key_type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), idx, (void *) &qarray_entry)))) {
-+ zval equal;
-+
-+ /* recursive */
-+ if (Z_TYPE_P(params_entry) == IS_ARRAY || Z_TYPE_P(params_entry) == IS_OBJECT) {
-+ return http_querystring_modify(*qarray_entry, params_entry);
-+ }
-+ /* equal */
-+ if ((SUCCESS == is_equal_function(&equal, *qarray_entry, params_entry TSRMLS_CC)) && Z_BVAL(equal)) {
-+ return 0;
-+ }
-+ }
-+
-+ /* add */
-+ if (Z_TYPE_P(params_entry) == IS_OBJECT) {
-+ zval *new_array;
-+
-+ MAKE_STD_ZVAL(new_array);
-+ array_init(new_array);
-+ http_querystring_modify_array(new_array, params_entry);
-+ params_entry = new_array;
-+ } else {
-+ ZVAL_ADDREF(params_entry);
-+ }
-+ if (key_type == HASH_KEY_IS_STRING) {
-+ add_assoc_zval_ex(qarray, key, keylen, params_entry);
-+ } else {
-+ add_index_zval(qarray, idx, params_entry);
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/http_querystring_object.c
-@@ -0,0 +1,633 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_querystring_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#include "php_http.h"
-+
-+#ifdef ZEND_ENGINE_2
-+
-+#include "php_variables.h"
-+#include "zend_interfaces.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_querystring_api.h"
-+#include "php_http_querystring_object.h"
-+#include "php_http_exception_object.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpQueryString, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpQueryString, method, 0)
-+#define HTTP_QUERYSTRING_ME(method, visibility) PHP_ME(HttpQueryString, method, HTTP_ARGS(HttpQueryString, method), visibility)
-+#define HTTP_QUERYSTRING_GME(method, visibility) PHP_ME(HttpQueryString, method, HTTP_ARGS(HttpQueryString, __getter), visibility)
-+
-+HTTP_BEGIN_ARGS(__construct, 0)
-+ HTTP_ARG_VAL(global, 0)
-+ HTTP_ARG_VAL(params, 0)
-+HTTP_END_ARGS;
-+
-+#ifndef WONKY
-+HTTP_BEGIN_ARGS(singleton, 0)
-+ HTTP_ARG_VAL(global, 0)
-+HTTP_END_ARGS;
-+#endif
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(global, 0)
-+ HTTP_ARG_VAL(params, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(toArray);
-+HTTP_EMPTY_ARGS(toString);
-+
-+HTTP_BEGIN_ARGS(get, 0)
-+ HTTP_ARG_VAL(name, 0)
-+ HTTP_ARG_VAL(type, 0)
-+ HTTP_ARG_VAL(defval, 0)
-+ HTTP_ARG_VAL(delete, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(set, 1)
-+ HTTP_ARG_VAL(params, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(mod, 0)
-+ HTTP_ARG_VAL(params, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(__getter, 1)
-+ HTTP_ARG_VAL(name, 0)
-+ HTTP_ARG_VAL(defval, 0)
-+ HTTP_ARG_VAL(delete, 0)
-+HTTP_END_ARGS;
-+
-+#ifdef HTTP_HAVE_ICONV
-+HTTP_BEGIN_ARGS(xlate, 2)
-+ HTTP_ARG_VAL(from_encoding, 0)
-+ HTTP_ARG_VAL(to_encoding, 0)
-+HTTP_END_ARGS;
-+#endif
-+
-+HTTP_EMPTY_ARGS(serialize);
-+HTTP_BEGIN_ARGS(unserialize, 1)
-+ HTTP_ARG_VAL(serialized, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(offsetGet, 1)
-+ HTTP_ARG_VAL(offset, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(offsetSet, 2)
-+ HTTP_ARG_VAL(offset, 0)
-+ HTTP_ARG_VAL(value, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(offsetExists, 1)
-+ HTTP_ARG_VAL(offset, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(offsetUnset, 1)
-+ HTTP_ARG_VAL(offset, 0)
-+HTTP_END_ARGS;
-+
-+
-+#define THIS_CE http_querystring_object_ce
-+zend_class_entry *http_querystring_object_ce;
-+zend_function_entry http_querystring_object_fe[] = {
-+ HTTP_QUERYSTRING_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
-+
-+ HTTP_QUERYSTRING_ME(toArray, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(toString, ZEND_ACC_PUBLIC)
-+ ZEND_MALIAS(HttpQueryString, __toString, toString, HTTP_ARGS(HttpQueryString, toString), ZEND_ACC_PUBLIC)
-+
-+ HTTP_QUERYSTRING_ME(get, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(set, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(mod, ZEND_ACC_PUBLIC)
-+
-+ HTTP_QUERYSTRING_GME(getBool, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_GME(getInt, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_GME(getFloat, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_GME(getString, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_GME(getArray, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_GME(getObject, ZEND_ACC_PUBLIC)
-+
-+ HTTP_QUERYSTRING_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+#ifndef WONKY
-+ HTTP_QUERYSTRING_ME(singleton, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+#endif
-+#ifdef HTTP_HAVE_ICONV
-+ HTTP_QUERYSTRING_ME(xlate, ZEND_ACC_PUBLIC)
-+#endif
-+
-+ /* Implements Serializable */
-+ HTTP_QUERYSTRING_ME(serialize, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(unserialize, ZEND_ACC_PUBLIC)
-+
-+ /* Implements ArrayAccess */
-+ HTTP_QUERYSTRING_ME(offsetGet, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(offsetSet, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(offsetExists, ZEND_ACC_PUBLIC)
-+ HTTP_QUERYSTRING_ME(offsetUnset, ZEND_ACC_PUBLIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_querystring_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_querystring_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpQueryString, http_querystring_object, NULL, 0);
-+
-+#ifndef WONKY
-+ zend_class_implements(http_querystring_object_ce TSRMLS_CC, 2, zend_ce_serializable, zend_ce_arrayaccess);
-+#endif
-+
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("instance")-1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("queryArray")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("queryString")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+
-+#ifndef WONKY
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_BOOL")-1, HTTP_QUERYSTRING_TYPE_BOOL TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_INT")-1, HTTP_QUERYSTRING_TYPE_INT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_FLOAT")-1, HTTP_QUERYSTRING_TYPE_FLOAT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_STRING")-1, HTTP_QUERYSTRING_TYPE_STRING TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_ARRAY")-1, HTTP_QUERYSTRING_TYPE_ARRAY TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("TYPE_OBJECT")-1, HTTP_QUERYSTRING_TYPE_OBJECT TSRMLS_CC);
-+#endif
-+
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_BOOL", HTTP_QUERYSTRING_TYPE_BOOL);
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_INT", HTTP_QUERYSTRING_TYPE_INT);
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_FLOAT", HTTP_QUERYSTRING_TYPE_FLOAT);
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_STRING", HTTP_QUERYSTRING_TYPE_STRING);
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_ARRAY", HTTP_QUERYSTRING_TYPE_ARRAY);
-+ HTTP_LONG_CONSTANT("HTTP_QUERYSTRING_TYPE_OBJECT", HTTP_QUERYSTRING_TYPE_OBJECT);
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_querystring_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_querystring_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_querystring_object_new_ex(zend_class_entry *ce, void *nothing, http_querystring_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_querystring_object *o;
-+
-+ o = ecalloc(1, sizeof(http_querystring_object));
-+ o->zo.ce = ce;
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_querystring_object, o);
-+ ov.handlers = &http_querystring_object_handlers;
-+
-+ return ov;
-+}
-+
-+void _http_querystring_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_querystring_object *o = (http_querystring_object *) object;
-+
-+ freeObject(o);
-+}
-+
-+/* {{{ querystring helpers */
-+#define http_querystring_instantiate(t, g, p, u) _http_querystring_instantiate((t), (g), (p), (u) TSRMLS_CC)
-+static inline zval *_http_querystring_instantiate(zval *this_ptr, zend_bool global, zval *params, zend_bool defer_update TSRMLS_DC)
-+{
-+ zval *qarray = NULL, *qstring = NULL, **_SERVER = NULL, **_GET = NULL, **QUERY_STRING = NULL;;
-+
-+ if (!this_ptr) {
-+ MAKE_STD_ZVAL(this_ptr);
-+ Z_TYPE_P(this_ptr) = IS_OBJECT;
-+ this_ptr->value.obj = http_querystring_object_new(http_querystring_object_ce);
-+ }
-+ if (global) {
-+#ifdef ZEND_ENGINE_2
-+ zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
-+#endif
-+ if ( (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &_SERVER)) &&
-+ (Z_TYPE_PP(_SERVER) == IS_ARRAY) &&
-+ (SUCCESS == zend_hash_find(Z_ARRVAL_PP(_SERVER), "QUERY_STRING", sizeof("QUERY_STRING"), (void *) &QUERY_STRING))) {
-+
-+ qstring = *QUERY_STRING;
-+#ifdef ZEND_ENGINE_2
-+ zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC);
-+#endif
-+ if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET)) && (Z_TYPE_PP(_GET) == IS_ARRAY)) {
-+ qarray = *_GET;
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET array");
-+ }
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Could not acquire reference to QUERY_STRING");
-+ }
-+
-+ if (qarray && qstring) {
-+ if (Z_TYPE_P(qstring) != IS_STRING) {
-+ convert_to_string(qstring);
-+ }
-+
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, qarray TSRMLS_CC);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, qstring TSRMLS_CC);
-+#ifdef Z_SET_ISREF
-+ Z_SET_ISREF_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC));
-+ Z_SET_ISREF_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+#else
-+ zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC)->is_ref = 1;
-+ zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC)->is_ref = 1;
-+#endif
-+
-+ if (params) {
-+ http_querystring_modify(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC), params);
-+ }
-+ if (!defer_update) {
-+ http_querystring_update(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC), zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+ }
-+ }
-+ } else {
-+ MAKE_STD_ZVAL(qarray);
-+ array_init(qarray);
-+
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, qarray TSRMLS_CC);
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryString")-1, "", 0 TSRMLS_CC);
-+
-+ if (params && http_querystring_modify(qarray, params) && !defer_update) {
-+ http_querystring_update(qarray, zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+ }
-+
-+ zval_ptr_dtor(&qarray);
-+ }
-+
-+ return this_ptr;
-+}
-+
-+#define http_querystring_get(o, t, n, l, def, del, r) _http_querystring_get((o), (t), (n), (l), (def), (del), (r) TSRMLS_CC)
-+static inline void _http_querystring_get(zval *this_ptr, int type, char *name, uint name_len, zval *defval, zend_bool del, zval *return_value TSRMLS_DC)
-+{
-+ zval **arrval, *qarray = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
-+
-+ if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
-+ if (type) {
-+ zval *value = http_zsep(type, *arrval);
-+ RETVAL_ZVAL(value, 1, 1);
-+ } else {
-+ RETVAL_ZVAL(*arrval, 1, 0);
-+ }
-+
-+ if (del && (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), name, name_len + 1))) {
-+ http_querystring_update(qarray, zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+ }
-+ } else if(defval) {
-+ RETURN_ZVAL(defval, 1, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto final void HttpQueryString::__construct([bool global = true[, mixed add])
-+ Creates a new HttpQueryString object instance. Operates on and modifies $_GET and $_SERVER['QUERY_STRING'] if global is TRUE. */
-+PHP_METHOD(HttpQueryString, __construct)
-+{
-+ zend_bool global = 1;
-+ zval *params = NULL;
-+
-+ SET_EH_THROW_HTTP();
-+ if (!sapi_module.treat_data) {
-+ http_error(HE_ERROR, HTTP_E_QUERYSTRING, "The SAPI does not have a treat_data function registered");
-+ } else if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bz", &global, ¶ms)) {
-+ http_querystring_instantiate(getThis(), global, params, 0);
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpQueryString HttpQueryString::factory([bool global = TRUE[, mixed params[, string class_name = "HttpQueryString"])
-+ Creates a new HttpQueryString object instance. */
-+PHP_METHOD(HttpQueryString, factory)
-+{
-+ zend_bool global = 1;
-+ zval *params = NULL;
-+ char *cn = NULL;
-+ int cl = 0;
-+ zend_object_value ov;
-+
-+ SET_EH_THROW_HTTP();
-+ if (!sapi_module.treat_data) {
-+ http_error(HE_ERROR, HTTP_E_QUERYSTRING, "The SAPI does not have a treat_data function registered");
-+ } else if ( SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bzs", &global, ¶ms, &cn, &cl) &&
-+ SUCCESS == http_object_new(&ov, cn, cl, _http_querystring_object_new_ex, http_querystring_object_ce, NULL, NULL)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ http_querystring_instantiate(return_value, global, params, 0);
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpQueryString::toString()
-+ Returns the string representation. */
-+PHP_METHOD(HttpQueryString, toString)
-+{
-+ NO_ARGS;
-+ RETURN_PROP(queryString);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpQueryString::toArray()
-+ Returns the array representation. */
-+PHP_METHOD(HttpQueryString, toArray)
-+{
-+ NO_ARGS;
-+ RETURN_PROP(queryArray);
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed HttpQueryString::get([string key[, mixed type = 0[, mixed defval = NULL[, bool delete = false]]]])
-+ Get (part of) the query string. The type parameter is either one of the HttpQueryString::TYPE_* constants or a type abbreviation like "b" for bool, "i" for int, "f" for float, "s" for string, "a" for array and "o" for a stdClass object. */
-+PHP_METHOD(HttpQueryString, get)
-+{
-+ char *name = NULL;
-+ int name_len = 0;
-+ long type = 0;
-+ zend_bool del = 0;
-+ zval *ztype = NULL, *defval = NULL;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szzb", &name, &name_len, &ztype, &defval, &del)) {
-+ if (name && name_len) {
-+ if (ztype) {
-+ if (Z_TYPE_P(ztype) == IS_LONG) {
-+ type = Z_LVAL_P(ztype);
-+ } else if(Z_TYPE_P(ztype) == IS_STRING) {
-+ switch (Z_STRVAL_P(ztype)[0]) {
-+ case 'B':
-+ case 'b': type = HTTP_QUERYSTRING_TYPE_BOOL; break;
-+ case 'I':
-+ case 'i': type = HTTP_QUERYSTRING_TYPE_INT; break;
-+ case 'F':
-+ case 'f': type = HTTP_QUERYSTRING_TYPE_FLOAT; break;
-+ case 'S':
-+ case 's': type = HTTP_QUERYSTRING_TYPE_STRING; break;
-+ case 'A':
-+ case 'a': type = HTTP_QUERYSTRING_TYPE_ARRAY; break;
-+ case 'O':
-+ case 'o': type = HTTP_QUERYSTRING_TYPE_OBJECT; break;
-+ }
-+ }
-+ }
-+ http_querystring_get(getThis(), type, name, name_len, defval, del, return_value);
-+ } else {
-+ RETURN_PROP(queryString);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpQueryString::set(mixed params)
-+ Set query string entry/entries. NULL values will unset the variable. */
-+PHP_METHOD(HttpQueryString, set)
-+{
-+ zval *params;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms)) {
-+ zval *qarray = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
-+ if (http_querystring_modify(qarray, params)) {
-+ http_querystring_update(qarray, zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+ }
-+ }
-+
-+ if (return_value_used) {
-+ RETURN_PROP(queryString);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpQueryString HttpQueryString::mod(mixed params)
-+ Copies the query string object and sets provided params at the clone. */
-+PHP_METHOD(HttpQueryString, mod)
-+{
-+ zval *zobj, *qarr, *qstr, *params;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms)) {
-+ zobj = http_querystring_instantiate(NULL, 0, zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC), 1);
-+ qarr = zend_read_property(THIS_CE, zobj, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
-+ qstr = zend_read_property(THIS_CE, zobj, ZEND_STRS("queryString")-1, 0 TSRMLS_CC);
-+
-+ http_querystring_modify(qarr, params);
-+ http_querystring_update(qarr, qstr);
-+
-+ RETURN_ZVAL(zobj, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+#ifndef WONKY
-+/* {{{ proto static HttpQueryString HttpQueryString::singleton([bool global = true])
-+ Get a single instance (differentiates between the global setting). */
-+PHP_METHOD(HttpQueryString, singleton)
-+{
-+ zend_bool global = 1;
-+ zval *instance = *zend_std_get_static_property(THIS_CE, ZEND_STRS("instance")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &global)) {
-+ zval **zobj_ptr = NULL, *zobj = NULL;
-+
-+ if (Z_TYPE_P(instance) == IS_ARRAY) {
-+ if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(instance), global, (void *) &zobj_ptr)) {
-+ RETVAL_ZVAL(*zobj_ptr, 1, 0);
-+ } else {
-+ zobj = http_querystring_instantiate(NULL, global, NULL, (zend_bool) !global);
-+ add_index_zval(instance, global, zobj);
-+ RETVAL_OBJECT(zobj, 1);
-+ }
-+ } else {
-+ MAKE_STD_ZVAL(instance);
-+ array_init(instance);
-+
-+ zobj = http_querystring_instantiate(NULL, global, NULL, (zend_bool) !global);
-+ add_index_zval(instance, global, zobj);
-+ RETVAL_OBJECT(zobj, 1);
-+
-+ zend_update_static_property(THIS_CE, ZEND_STRS("instance")-1, instance TSRMLS_CC);
-+ zval_ptr_dtor(&instance);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+#endif
-+
-+/* {{{ Getters by type */
-+#define HTTP_QUERYSTRING_GETTER(method, TYPE) \
-+PHP_METHOD(HttpQueryString, method) \
-+{ \
-+ char *name; \
-+ int name_len; \
-+ zval *defval = NULL; \
-+ zend_bool del = 0; \
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &name, &name_len, &defval, &del)) { \
-+ http_querystring_get(getThis(), TYPE, name, name_len, defval, del, return_value); \
-+ } \
-+}
-+HTTP_QUERYSTRING_GETTER(getBool, IS_BOOL);
-+HTTP_QUERYSTRING_GETTER(getInt, IS_LONG);
-+HTTP_QUERYSTRING_GETTER(getFloat, IS_DOUBLE);
-+HTTP_QUERYSTRING_GETTER(getString, IS_STRING);
-+HTTP_QUERYSTRING_GETTER(getArray, IS_ARRAY);
-+HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
-+/* }}} */
-+
-+#ifdef HTTP_HAVE_ICONV
-+/* {{{ proto bool HttpQueryString::xlate(string ie, string oe)
-+ Converts the query string from the source encoding ie to the target encoding oe. WARNING: Don't use any character set that can contain NUL bytes like UTF-16. */
-+PHP_METHOD(HttpQueryString, xlate)
-+{
-+ char *ie, *oe;
-+ int ie_len, oe_len;
-+ zval xa, *qa, *qs;
-+ STATUS rs;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ qa = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
-+ qs = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC);
-+ INIT_PZVAL(&xa);
-+ array_init(&xa);
-+
-+ if (SUCCESS == (rs = http_querystring_xlate(&xa, qa, ie, oe))) {
-+ zend_hash_clean(Z_ARRVAL_P(qa));
-+ zend_hash_copy(Z_ARRVAL_P(qa), Z_ARRVAL(xa), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ http_querystring_update(qa, qs);
-+ }
-+ zval_dtor(&xa);
-+
-+ RETURN_SUCCESS(rs);
-+}
-+/* }}} */
-+#endif /* HAVE_ICONV */
-+
-+/* {{{ proto string HttpQueryString::serialize()
-+ Implements Serializable::serialize(). */
-+PHP_METHOD(HttpQueryString, serialize)
-+{
-+ NO_ARGS;
-+ RETURN_PROP(queryString);
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpQueryString::unserialize(string serialized)
-+ Implements Serializable::unserialize(). */
-+PHP_METHOD(HttpQueryString, unserialize)
-+{
-+ zval *serialized;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
-+ if (Z_TYPE_P(serialized) == IS_STRING) {
-+ http_querystring_instantiate(getThis(), 0, serialized, 0);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Expected a string as parameter");
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed HttpQueryString::offsetGet(string offset)
-+ Implements ArrayAccess::offsetGet(). */
-+PHP_METHOD(HttpQueryString, offsetGet)
-+{
-+ char *offset_str;
-+ int offset_len;
-+ zval **value;
-+
-+ if ( (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) &&
-+ (SUCCESS == zend_hash_find(Z_ARRVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC)), offset_str, offset_len + 1, (void *) &value))) {
-+ RETVAL_ZVAL(*value, 1, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpQueryString::offsetSet(string offset, mixed value)
-+ Implements ArrayAccess::offsetGet(). */
-+PHP_METHOD(HttpQueryString, offsetSet)
-+{
-+ char *offset_str;
-+ int offset_len;
-+ zval *value;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) {
-+ zval *qarr = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC), *qstr = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC);
-+
-+ ZVAL_ADDREF(value);
-+ add_assoc_zval_ex(qarr, offset_str, offset_len + 1, value);
-+ http_querystring_update(qarr, qstr);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpQueryString::offsetExists(string offset)
-+ Implements ArrayAccess::offsetExists(). */
-+PHP_METHOD(HttpQueryString, offsetExists)
-+{
-+ char *offset_str;
-+ int offset_len;
-+ zval **value;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
-+ RETURN_BOOL((SUCCESS == zend_hash_find(Z_ARRVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC)), offset_str, offset_len + 1, (void *) &value)) && (Z_TYPE_PP(value) != IS_NULL));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpQueryString::offsetUnset(string offset)
-+ Implements ArrayAccess::offsetUnset(). */
-+PHP_METHOD(HttpQueryString, offsetUnset)
-+{
-+ char *offset_str;
-+ int offset_len;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
-+ zval *qarr = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
-+
-+ if (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarr), offset_str, offset_len + 1)) {
-+ http_querystring_update(qarr, zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryString")-1, 0 TSRMLS_CC));
-+ }
-+ }
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_request_api.c
-@@ -0,0 +1,1326 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_api.c 310775 2011-05-05 06:02:50Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#ifdef HTTP_HAVE_CURL
-+
-+#include "php_http_api.h"
-+#include "php_http_persistent_handle_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_url_api.h"
-+
-+#ifdef ZEND_ENGINE_2
-+# include "php_http_request_object.h"
-+#endif
-+
-+#include "php_http_request_int.h"
-+
-+/* {{{ cruft for thread safe SSL crypto locks */
-+#ifdef HTTP_NEED_OPENSSL_TSL
-+static MUTEX_T *http_openssl_tsl = NULL;
-+
-+static void http_openssl_thread_lock(int mode, int n, const char * file, int line)
-+{
-+ if (mode & CRYPTO_LOCK) {
-+ tsrm_mutex_lock(http_openssl_tsl[n]);
-+ } else {
-+ tsrm_mutex_unlock(http_openssl_tsl[n]);
-+ }
-+}
-+
-+static ulong http_openssl_thread_id(void)
-+{
-+ return (ulong) tsrm_thread_id();
-+}
-+#endif
-+#ifdef HTTP_NEED_GNUTLS_TSL
-+static int http_gnutls_mutex_create(void **m)
-+{
-+ if (*((MUTEX_T *) m) = tsrm_mutex_alloc()) {
-+ return SUCCESS;
-+ } else {
-+ return FAILURE;
-+ }
-+}
-+
-+static int http_gnutls_mutex_destroy(void **m)
-+{
-+ tsrm_mutex_free(*((MUTEX_T *) m));
-+ return SUCCESS;
-+}
-+
-+static int http_gnutls_mutex_lock(void **m)
-+{
-+ return tsrm_mutex_lock(*((MUTEX_T *) m));
-+}
-+
-+static int http_gnutls_mutex_unlock(void **m)
-+{
-+ return tsrm_mutex_unlock(*((MUTEX_T *) m));
-+}
-+
-+static struct gcry_thread_cbs http_gnutls_tsl = {
-+ GCRY_THREAD_OPTION_USER,
-+ NULL,
-+ http_gnutls_mutex_create,
-+ http_gnutls_mutex_destroy,
-+ http_gnutls_mutex_lock,
-+ http_gnutls_mutex_unlock
-+};
-+#endif
-+/* }}} */
-+
-+/* safe curl wrappers */
-+#define init_curl_storage(ch) \
-+ {\
-+ http_request_storage *st = pecalloc(1, sizeof(http_request_storage), 1); \
-+ curl_easy_setopt(ch, CURLOPT_PRIVATE, st); \
-+ curl_easy_setopt(ch, CURLOPT_ERRORBUFFER, st->errorbuffer); \
-+ }
-+
-+static void *safe_curl_init(void)
-+{
-+ CURL *ch;
-+
-+ if ((ch = curl_easy_init())) {
-+ init_curl_storage(ch);
-+ return ch;
-+ }
-+ return NULL;
-+}
-+static void *safe_curl_copy(void *p)
-+{
-+ CURL *ch;
-+
-+ if ((ch = curl_easy_duphandle(p))) {
-+ init_curl_storage(ch);
-+ return ch;
-+ }
-+ return NULL;
-+}
-+static void safe_curl_dtor(void *p) {
-+ http_request_storage *st = http_request_storage_get(p);
-+
-+ curl_easy_cleanup(p);
-+
-+ if (st) {
-+ if (st->url) {
-+ pefree(st->url, 1);
-+ }
-+ if (st->cookiestore) {
-+ pefree(st->cookiestore, 1);
-+ }
-+ pefree(st, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ MINIT */
-+PHP_MINIT_FUNCTION(http_request)
-+{
-+#ifdef HTTP_NEED_OPENSSL_TSL
-+ /* mod_ssl, libpq or ext/curl might already have set thread lock callbacks */
-+ if (!CRYPTO_get_id_callback()) {
-+ int i, c = CRYPTO_num_locks();
-+
-+ http_openssl_tsl = malloc(c * sizeof(MUTEX_T));
-+
-+ for (i = 0; i < c; ++i) {
-+ http_openssl_tsl[i] = tsrm_mutex_alloc();
-+ }
-+
-+ CRYPTO_set_id_callback(http_openssl_thread_id);
-+ CRYPTO_set_locking_callback(http_openssl_thread_lock);
-+ }
-+#endif
-+#ifdef HTTP_NEED_GNUTLS_TSL
-+ gcry_control(GCRYCTL_SET_THREAD_CBS, &http_gnutls_tsl);
-+#endif
-+
-+ if (CURLE_OK != curl_global_init(CURL_GLOBAL_ALL)) {
-+ return FAILURE;
-+ }
-+
-+ if (SUCCESS != http_persistent_handle_provide("http_request", safe_curl_init, safe_curl_dtor, safe_curl_copy)) {
-+ return FAILURE;
-+ }
-+
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC);
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST);
-+#if HTTP_CURL_VERSION(7,19,3)
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST_IE", CURLAUTH_DIGEST_IE);
-+#endif
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_NTLM", CURLAUTH_NTLM);
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_GSSNEG", CURLAUTH_GSSNEGOTIATE);
-+ HTTP_LONG_CONSTANT("HTTP_AUTH_ANY", CURLAUTH_ANY);
-+
-+ HTTP_LONG_CONSTANT("HTTP_VERSION_NONE", CURL_HTTP_VERSION_NONE); /* to be removed */
-+ HTTP_LONG_CONSTANT("HTTP_VERSION_1_0", CURL_HTTP_VERSION_1_0);
-+ HTTP_LONG_CONSTANT("HTTP_VERSION_1_1", CURL_HTTP_VERSION_1_1);
-+ HTTP_LONG_CONSTANT("HTTP_VERSION_ANY", CURL_HTTP_VERSION_NONE);
-+
-+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_TLSv1", CURL_SSLVERSION_TLSv1);
-+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_SSLv2", CURL_SSLVERSION_SSLv2);
-+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_SSLv3", CURL_SSLVERSION_SSLv3);
-+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_ANY", CURL_SSLVERSION_DEFAULT);
-+
-+ HTTP_LONG_CONSTANT("HTTP_IPRESOLVE_V4", CURL_IPRESOLVE_V4);
-+ HTTP_LONG_CONSTANT("HTTP_IPRESOLVE_V6", CURL_IPRESOLVE_V6);
-+ HTTP_LONG_CONSTANT("HTTP_IPRESOLVE_ANY", CURL_IPRESOLVE_WHATEVER);
-+
-+#if HTTP_CURL_VERSION(7,15,2)
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_SOCKS4", CURLPROXY_SOCKS4);
-+#endif
-+#if HTTP_CURL_VERSION(7,18,0)
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_SOCKS4A", CURLPROXY_SOCKS4A);
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_SOCKS5_HOSTNAME", CURLPROXY_SOCKS5_HOSTNAME);
-+#endif
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_SOCKS5", CURLPROXY_SOCKS5);
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_HTTP", CURLPROXY_HTTP);
-+#if HTTP_CURL_VERSION(7,19,4)
-+ HTTP_LONG_CONSTANT("HTTP_PROXY_HTTP_1_0", CURLPROXY_HTTP_1_0);
-+#endif
-+
-+#if HTTP_CURL_VERSION(7,19,1)
-+ HTTP_LONG_CONSTANT("HTTP_POSTREDIR_301", CURL_REDIR_POST_301);
-+ HTTP_LONG_CONSTANT("HTTP_POSTREDIR_302", CURL_REDIR_POST_302);
-+ HTTP_LONG_CONSTANT("HTTP_POSTREDIR_ALL", CURL_REDIR_POST_ALL);
-+#endif
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ MSHUTDOWN */
-+PHP_MSHUTDOWN_FUNCTION(http_request)
-+{
-+ curl_global_cleanup();
-+#ifdef HTTP_NEED_OPENSSL_TSL
-+ if (http_openssl_tsl) {
-+ int i, c = CRYPTO_num_locks();
-+
-+ CRYPTO_set_id_callback(NULL);
-+ CRYPTO_set_locking_callback(NULL);
-+
-+ for (i = 0; i < c; ++i) {
-+ tsrm_mutex_free(http_openssl_tsl[i]);
-+ }
-+
-+ free(http_openssl_tsl);
-+ http_openssl_tsl = NULL;
-+ }
-+#endif
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ forward declarations */
-+#define http_request_option(r, o, k, t) _http_request_option_ex((r), (o), (k), sizeof(k), (t) TSRMLS_CC)
-+#define http_request_option_ex(r, o, k, l, t) _http_request_option_ex((r), (o), (k), (l), (t) TSRMLS_CC)
-+static inline zval *_http_request_option_ex(http_request *request, HashTable *options, char *key, size_t keylen, int type TSRMLS_DC);
-+#define http_request_option_cache(r, k, z) _http_request_option_cache_ex((r), (k), sizeof(k), 0, (z) TSRMLS_CC)
-+#define http_request_option_cache_ex(r, k, kl, h, z) _http_request_option_cache_ex((r), (k), (kl), (h), (z) TSRMLS_CC)
-+static inline zval *_http_request_option_cache_ex(http_request *r, char *key, size_t keylen, ulong h, zval *opt TSRMLS_DC);
-+
-+#define http_request_cookies_enabled(r) _http_request_cookies_enabled((r))
-+static inline int _http_request_cookies_enabled(http_request *r);
-+
-+static size_t http_curl_read_callback(void *, size_t, size_t, void *);
-+static int http_curl_progress_callback(void *, double, double, double, double);
-+static int http_curl_raw_callback(CURL *, curl_infotype, char *, size_t, void *);
-+static int http_curl_dummy_callback(char *data, size_t n, size_t l, void *s) { return n*l; }
-+static curlioerr http_curl_ioctl_callback(CURL *, curliocmd, void *);
-+/* }}} */
-+
-+/* {{{ CURL *http_curl_init(http_request *) */
-+PHP_HTTP_API CURL * _http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC)
-+{
-+ if (ch || (SUCCESS == http_persistent_handle_acquire("http_request", &ch))) {
-+#if defined(ZTS)
-+ curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
-+#endif
-+ curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
-+ curl_easy_setopt(ch, CURLOPT_FILETIME, 1L);
-+ curl_easy_setopt(ch, CURLOPT_AUTOREFERER, 1L);
-+ curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
-+ curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, NULL);
-+ curl_easy_setopt(ch, CURLOPT_DEBUGFUNCTION, http_curl_raw_callback);
-+ curl_easy_setopt(ch, CURLOPT_READFUNCTION, http_curl_read_callback);
-+ curl_easy_setopt(ch, CURLOPT_IOCTLFUNCTION, http_curl_ioctl_callback);
-+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, http_curl_dummy_callback);
-+
-+ /* set context */
-+ if (request) {
-+ curl_easy_setopt(ch, CURLOPT_DEBUGDATA, request);
-+
-+ /* attach curl handle */
-+ request->ch = ch;
-+ /* set defaults (also in http_request_reset()) */
-+ http_request_defaults(request);
-+ }
-+ }
-+
-+ return ch;
-+}
-+/* }}} */
-+
-+/* {{{ CURL *http_curl_copy(CURL *) */
-+PHP_HTTP_API CURL *_http_curl_copy(CURL *ch TSRMLS_DC)
-+{
-+ CURL *copy;
-+
-+ if (SUCCESS == http_persistent_handle_accrete("http_request", ch, ©)) {
-+ return copy;
-+ }
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ void http_curl_free(CURL **) */
-+PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC)
-+{
-+ if (*ch) {
-+ curl_easy_setopt(*ch, CURLOPT_NOPROGRESS, 1L);
-+ curl_easy_setopt(*ch, CURLOPT_PROGRESSFUNCTION, NULL);
-+ curl_easy_setopt(*ch, CURLOPT_VERBOSE, 0L);
-+ curl_easy_setopt(*ch, CURLOPT_DEBUGFUNCTION, NULL);
-+
-+ http_persistent_handle_release("http_request", ch);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ http_request *http_request_init(http_request *) */
-+PHP_HTTP_API http_request *_http_request_init_ex(http_request *request, CURL *ch, http_request_method meth, const char *url ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ http_request *r;
-+
-+ if (request) {
-+ r = request;
-+ } else {
-+ r = emalloc_rel(sizeof(http_request));
-+ }
-+ memset(r, 0, sizeof(http_request));
-+
-+ r->ch = ch;
-+ r->url = (url) ? http_absolute_url(url) : NULL;
-+ r->meth = (meth > 0) ? meth : HTTP_GET;
-+
-+ phpstr_init(&r->conv.request);
-+ phpstr_init_ex(&r->conv.response, HTTP_CURLBUF_SIZE, 0);
-+ phpstr_init(&r->_cache.cookies);
-+ zend_hash_init(&r->_cache.options, 0, NULL, ZVAL_PTR_DTOR, 0);
-+
-+ TSRMLS_SET_CTX(r->tsrm_ls);
-+
-+ return r;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_dtor(http_request *) */
-+PHP_HTTP_API void _http_request_dtor(http_request *request)
-+{
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ http_request_reset(request);
-+ http_curl_free(&request->ch);
-+
-+ phpstr_dtor(&request->_cache.cookies);
-+ zend_hash_destroy(&request->_cache.options);
-+ if (request->_cache.headers) {
-+ curl_slist_free_all(request->_cache.headers);
-+ request->_cache.headers = NULL;
-+ }
-+ if (request->_progress_callback) {
-+ zval_ptr_dtor(&request->_progress_callback);
-+ request->_progress_callback = NULL;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_free(http_request **) */
-+PHP_HTTP_API void _http_request_free(http_request **request)
-+{
-+ if (*request) {
-+ TSRMLS_FETCH_FROM_CTX((*request)->tsrm_ls);
-+ http_request_body_free(&(*request)->body);
-+ http_request_dtor(*request);
-+ efree(*request);
-+ *request = NULL;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_reset(http_request *) */
-+PHP_HTTP_API void _http_request_reset(http_request *request)
-+{
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+ STR_SET(request->url, NULL);
-+ request->conv.last_type = 0;
-+ phpstr_dtor(&request->conv.request);
-+ phpstr_dtor(&request->conv.response);
-+ http_request_body_dtor(request->body);
-+ http_request_defaults(request);
-+
-+ if (request->ch) {
-+ http_request_storage *st = http_request_storage_get(request->ch);
-+
-+ if (st) {
-+ if (st->url) {
-+ pefree(st->url, 1);
-+ st->url = NULL;
-+ }
-+ if (st->cookiestore) {
-+ pefree(st->cookiestore, 1);
-+ st->cookiestore = NULL;
-+ }
-+ st->errorbuffer[0] = '\0';
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_enable_cookies(http_request *) */
-+PHP_HTTP_API STATUS _http_request_enable_cookies(http_request *request)
-+{
-+ int initialized = 1;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
-+ if (initialized && (http_request_cookies_enabled(request) || (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "")))) {
-+ return SUCCESS;
-+ }
-+ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not enable cookies for this session");
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_reset_cookies(http_request *, int) */
-+PHP_HTTP_API STATUS _http_request_reset_cookies(http_request *request, int session_only)
-+{
-+ int initialized = 1;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
-+ if (initialized) {
-+ if (!http_request_cookies_enabled(request)) {
-+ if (SUCCESS != http_request_enable_cookies(request)) {
-+ return FAILURE;
-+ }
-+ }
-+ if (session_only) {
-+#if HTTP_CURL_VERSION(7,15,4)
-+ if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS")) {
-+ return SUCCESS;
-+ }
-+#else
-+ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)");
-+#endif
-+ } else {
-+#if HTTP_CURL_VERSION(7,14,1)
-+ if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL")) {
-+ return SUCCESS;
-+ }
-+#else
-+ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset cookies (need libcurl >= v7.14.1)");
-+#endif
-+ }
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+PHP_HTTP_API STATUS _http_request_flush_cookies(http_request *request)
-+{
-+ int initialized = 1;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
-+ if (initialized) {
-+ if (!http_request_cookies_enabled(request)) {
-+ return FAILURE;
-+ }
-+#if HTTP_CURL_VERSION(7,17,1)
-+ if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "FLUSH")) {
-+ return SUCCESS;
-+ }
-+#else
-+ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not flush cookies (need libcurl >= v7.17.1)");
-+#endif
-+ }
-+ return FAILURE;
-+}
-+
-+/* {{{ void http_request_defaults(http_request *) */
-+PHP_HTTP_API void _http_request_defaults(http_request *request)
-+{
-+ if (request->ch) {
-+ HTTP_CURL_OPT(CURLOPT_PROGRESSFUNCTION, NULL);
-+ HTTP_CURL_OPT(CURLOPT_URL, NULL);
-+ HTTP_CURL_OPT(CURLOPT_NOPROGRESS, 1L);
-+#if HTTP_CURL_VERSION(7,19,4)
-+ HTTP_CURL_OPT(CURLOPT_NOPROXY, NULL);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_PROXY, NULL);
-+ HTTP_CURL_OPT(CURLOPT_PROXYPORT, 0L);
-+ HTTP_CURL_OPT(CURLOPT_PROXYTYPE, 0L);
-+ /* libcurl < 7.19.6 does not clear auth info with USERPWD set to NULL */
-+#if HTTP_CURL_VERSION(7,19,1)
-+ HTTP_CURL_OPT(CURLOPT_PROXYUSERNAME, NULL);
-+ HTTP_CURL_OPT(CURLOPT_PROXYPASSWORD, NULL);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_PROXYAUTH, 0L);
-+ HTTP_CURL_OPT(CURLOPT_HTTPPROXYTUNNEL, 0L);
-+ HTTP_CURL_OPT(CURLOPT_DNS_CACHE_TIMEOUT, 60L);
-+ HTTP_CURL_OPT(CURLOPT_IPRESOLVE, 0);
-+ HTTP_CURL_OPT(CURLOPT_LOW_SPEED_LIMIT, 0L);
-+ HTTP_CURL_OPT(CURLOPT_LOW_SPEED_TIME, 0L);
-+#if HTTP_CURL_VERSION(7,15,5)
-+ /* LFS weirdance
-+ HTTP_CURL_OPT(CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) 0);
-+ HTTP_CURL_OPT(CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) 0);
-+ */
-+#endif
-+ /* crashes
-+ HTTP_CURL_OPT(CURLOPT_MAXCONNECTS, 5L); */
-+ HTTP_CURL_OPT(CURLOPT_FRESH_CONNECT, 0L);
-+ HTTP_CURL_OPT(CURLOPT_FORBID_REUSE, 0L);
-+ HTTP_CURL_OPT(CURLOPT_INTERFACE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_PORT, 0L);
-+#if HTTP_CURL_VERSION(7,19,0)
-+ HTTP_CURL_OPT(CURLOPT_ADDRESS_SCOPE, 0L);
-+#endif
-+#if HTTP_CURL_VERSION(7,15,2)
-+ HTTP_CURL_OPT(CURLOPT_LOCALPORT, 0L);
-+ HTTP_CURL_OPT(CURLOPT_LOCALPORTRANGE, 0L);
-+#endif
-+ /* libcurl < 7.19.6 does not clear auth info with USERPWD set to NULL */
-+#if HTTP_CURL_VERSION(7,19,1)
-+ HTTP_CURL_OPT(CURLOPT_USERNAME, NULL);
-+ HTTP_CURL_OPT(CURLOPT_PASSWORD, NULL);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_HTTPAUTH, 0L);
-+ HTTP_CURL_OPT(CURLOPT_ENCODING, NULL);
-+#if HTTP_CURL_VERSION(7,16,2)
-+ /* we do this ourself anyway */
-+ HTTP_CURL_OPT(CURLOPT_HTTP_CONTENT_DECODING, 0L);
-+ HTTP_CURL_OPT(CURLOPT_HTTP_TRANSFER_DECODING, 0L);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_FOLLOWLOCATION, 0L);
-+#if HTTP_CURL_VERSION(7,19,1)
-+ HTTP_CURL_OPT(CURLOPT_POSTREDIR, 0L);
-+#elif HTTP_CURL_VERSION(7,17,1)
-+ HTTP_CURL_OPT(CURLOPT_POST301, 0L);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_UNRESTRICTED_AUTH, 0L);
-+ HTTP_CURL_OPT(CURLOPT_REFERER, NULL);
-+ HTTP_CURL_OPT(CURLOPT_USERAGENT, "PECL::HTTP/" PHP_HTTP_VERSION " (PHP/" PHP_VERSION ")");
-+ HTTP_CURL_OPT(CURLOPT_HTTPHEADER, NULL);
-+ HTTP_CURL_OPT(CURLOPT_COOKIE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_COOKIESESSION, 0L);
-+ /* these options would enable curl's cookie engine by default which we don't want
-+ HTTP_CURL_OPT(CURLOPT_COOKIEFILE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_COOKIEJAR, NULL); */
-+#if HTTP_CURL_VERSION(7,14,1)
-+ HTTP_CURL_OPT(CURLOPT_COOKIELIST, NULL);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_RANGE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_RESUME_FROM, 0L);
-+ HTTP_CURL_OPT(CURLOPT_MAXFILESIZE, 0L);
-+ HTTP_CURL_OPT(CURLOPT_TIMECONDITION, 0L);
-+ HTTP_CURL_OPT(CURLOPT_TIMEVALUE, 0L);
-+ HTTP_CURL_OPT(CURLOPT_TIMEOUT, 0L);
-+ HTTP_CURL_OPT(CURLOPT_CONNECTTIMEOUT, 3);
-+ HTTP_CURL_OPT(CURLOPT_SSLCERT, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLCERTTYPE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLCERTPASSWD, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLKEY, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLKEYTYPE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLKEYPASSWD, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLENGINE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_SSLVERSION, 0L);
-+ HTTP_CURL_OPT(CURLOPT_SSL_VERIFYPEER, 0L);
-+ HTTP_CURL_OPT(CURLOPT_SSL_VERIFYHOST, 0L);
-+ HTTP_CURL_OPT(CURLOPT_SSL_CIPHER_LIST, NULL);
-+#if HTTP_CURL_VERSION(7,19,0)
-+ HTTP_CURL_OPT(CURLOPT_ISSUERCERT, NULL);
-+ #if defined(HTTP_HAVE_OPENSSL)
-+ HTTP_CURL_OPT(CURLOPT_CRLFILE, NULL);
-+ #endif
-+#endif
-+#if HTTP_CURL_VERSION(7,19,1) && defined(HTTP_HAVE_OPENSSL)
-+ HTTP_CURL_OPT(CURLOPT_CERTINFO, NULL);
-+#endif
-+#ifdef HTTP_CURL_CAINFO
-+ HTTP_CURL_OPT(CURLOPT_CAINFO, HTTP_CURL_CAINFO);
-+#else
-+ HTTP_CURL_OPT(CURLOPT_CAINFO, NULL);
-+#endif
-+ HTTP_CURL_OPT(CURLOPT_CAPATH, NULL);
-+ HTTP_CURL_OPT(CURLOPT_RANDOM_FILE, NULL);
-+ HTTP_CURL_OPT(CURLOPT_EGDSOCKET, NULL);
-+ HTTP_CURL_OPT(CURLOPT_POSTFIELDS, NULL);
-+ HTTP_CURL_OPT(CURLOPT_POSTFIELDSIZE, 0L);
-+ HTTP_CURL_OPT(CURLOPT_HTTPPOST, NULL);
-+ HTTP_CURL_OPT(CURLOPT_IOCTLDATA, NULL);
-+ HTTP_CURL_OPT(CURLOPT_READDATA, NULL);
-+ HTTP_CURL_OPT(CURLOPT_INFILESIZE, 0L);
-+ HTTP_CURL_OPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE);
-+ HTTP_CURL_OPT(CURLOPT_CUSTOMREQUEST, NULL);
-+ HTTP_CURL_OPT(CURLOPT_NOBODY, 0L);
-+ HTTP_CURL_OPT(CURLOPT_POST, 0L);
-+ HTTP_CURL_OPT(CURLOPT_UPLOAD, 0L);
-+ HTTP_CURL_OPT(CURLOPT_HTTPGET, 1L);
-+ }
-+}
-+/* }}} */
-+
-+PHP_HTTP_API void _http_request_set_progress_callback(http_request *request, zval *cb)
-+{
-+ if (request->_progress_callback) {
-+ zval_ptr_dtor(&request->_progress_callback);
-+ }
-+ if ((request->_progress_callback = cb)) {
-+ ZVAL_ADDREF(cb);
-+ HTTP_CURL_OPT(CURLOPT_NOPROGRESS, 0);
-+ HTTP_CURL_OPT(CURLOPT_PROGRESSDATA, request);
-+ HTTP_CURL_OPT(CURLOPT_PROGRESSFUNCTION, http_curl_progress_callback);
-+ } else {
-+ HTTP_CURL_OPT(CURLOPT_NOPROGRESS, 1);
-+ HTTP_CURL_OPT(CURLOPT_PROGRESSDATA, NULL);
-+ HTTP_CURL_OPT(CURLOPT_PROGRESSFUNCTION, NULL);
-+ }
-+}
-+
-+/* {{{ STATUS http_request_prepare(http_request *, HashTable *) */
-+PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *options)
-+{
-+ zval *zoption;
-+ zend_bool range_req = 0;
-+ http_request_storage *storage;
-+
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ HTTP_CHECK_CURL_INIT(request->ch, http_curl_init(request), return FAILURE);
-+
-+ if (!request->url) {
-+ return FAILURE;
-+ }
-+ if (!(storage = http_request_storage_get(request->ch))) {
-+ return FAILURE;
-+ }
-+ storage->errorbuffer[0] = '\0';
-+ /* set options */
-+ if (storage->url) {
-+ pefree(storage->url, 1);
-+ }
-+ storage->url = pestrdup(request->url, 1);
-+ HTTP_CURL_OPT(CURLOPT_URL, storage->url);
-+
-+ /* progress callback */
-+ if ((zoption = http_request_option(request, options, "onprogress", -1))) {
-+ http_request_set_progress_callback(request, zoption);
-+ }
-+
-+ /* proxy */
-+ if ((zoption = http_request_option(request, options, "proxyhost", IS_STRING))) {
-+ HTTP_CURL_OPT(CURLOPT_PROXY, Z_STRVAL_P(zoption));
-+ /* type */
-+ if ((zoption = http_request_option(request, options, "proxytype", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_PROXYTYPE, Z_LVAL_P(zoption));
-+ }
-+ /* port */
-+ if ((zoption = http_request_option(request, options, "proxyport", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_PROXYPORT, Z_LVAL_P(zoption));
-+ }
-+ /* user:pass */
-+ if ((zoption = http_request_option(request, options, "proxyauth", IS_STRING)) && Z_STRLEN_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_PROXYUSERPWD, Z_STRVAL_P(zoption));
-+ }
-+ /* auth method */
-+ if ((zoption = http_request_option(request, options, "proxyauthtype", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_PROXYAUTH, Z_LVAL_P(zoption));
-+ }
-+ /* tunnel */
-+ if ((zoption = http_request_option(request, options, "proxytunnel", IS_BOOL)) && Z_BVAL_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_HTTPPROXYTUNNEL, 1L);
-+ }
-+ }
-+#if HTTP_CURL_VERSION(7,19,4)
-+ if ((zoption = http_request_option(request, options, "noproxy", IS_STRING))) {
-+ HTTP_CURL_OPT(CURLOPT_NOPROXY, Z_STRVAL_P(zoption));
-+ }
-+#endif
-+
-+ /* dns */
-+ if ((zoption = http_request_option(request, options, "dns_cache_timeout", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_DNS_CACHE_TIMEOUT, Z_LVAL_P(zoption));
-+ }
-+ if ((zoption = http_request_option(request, options, "ipresolve", IS_LONG)) && Z_LVAL_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_IPRESOLVE, Z_LVAL_P(zoption));
-+ }
-+
-+ /* limits */
-+ if ((zoption = http_request_option(request, options, "low_speed_limit", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_LOW_SPEED_LIMIT, Z_LVAL_P(zoption));
-+ }
-+ if ((zoption = http_request_option(request, options, "low_speed_time", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_LOW_SPEED_TIME, Z_LVAL_P(zoption));
-+ }
-+#if HTTP_CURL_VERSION(7,15,5)
-+ /* LSF weirdance
-+ if ((zoption = http_request_option(request, options, "max_send_speed", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) Z_LVAL_P(zoption));
-+ }
-+ if ((zoption = http_request_option(request, options, "max_recv_speed", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) Z_LVAL_P(zoption));
-+ }
-+ */
-+#endif
-+ /* crashes
-+ if ((zoption = http_request_option(request, options, "maxconnects", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_MAXCONNECTS, Z_LVAL_P(zoption));
-+ } */
-+ if ((zoption = http_request_option(request, options, "fresh_connect", IS_BOOL)) && Z_BVAL_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_FRESH_CONNECT, 1L);
-+ }
-+ if ((zoption = http_request_option(request, options, "forbid_reuse", IS_BOOL)) && Z_BVAL_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_FORBID_REUSE, 1L);
-+ }
-+
-+ /* outgoing interface */
-+ if ((zoption = http_request_option(request, options, "interface", IS_STRING))) {
-+ HTTP_CURL_OPT(CURLOPT_INTERFACE, Z_STRVAL_P(zoption));
-+
-+#if HTTP_CURL_VERSION(7,15,2)
-+ if ((zoption = http_request_option(request, options, "portrange", IS_ARRAY))) {
-+ zval **prs, **pre;
-+
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(zoption));
-+ if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &prs)) {
-+ zend_hash_move_forward(Z_ARRVAL_P(zoption));
-+ if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &pre)) {
-+ zval *prs_cpy = http_zsep(IS_LONG, *prs);
-+ zval *pre_cpy = http_zsep(IS_LONG, *pre);
-+
-+ if (Z_LVAL_P(prs_cpy) && Z_LVAL_P(pre_cpy)) {
-+ HTTP_CURL_OPT(CURLOPT_LOCALPORT, MIN(Z_LVAL_P(prs_cpy), Z_LVAL_P(pre_cpy)));
-+ HTTP_CURL_OPT(CURLOPT_LOCALPORTRANGE, labs(Z_LVAL_P(prs_cpy)-Z_LVAL_P(pre_cpy))+1L);
-+ }
-+ zval_ptr_dtor(&prs_cpy);
-+ zval_ptr_dtor(&pre_cpy);
-+ }
-+ }
-+ }
-+#endif
-+ }
-+
-+ /* another port */
-+ if ((zoption = http_request_option(request, options, "port", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_PORT, Z_LVAL_P(zoption));
-+ }
-+
-+ /* RFC4007 zone_id */
-+#if HTTP_CURL_VERSION(7,19,0)
-+ if ((zoption = http_request_option(request, options, "address_scope", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_ADDRESS_SCOPE, Z_LVAL_P(zoption));
-+ }
-+#endif
-+
-+ /* auth */
-+ if ((zoption = http_request_option(request, options, "httpauth", IS_STRING)) && Z_STRLEN_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_USERPWD, Z_STRVAL_P(zoption));
-+ }
-+ if ((zoption = http_request_option(request, options, "httpauthtype", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_HTTPAUTH, Z_LVAL_P(zoption));
-+ }
-+
-+ /* redirects, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "redirect", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_FOLLOWLOCATION, Z_LVAL_P(zoption) ? 1L : 0L);
-+ HTTP_CURL_OPT(CURLOPT_MAXREDIRS, Z_LVAL_P(zoption));
-+ if ((zoption = http_request_option(request, options, "unrestrictedauth", IS_BOOL))) {
-+ HTTP_CURL_OPT(CURLOPT_UNRESTRICTED_AUTH, Z_LVAL_P(zoption));
-+ }
-+#if HTTP_CURL_VERSION(7,17,1)
-+ if ((zoption = http_request_option(request, options, "postredir", IS_BOOL))) {
-+# if HTTP_CURL_VERSION(7,19,1)
-+ HTTP_CURL_OPT(CURLOPT_POSTREDIR, Z_BVAL_P(zoption) ? 1L : 0L);
-+# else
-+ HTTP_CURL_OPT(CURLOPT_POST301, Z_BVAL_P(zoption) ? 1L : 0L);
-+# endif
-+ }
-+#endif
-+ }
-+
-+ /* retries, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "retrycount", IS_LONG))) {
-+ request->_retry.count = Z_LVAL_P(zoption);
-+ if ((zoption = http_request_option(request, options, "retrydelay", IS_DOUBLE))) {
-+ request->_retry.delay = Z_DVAL_P(zoption);
-+ } else {
-+ request->_retry.delay = 0;
-+ }
-+ } else {
-+ request->_retry.count = 0;
-+ }
-+
-+ /* referer */
-+ if ((zoption = http_request_option(request, options, "referer", IS_STRING)) && Z_STRLEN_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_REFERER, Z_STRVAL_P(zoption));
-+ }
-+
-+ /* useragent, default "PECL::HTTP/version (PHP/version)" */
-+ if ((zoption = http_request_option(request, options, "useragent", IS_STRING))) {
-+ /* allow to send no user agent, not even default one */
-+ if (Z_STRLEN_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_USERAGENT, Z_STRVAL_P(zoption));
-+ } else {
-+ HTTP_CURL_OPT(CURLOPT_USERAGENT, NULL);
-+ }
-+ }
-+
-+ /* resume */
-+ if ((zoption = http_request_option(request, options, "resume", IS_LONG)) && (Z_LVAL_P(zoption) > 0)) {
-+ range_req = 1;
-+ HTTP_CURL_OPT(CURLOPT_RESUME_FROM, Z_LVAL_P(zoption));
-+ }
-+ /* or range of kind array(array(0,499), array(100,1499)) */
-+ else if ((zoption = http_request_option(request, options, "range", IS_ARRAY)) && zend_hash_num_elements(Z_ARRVAL_P(zoption))) {
-+ HashPosition pos1, pos2;
-+ zval **rr, **rb, **re;
-+ phpstr rs;
-+
-+ phpstr_init(&rs);
-+ FOREACH_VAL(pos1, zoption, rr) {
-+ if (Z_TYPE_PP(rr) == IS_ARRAY) {
-+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(rr), &pos2);
-+ if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &rb, &pos2)) {
-+ zend_hash_move_forward_ex(Z_ARRVAL_PP(rr), &pos2);
-+ if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &re, &pos2)) {
-+ if ( ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) &&
-+ ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) {
-+ zval *rbl = http_zsep(IS_LONG, *rb);
-+ zval *rel = http_zsep(IS_LONG, *re);
-+
-+ if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) {
-+ phpstr_appendf(&rs, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel));
-+ }
-+ zval_ptr_dtor(&rbl);
-+ zval_ptr_dtor(&rel);
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ if (PHPSTR_LEN(&rs)) {
-+ zval *cached_range;
-+
-+ /* ditch last comma */
-+ PHPSTR_VAL(&rs)[PHPSTR_LEN(&rs)-- -1] = '\0';
-+ /* cache string */
-+ MAKE_STD_ZVAL(cached_range);
-+ ZVAL_STRINGL(cached_range, PHPSTR_VAL(&rs), PHPSTR_LEN(&rs), 0);
-+ HTTP_CURL_OPT(CURLOPT_RANGE, Z_STRVAL_P(http_request_option_cache(request, "range", cached_range)));
-+ zval_ptr_dtor(&cached_range);
-+ }
-+ }
-+
-+ /* additional headers, array('name' => 'value') */
-+ if (request->_cache.headers) {
-+ curl_slist_free_all(request->_cache.headers);
-+ request->_cache.headers = NULL;
-+ }
-+ if ((zoption = http_request_option(request, options, "headers", IS_ARRAY))) {
-+ HashKey header_key = initHashKey(0);
-+ zval **header_val;
-+ HashPosition pos;
-+ phpstr header;
-+
-+ phpstr_init(&header);
-+ FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
-+ if (header_key.type == HASH_KEY_IS_STRING) {
-+ zval *header_cpy = http_zsep(IS_STRING, *header_val);
-+
-+ if (!strcasecmp(header_key.str, "range")) {
-+ range_req = 1;
-+ }
-+
-+ phpstr_appendf(&header, "%s: %s", header_key.str, Z_STRVAL_P(header_cpy));
-+ phpstr_fix(&header);
-+ request->_cache.headers = curl_slist_append(request->_cache.headers, PHPSTR_VAL(&header));
-+ phpstr_reset(&header);
-+
-+ zval_ptr_dtor(&header_cpy);
-+ }
-+ }
-+ phpstr_dtor(&header);
-+ }
-+ /* etag */
-+ if ((zoption = http_request_option(request, options, "etag", IS_STRING)) && Z_STRLEN_P(zoption)) {
-+ zend_bool is_quoted = !((Z_STRVAL_P(zoption)[0] != '"') || (Z_STRVAL_P(zoption)[Z_STRLEN_P(zoption)-1] != '"'));
-+ phpstr header;
-+
-+ phpstr_init(&header);
-+ phpstr_appendf(&header, is_quoted?"%s: %s":"%s: \"%s\"", range_req?"If-Match":"If-None-Match", Z_STRVAL_P(zoption));
-+ phpstr_fix(&header);
-+ request->_cache.headers = curl_slist_append(request->_cache.headers, PHPSTR_VAL(&header));
-+ phpstr_dtor(&header);
-+ }
-+ /* compression */
-+ if ((zoption = http_request_option(request, options, "compress", IS_BOOL)) && Z_LVAL_P(zoption)) {
-+ request->_cache.headers = curl_slist_append(request->_cache.headers, "Accept-Encoding: gzip;q=1.0,deflate;q=0.5");
-+ }
-+ HTTP_CURL_OPT(CURLOPT_HTTPHEADER, request->_cache.headers);
-+
-+ /* lastmodified */
-+ if ((zoption = http_request_option(request, options, "lastmodified", IS_LONG))) {
-+ if (Z_LVAL_P(zoption)) {
-+ if (Z_LVAL_P(zoption) > 0) {
-+ HTTP_CURL_OPT(CURLOPT_TIMEVALUE, Z_LVAL_P(zoption));
-+ } else {
-+ HTTP_CURL_OPT(CURLOPT_TIMEVALUE, (long) HTTP_G->request.time + Z_LVAL_P(zoption));
-+ }
-+ HTTP_CURL_OPT(CURLOPT_TIMECONDITION, (long) (range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE));
-+ } else {
-+ HTTP_CURL_OPT(CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
-+ }
-+ }
-+
-+ /* cookies, array('name' => 'value') */
-+ if ((zoption = http_request_option(request, options, "cookies", IS_ARRAY))) {
-+ phpstr_dtor(&request->_cache.cookies);
-+ if (zend_hash_num_elements(Z_ARRVAL_P(zoption))) {
-+ zval *urlenc_cookies = NULL;
-+ /* check whether cookies should not be urlencoded; default is to urlencode them */
-+ if ((!(urlenc_cookies = http_request_option(request, options, "encodecookies", IS_BOOL))) || Z_BVAL_P(urlenc_cookies)) {
-+ if (SUCCESS == http_urlencode_hash_recursive(HASH_OF(zoption), &request->_cache.cookies, "; ", lenof("; "), NULL, 0)) {
-+ phpstr_fix(&request->_cache.cookies);
-+ HTTP_CURL_OPT(CURLOPT_COOKIE, request->_cache.cookies.data);
-+ }
-+ } else {
-+ HashPosition pos;
-+ HashKey cookie_key = initHashKey(0);
-+ zval **cookie_val;
-+
-+ FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) {
-+ if (cookie_key.type == HASH_KEY_IS_STRING) {
-+ zval *val = http_zsep(IS_STRING, *cookie_val);
-+ phpstr_appendf(&request->_cache.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
-+ zval_ptr_dtor(&val);
-+ }
-+ }
-+
-+ phpstr_fix(&request->_cache.cookies);
-+ if (PHPSTR_LEN(&request->_cache.cookies)) {
-+ HTTP_CURL_OPT(CURLOPT_COOKIE, PHPSTR_VAL(&request->_cache.cookies));
-+ }
-+ }
-+ }
-+ }
-+
-+ /* don't load session cookies from cookiestore */
-+ if ((zoption = http_request_option(request, options, "cookiesession", IS_BOOL)) && Z_BVAL_P(zoption)) {
-+ HTTP_CURL_OPT(CURLOPT_COOKIESESSION, 1L);
-+ }
-+
-+ /* cookiestore, read initial cookies from that file and store cookies back into that file */
-+ if ((zoption = http_request_option(request, options, "cookiestore", IS_STRING))) {
-+ if (Z_STRLEN_P(zoption)) {
-+ HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(zoption), return FAILURE);
-+ }
-+ if (storage->cookiestore) {
-+ pefree(storage->cookiestore, 1);
-+ }
-+ storage->cookiestore = pestrndup(Z_STRVAL_P(zoption), Z_STRLEN_P(zoption), 1);
-+ HTTP_CURL_OPT(CURLOPT_COOKIEFILE, storage->cookiestore);
-+ HTTP_CURL_OPT(CURLOPT_COOKIEJAR, storage->cookiestore);
-+ }
-+
-+ /* maxfilesize */
-+ if ((zoption = http_request_option(request, options, "maxfilesize", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_MAXFILESIZE, Z_LVAL_P(zoption));
-+ }
-+
-+ /* http protocol */
-+ if ((zoption = http_request_option(request, options, "protocol", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_HTTP_VERSION, Z_LVAL_P(zoption));
-+ }
-+
-+#if HTTP_CURL_VERSION(7,16,2)
-+ /* timeout, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "timeout", IS_DOUBLE))) {
-+ HTTP_CURL_OPT(CURLOPT_TIMEOUT_MS, (long)(Z_DVAL_P(zoption)*1000));
-+ }
-+ /* connecttimeout, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "connecttimeout", IS_DOUBLE))) {
-+ HTTP_CURL_OPT(CURLOPT_CONNECTTIMEOUT_MS, (long)(Z_DVAL_P(zoption)*1000));
-+ }
-+#else
-+ /* timeout, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "timeout", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_TIMEOUT, Z_LVAL_P(zoption));
-+ }
-+ /* connecttimeout, defaults to 0 */
-+ if ((zoption = http_request_option(request, options, "connecttimeout", IS_LONG))) {
-+ HTTP_CURL_OPT(CURLOPT_CONNECTTIMEOUT, Z_LVAL_P(zoption));
-+ }
-+#endif
-+
-+ /* ssl */
-+ if ((zoption = http_request_option(request, options, "ssl", IS_ARRAY))) {
-+ HashKey key = initHashKey(0);
-+ zval **param;
-+ HashPosition pos;
-+
-+ FOREACH_KEYVAL(pos, zoption, key, param) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLCERT, 0, 1);
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTTYPE, 0, 0);
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTPASSWD, 0, 0);
-+
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEY, 0, 0);
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYTYPE, 0, 0);
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYPASSWD, 0, 0);
-+
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSLENGINE, 0, 0);
-+ HTTP_CURL_OPT_LONG(CURLOPT_SSLVERSION, 0);
-+
-+ HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYPEER, 1);
-+ HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYHOST, 1);
-+ HTTP_CURL_OPT_STRING(CURLOPT_SSL_CIPHER_LIST, 1, 0);
-+
-+ HTTP_CURL_OPT_STRING(CURLOPT_CAINFO, -3, 1);
-+ HTTP_CURL_OPT_STRING(CURLOPT_CAPATH, -3, 1);
-+ HTTP_CURL_OPT_STRING(CURLOPT_RANDOM_FILE, -3, 1);
-+ HTTP_CURL_OPT_STRING(CURLOPT_EGDSOCKET, -3, 1);
-+#if HTTP_CURL_VERSION(7,19,0)
-+ HTTP_CURL_OPT_STRING(CURLOPT_ISSUERCERT, -3, 1);
-+ #if defined(HTTP_HAVE_OPENSSL)
-+ HTTP_CURL_OPT_STRING(CURLOPT_CRLFILE, -3, 1);
-+ #endif
-+#endif
-+#if HTTP_CURL_VERSION(7,19,1) && defined(HTTP_HAVE_OPENSSL)
-+ HTTP_CURL_OPT_LONG(CURLOPT_CERTINFO, -3);
-+#endif
-+ }
-+ }
-+ }
-+
-+ /* request method */
-+ switch (request->meth) {
-+ case HTTP_GET:
-+ HTTP_CURL_OPT(CURLOPT_HTTPGET, 1L);
-+ break;
-+
-+ case HTTP_HEAD:
-+ HTTP_CURL_OPT(CURLOPT_NOBODY, 1L);
-+ break;
-+
-+ case HTTP_POST:
-+ HTTP_CURL_OPT(CURLOPT_POST, 1L);
-+ break;
-+
-+ case HTTP_PUT:
-+ HTTP_CURL_OPT(CURLOPT_UPLOAD, 1L);
-+ break;
-+
-+ default:
-+ if (http_request_method_exists(0, request->meth, NULL)) {
-+ HTTP_CURL_OPT(CURLOPT_CUSTOMREQUEST, http_request_method_name(request->meth));
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unsupported request method: %d (%s)", request->meth, request->url);
-+ return FAILURE;
-+ }
-+ break;
-+ }
-+
-+ /* attach request body */
-+ if (request->body && (request->meth != HTTP_GET) && (request->meth != HTTP_HEAD) && (request->meth != HTTP_OPTIONS)) {
-+ switch (request->body->type) {
-+ case HTTP_REQUEST_BODY_EMPTY:
-+ /* nothing */
-+ break;
-+
-+ case HTTP_REQUEST_BODY_CURLPOST:
-+ HTTP_CURL_OPT(CURLOPT_HTTPPOST, (struct curl_httppost *) request->body->data);
-+ break;
-+
-+ case HTTP_REQUEST_BODY_CSTRING:
-+ if (request->meth != HTTP_PUT) {
-+ HTTP_CURL_OPT(CURLOPT_POSTFIELDS, request->body->data);
-+ HTTP_CURL_OPT(CURLOPT_POSTFIELDSIZE, request->body->size);
-+ break;
-+ }
-+ /* fallthrough, PUT/UPLOAD _needs_ READDATA */
-+ case HTTP_REQUEST_BODY_UPLOADFILE:
-+ HTTP_CURL_OPT(CURLOPT_IOCTLDATA, request);
-+ HTTP_CURL_OPT(CURLOPT_READDATA, request);
-+ HTTP_CURL_OPT(CURLOPT_INFILESIZE, request->body->size);
-+ break;
-+
-+ default:
-+ /* shouldn't ever happen */
-+ http_error_ex(HE_ERROR, 0, "Unknown request body type: %d (%s)", request->body->type, request->url);
-+ return FAILURE;
-+ }
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_exec(http_request *) */
-+PHP_HTTP_API void _http_request_exec(http_request *request)
-+{
-+ uint tries = 0;
-+ CURLcode result;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+retry:
-+ if (CURLE_OK != (result = curl_easy_perform(request->ch))) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "%s; %s (%s)", curl_easy_strerror(result), http_request_storage_get(request->ch)->errorbuffer, request->url);
-+#ifdef ZEND_ENGINE_2
-+ if ((HTTP_G->only_exceptions || GLOBAL_ERROR_HANDLING == EH_THROW) && EG(exception)) {
-+ add_property_long(EG(exception), "curlCode", result);
-+ }
-+#endif
-+
-+ if (request->_retry.count > tries++) {
-+ switch (result) {
-+ case CURLE_COULDNT_RESOLVE_PROXY:
-+ case CURLE_COULDNT_RESOLVE_HOST:
-+ case CURLE_COULDNT_CONNECT:
-+ case CURLE_WRITE_ERROR:
-+ case CURLE_READ_ERROR:
-+ case CURLE_OPERATION_TIMEDOUT:
-+ case CURLE_SSL_CONNECT_ERROR:
-+ case CURLE_GOT_NOTHING:
-+ case CURLE_SSL_ENGINE_SETFAILED:
-+ case CURLE_SEND_ERROR:
-+ case CURLE_RECV_ERROR:
-+ case CURLE_SSL_ENGINE_INITFAILED:
-+ case CURLE_LOGIN_DENIED:
-+ if (request->_retry.delay >= HTTP_DIFFSEC) {
-+ http_sleep(request->_retry.delay);
-+ }
-+ goto retry;
-+ default:
-+ break;
-+ }
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ static size_t http_curl_read_callback(void *, size_t, size_t, void *) */
-+static size_t http_curl_read_callback(void *data, size_t len, size_t n, void *ctx)
-+{
-+ http_request *request = (http_request *) ctx;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ if (request->body) {
-+ switch (request->body->type) {
-+ case HTTP_REQUEST_BODY_CSTRING:
-+ {
-+ size_t out = MIN(len * n, request->body->size - request->body->priv);
-+
-+ if (out) {
-+ memcpy(data, ((char *) request->body->data) + request->body->priv, out);
-+ request->body->priv += out;
-+ return out;
-+ }
-+ break;
-+ }
-+
-+ case HTTP_REQUEST_BODY_UPLOADFILE:
-+ return php_stream_read((php_stream *) request->body->data, data, len * n);
-+ }
-+ }
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ static int http_curl_progress_callback(void *, double, double, double, double) */
-+static int http_curl_progress_callback(void *ctx, double dltotal, double dlnow, double ultotal, double ulnow)
-+{
-+ zval *param, retval;
-+ http_request *request = (http_request *) ctx;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ INIT_PZVAL(&retval);
-+ ZVAL_NULL(&retval);
-+
-+ MAKE_STD_ZVAL(param);
-+ array_init(param);
-+ add_assoc_double(param, "dltotal", dltotal);
-+ add_assoc_double(param, "dlnow", dlnow);
-+ add_assoc_double(param, "ultotal", ultotal);
-+ add_assoc_double(param, "ulnow", ulnow);
-+
-+ with_error_handling(EH_NORMAL, NULL) {
-+ request->_in_progress_cb = 1;
-+ call_user_function(EG(function_table), NULL, request->_progress_callback, &retval, 1, ¶m TSRMLS_CC);
-+ request->_in_progress_cb = 0;
-+ } end_error_handling();
-+
-+ zval_ptr_dtor(¶m);
-+ zval_dtor(&retval);
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ static curlioerr http_curl_ioctl_callback(CURL *, curliocmd, void *) */
-+static curlioerr http_curl_ioctl_callback(CURL *ch, curliocmd cmd, void *ctx)
-+{
-+ http_request *request = (http_request *) ctx;
-+ TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
-+
-+ if (cmd != CURLIOCMD_RESTARTREAD) {
-+ return CURLIOE_UNKNOWNCMD;
-+ }
-+
-+ if (request->body) {
-+ switch (request->body->type) {
-+ case HTTP_REQUEST_BODY_CSTRING:
-+ request->body->priv = 0;
-+ return CURLIOE_OK;
-+ break;
-+
-+ case HTTP_REQUEST_BODY_UPLOADFILE:
-+ if (SUCCESS == php_stream_rewind((php_stream *) request->body->data)) {
-+ return CURLIOE_OK;
-+ }
-+ break;
-+ }
-+ }
-+
-+ return CURLIOE_FAILRESTART;
-+}
-+/* }}} */
-+
-+/* {{{ static int http_curl_raw_callback(CURL *, curl_infotype, char *, size_t, void *) */
-+static int http_curl_raw_callback(CURL *ch, curl_infotype type, char *data, size_t length, void *ctx)
-+{
-+ http_request *request = (http_request *) ctx;
-+
-+#define EMPTY_HEADER(d, l) (!l || (l == 1 && d[0] == '\n') || (l == 2 && d[0] == '\r' && d[1] == '\n'))
-+ switch (type) {
-+ case CURLINFO_DATA_IN:
-+ if (request->conv.last_type == CURLINFO_HEADER_IN) {
-+ phpstr_appends(&request->conv.response, HTTP_CRLF);
-+ }
-+ phpstr_append(&request->conv.response, data, length);
-+ break;
-+ case CURLINFO_HEADER_IN:
-+ if (!EMPTY_HEADER(data, length)) {
-+ phpstr_append(&request->conv.response, data, length);
-+ }
-+ break;
-+ case CURLINFO_DATA_OUT:
-+ case CURLINFO_HEADER_OUT:
-+ phpstr_append(&request->conv.request, data, length);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+#if 0
-+ {
-+ const char _sym[] = "><><><";
-+ if (type) {
-+ for (fprintf(stderr, "%c ", _sym[type-1]); length--; data++) {
-+ fprintf(stderr, HTTP_IS_CTYPE(print, *data)?"%c":"\\x%02X", (int) *data);
-+ if (*data == '\n' && length) {
-+ fprintf(stderr, "\n%c ", _sym[type-1]);
-+ }
-+ }
-+ fprintf(stderr, "\n");
-+ } else {
-+ fprintf(stderr, "# %s", data);
-+ }
-+ }
-+#endif
-+
-+ if (type) {
-+ request->conv.last_type = type;
-+ }
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ static inline zval *http_request_option(http_request *, HashTable *, char *, size_t, int) */
-+static inline zval *_http_request_option_ex(http_request *r, HashTable *options, char *key, size_t keylen, int type TSRMLS_DC)
-+{
-+ if (options) {
-+ zval **zoption;
-+ ulong h = zend_hash_func(key, keylen);
-+
-+ if (SUCCESS == zend_hash_quick_find(options, key, keylen, h, (void *) &zoption)) {
-+ zval *option, *cached;
-+
-+ option = http_zsep(type, *zoption);
-+ cached = http_request_option_cache_ex(r, key, keylen, h, option);
-+
-+ zval_ptr_dtor(&option);
-+ return cached;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+/* }}} */
-+
-+/* {{{ static inline zval *http_request_option_cache(http_request *, char *key, zval *) */
-+static inline zval *_http_request_option_cache_ex(http_request *r, char *key, size_t keylen, ulong h, zval *opt TSRMLS_DC)
-+{
-+ ZVAL_ADDREF(opt);
-+
-+ if (h) {
-+ zend_hash_quick_update(&r->_cache.options, key, keylen, h, &opt, sizeof(zval *), NULL);
-+ } else {
-+ zend_hash_update(&r->_cache.options, key, keylen, &opt, sizeof(zval *), NULL);
-+ }
-+
-+ return opt;
-+}
-+/* }}} */
-+
-+/* {{{ static inline int http_request_cookies_enabled(http_request *) */
-+static inline int _http_request_cookies_enabled(http_request *request) {
-+ http_request_storage *st;
-+
-+ if (request->ch && (st = http_request_storage_get(request->ch)) && st->cookiestore) {
-+ /* cookies are enabled */
-+ return 1;
-+ }
-+ return 0;
-+}
-+/* }}} */
-+
-+#endif /* HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_request_body_api.c
-@@ -0,0 +1,332 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_body_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#ifdef HTTP_HAVE_CURL
-+
-+#include "php_http_api.h"
-+#include "php_http_url_api.h"
-+#include "php_http_request_body_api.h"
-+
-+/* {{{ */
-+typedef struct curl_httppost *post_data[2];
-+static STATUS recursive_fields(post_data http_post_data, HashTable *fields, const char *prefix TSRMLS_DC);
-+static STATUS recursive_files(post_data http_post_data, HashTable *files, const char *prefix TSRMLS_DC);
-+/* }}} */
-+
-+/* {{{ http_request_body *http_request_body_new() */
-+PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *body, int type, void *data, size_t size, zend_bool free ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ if (!body) {
-+ body = emalloc_rel(sizeof(http_request_body));
-+ }
-+
-+ body->type = type;
-+ body->free = free;
-+ body->priv = 0;
-+ body->data = data;
-+ body->size = size;
-+
-+ return body;
-+}
-+/* }}} */
-+
-+/* {{{ http_request_body *http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
-+PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
-+{
-+ if (files && (zend_hash_num_elements(files) > 0)) {
-+ struct curl_httppost *http_post_data[2] = {NULL, NULL};
-+
-+ if (fields && SUCCESS != recursive_fields(http_post_data, fields, NULL TSRMLS_CC)) {
-+ return NULL;
-+ }
-+ if (SUCCESS != recursive_files(http_post_data, files, NULL TSRMLS_CC)) {
-+ return NULL;
-+ }
-+ return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CURLPOST, http_post_data[0], 0, 1);
-+ } else if (fields) {
-+ char *encoded;
-+ size_t encoded_len;
-+
-+ if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) {
-+ http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data");
-+ return NULL;
-+ }
-+
-+ return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, encoded, encoded_len, 1);
-+ } else {
-+ return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, estrndup("", 0), 0, 1);
-+ }
-+}
-+
-+/* STATUS http_request_body_encode(http_request_body *, char**, size_t *) */
-+PHP_HTTP_API STATUS _http_request_body_encode(http_request_body *body, char **buf, size_t *len TSRMLS_DC)
-+{
-+ switch (body->type) {
-+ case HTTP_REQUEST_BODY_CURLPOST:
-+ {
-+#ifdef HAVE_CURL_FORMGET
-+ phpstr str;
-+
-+ phpstr_init_ex(&str, 0x8000, 0);
-+ if (curl_formget(body->data, &str, (curl_formget_callback) phpstr_append)) {
-+ phpstr_dtor(&str);
-+ } else {
-+ phpstr_fix(&str);
-+ *buf = PHPSTR_VAL(&str);
-+ *len = PHPSTR_LEN(&str);
-+ return SUCCESS;
-+ }
-+#endif
-+ break;
-+ }
-+
-+ case HTTP_REQUEST_BODY_CSTRING:
-+ *buf = estrndup(body->data, *len = body->size);
-+ return SUCCESS;
-+
-+ default:
-+ break;
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_body_dtor(http_request_body *) */
-+PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC)
-+{
-+ if (body) {
-+ if (body->free) {
-+ switch (body->type) {
-+ case HTTP_REQUEST_BODY_CSTRING:
-+ if (body->data) {
-+ efree(body->data);
-+ }
-+ break;
-+
-+ case HTTP_REQUEST_BODY_CURLPOST:
-+ curl_formfree(body->data);
-+ break;
-+
-+ case HTTP_REQUEST_BODY_UPLOADFILE:
-+ php_stream_close(body->data);
-+ break;
-+ }
-+ }
-+ memset(body, 0, sizeof(http_request_body));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_body_free(http_request_body *) */
-+PHP_HTTP_API void _http_request_body_free(http_request_body **body TSRMLS_DC)
-+{
-+ if (*body) {
-+ http_request_body_dtor(*body);
-+ efree(*body);
-+ *body = NULL;
-+ }
-+}
-+/* }}} */
-+
-+static inline char *format_key(uint type, char *str, ulong num, const char *prefix, int numeric_key_for_empty_prefix) {
-+ char *new_key = NULL;
-+
-+ if (prefix && *prefix) {
-+ if (type == HASH_KEY_IS_STRING) {
-+ spprintf(&new_key, 0, "%s[%s]", prefix, str);
-+ } else {
-+ spprintf(&new_key, 0, "%s[%lu]", prefix, num);
-+ }
-+ } else if (type == HASH_KEY_IS_STRING) {
-+ new_key = estrdup(str);
-+ } else if (numeric_key_for_empty_prefix) {
-+ spprintf(&new_key, 0, "%lu", num);
-+ }
-+
-+ return new_key;
-+}
-+
-+/* {{{ static STATUS recursive_fields(post_data d, HashTable *f, const char *p TSRMLS_DC) */
-+static STATUS recursive_fields(post_data http_post_data, HashTable *fields, const char *prefix TSRMLS_DC) {
-+ HashKey key = initHashKey(0);
-+ zval **data_ptr;
-+ HashPosition pos;
-+ char *new_key = NULL;
-+ CURLcode err = 0;
-+
-+ if (fields && !fields->nApplyCount) {
-+ FOREACH_HASH_KEYVAL(pos, fields, key, data_ptr) {
-+ if (key.type != HASH_KEY_IS_STRING || *key.str) {
-+ new_key = format_key(key.type, key.str, key.num, prefix, 1);
-+
-+ switch (Z_TYPE_PP(data_ptr)) {
-+ case IS_ARRAY:
-+ case IS_OBJECT: {
-+ STATUS status;
-+
-+ ++fields->nApplyCount;
-+ status = recursive_fields(http_post_data, HASH_OF(*data_ptr), new_key TSRMLS_CC);
-+ --fields->nApplyCount;
-+
-+ if (SUCCESS != status) {
-+ goto error;
-+ }
-+ break;
-+ }
-+
-+ default: {
-+ zval *data = http_zsep(IS_STRING, *data_ptr);
-+
-+ err = curl_formadd(&http_post_data[0], &http_post_data[1],
-+ CURLFORM_COPYNAME, new_key,
-+ CURLFORM_COPYCONTENTS, Z_STRVAL_P(data),
-+ CURLFORM_CONTENTSLENGTH, (long) Z_STRLEN_P(data),
-+ CURLFORM_END
-+ );
-+
-+ zval_ptr_dtor(&data);
-+
-+ if (CURLE_OK != err) {
-+ goto error;
-+ }
-+ break;
-+ }
-+ }
-+ STR_FREE(new_key);
-+ }
-+ }
-+ }
-+
-+ return SUCCESS;
-+
-+error:
-+ if (new_key) {
-+ efree(new_key);
-+ }
-+ if (http_post_data[0]) {
-+ curl_formfree(http_post_data[0]);
-+ }
-+ if (err) {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: unknown error");
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ static STATUS recursive_files(post_data d, HashTable *f, const char *p TSRMLS_DC) */
-+static STATUS recursive_files(post_data http_post_data, HashTable *files, const char *prefix TSRMLS_DC) {
-+ HashKey key = initHashKey(0);
-+ zval **data_ptr;
-+ HashPosition pos;
-+ char *new_key = NULL;
-+ CURLcode err = 0;
-+
-+ if (files && !files->nApplyCount) {
-+ FOREACH_HASH_KEYVAL(pos, files, key, data_ptr) {
-+ zval **file_ptr, **type_ptr, **name_ptr;
-+
-+ if (key.type != HASH_KEY_IS_STRING || *key.str) {
-+ new_key = format_key(key.type, key.str, key.num, prefix, 0);
-+
-+ if (Z_TYPE_PP(data_ptr) != IS_ARRAY && Z_TYPE_PP(data_ptr) != IS_OBJECT) {
-+ if (new_key || key.type == HASH_KEY_IS_STRING) {
-+ http_error_ex(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry '%s'", new_key ? new_key : key.str);
-+ } else {
-+ http_error_ex(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry '%lu'", key.num);
-+ }
-+ } else if ( SUCCESS != zend_hash_find(HASH_OF(*data_ptr), "name", sizeof("name"), (void *) &name_ptr) ||
-+ SUCCESS != zend_hash_find(HASH_OF(*data_ptr), "type", sizeof("type"), (void *) &type_ptr) ||
-+ SUCCESS != zend_hash_find(HASH_OF(*data_ptr), "file", sizeof("file"), (void *) &file_ptr)) {
-+ STATUS status;
-+
-+ ++files->nApplyCount;
-+ status = recursive_files(http_post_data, HASH_OF(*data_ptr), new_key TSRMLS_CC);
-+ --files->nApplyCount;
-+
-+ if (SUCCESS != status) {
-+ goto error;
-+ }
-+ } else {
-+ const char *path;
-+ zval *file = http_zsep(IS_STRING, *file_ptr);
-+ zval *type = http_zsep(IS_STRING, *type_ptr);
-+ zval *name = http_zsep(IS_STRING, *name_ptr);
-+
-+ HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(file), goto error);
-+
-+ /* this is blatant but should be sufficient for most cases */
-+ if (strncasecmp(Z_STRVAL_P(file), "file://", lenof("file://"))) {
-+ path = Z_STRVAL_P(file);
-+ } else {
-+ path = Z_STRVAL_P(file) + lenof("file://");
-+ }
-+
-+ if (new_key) {
-+ char *tmp_key = format_key(HASH_KEY_IS_STRING, Z_STRVAL_P(name), 0, new_key, 0);
-+ STR_SET(new_key, tmp_key);
-+ }
-+
-+ err = curl_formadd(&http_post_data[0], &http_post_data[1],
-+ CURLFORM_COPYNAME, new_key ? new_key : Z_STRVAL_P(name),
-+ CURLFORM_FILE, path,
-+ CURLFORM_CONTENTTYPE, Z_STRVAL_P(type),
-+ CURLFORM_END
-+ );
-+
-+ zval_ptr_dtor(&file);
-+ zval_ptr_dtor(&type);
-+ zval_ptr_dtor(&name);
-+
-+ if (CURLE_OK != err) {
-+ goto error;
-+ }
-+ }
-+ STR_FREE(new_key);
-+ }
-+ }
-+ }
-+
-+ return SUCCESS;
-+
-+error:
-+ if (new_key) {
-+ efree(new_key);
-+ }
-+ if (http_post_data[0]) {
-+ curl_formfree(http_post_data[0]);
-+ }
-+ if (err) {
-+ http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: unknown error");
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+#endif /* HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/http_request_datashare_api.c
-@@ -0,0 +1,288 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_datashare_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+
-+#include "php_http_api.h"
-+#include "php_http_persistent_handle_api.h"
-+#include "php_http_request_datashare_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+
-+static HashTable http_request_datashare_options;
-+static http_request_datashare http_request_datashare_global;
-+static int http_request_datashare_compare_handles(void *h1, void *h2);
-+static void http_request_datashare_destroy_handles(void *el);
-+#ifdef ZTS
-+static void *http_request_datashare_locks_init(void);
-+static void http_request_datashare_locks_dtor(void *l);
-+static void http_request_datashare_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr);
-+static void http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr);
-+#endif
-+
-+http_request_datashare *_http_request_datashare_global_get(void)
-+{
-+ return &http_request_datashare_global;
-+}
-+
-+PHP_MINIT_FUNCTION(http_request_datashare)
-+{
-+ curl_lock_data val;
-+
-+ if (SUCCESS != http_persistent_handle_provide("http_request_datashare", curl_share_init, (http_persistent_handle_dtor) curl_share_cleanup, NULL)) {
-+ return FAILURE;
-+ }
-+#ifdef ZTS
-+ if (SUCCESS != http_persistent_handle_provide("http_request_datashare_lock", http_request_datashare_locks_init, http_request_datashare_locks_dtor, NULL)) {
-+ return FAILURE;
-+ }
-+#endif
-+
-+ if (!http_request_datashare_init_ex(&http_request_datashare_global, 1)) {
-+ return FAILURE;
-+ }
-+
-+ zend_hash_init(&http_request_datashare_options, 4, NULL, NULL, 1);
-+#define ADD_DATASHARE_OPT(name, opt) \
-+ val = opt; \
-+ zend_hash_add(&http_request_datashare_options, name, sizeof(name), &val, sizeof(curl_lock_data), NULL)
-+ ADD_DATASHARE_OPT("cookie", CURL_LOCK_DATA_COOKIE);
-+ ADD_DATASHARE_OPT("dns", CURL_LOCK_DATA_DNS);
-+ ADD_DATASHARE_OPT("ssl", CURL_LOCK_DATA_SSL_SESSION);
-+ ADD_DATASHARE_OPT("connect", CURL_LOCK_DATA_CONNECT);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_MSHUTDOWN_FUNCTION(http_request_datashare)
-+{
-+ http_request_datashare_dtor(&http_request_datashare_global);
-+ zend_hash_destroy(&http_request_datashare_options);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_RINIT_FUNCTION(http_request_datashare)
-+{
-+ zend_llist_init(&HTTP_G->request.datashare.handles, sizeof(zval *), http_request_datashare_destroy_handles, 0);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_RSHUTDOWN_FUNCTION(http_request_datashare)
-+{
-+ zend_llist_destroy(&HTTP_G->request.datashare.handles);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_request_datashare *share, zend_bool persistent TSRMLS_DC)
-+{
-+ zend_bool free_share;
-+
-+ if ((free_share = !share)) {
-+ share = pemalloc(sizeof(http_request_datashare), persistent);
-+ }
-+ memset(share, 0, sizeof(http_request_datashare));
-+
-+ if (SUCCESS != http_persistent_handle_acquire("http_request_datashare", &share->ch)) {
-+ if (free_share) {
-+ pefree(share, persistent);
-+ }
-+ return NULL;
-+ }
-+
-+ if (!(share->persistent = persistent)) {
-+ share->handle.list = emalloc(sizeof(zend_llist));
-+ zend_llist_init(share->handle.list, sizeof(zval *), ZVAL_PTR_DTOR, 0);
-+#ifdef ZTS
-+ } else {
-+ if (SUCCESS == http_persistent_handle_acquire("http_request_datashare_lock", (void *) &share->handle.locks)) {
-+ curl_share_setopt(share->ch, CURLSHOPT_LOCKFUNC, http_request_datashare_lock_func);
-+ curl_share_setopt(share->ch, CURLSHOPT_UNLOCKFUNC, http_request_datashare_unlock_func);
-+ curl_share_setopt(share->ch, CURLSHOPT_USERDATA, share->handle.locks);
-+ }
-+#endif
-+ }
-+
-+ return share;
-+}
-+
-+PHP_HTTP_API STATUS _http_request_datashare_attach(http_request_datashare *share, zval *request TSRMLS_DC)
-+{
-+ CURLcode rc;
-+ getObjectEx(http_request_object, obj, request);
-+
-+ if (obj->share) {
-+ if (obj->share == share) {
-+ return SUCCESS;
-+ } else if (SUCCESS != http_request_datashare_detach(obj->share, request)) {
-+ return FAILURE;
-+ }
-+ }
-+
-+ HTTP_CHECK_CURL_INIT(obj->request->ch, http_curl_init_ex(obj->request->ch, obj->request), return FAILURE);
-+ if (CURLE_OK != (rc = curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, share->ch))) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not attach HttpRequest object(#%d) to the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_easy_strerror(rc));
-+ return FAILURE;
-+ }
-+
-+ obj->share = share;
-+ ZVAL_ADDREF(request);
-+ zend_llist_add_element(HTTP_RSHARE_HANDLES(share), (void *) &request);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API STATUS _http_request_datashare_detach(http_request_datashare *share, zval *request TSRMLS_DC)
-+{
-+ CURLcode rc;
-+ getObjectEx(http_request_object, obj, request);
-+
-+ if (!obj->share) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "HttpRequest object(#%d) is not attached to any HttpRequestDataShare", Z_OBJ_HANDLE_P(request));
-+ } else if (obj->share != share) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "HttpRequest object(#%d) is not attached to this HttpRequestDataShare", Z_OBJ_HANDLE_P(request));
-+ } else if (CURLE_OK != (rc = curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, NULL))) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not detach HttpRequest object(#%d) from the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_share_strerror(rc));
-+ } else {
-+ obj->share = NULL;
-+ zend_llist_del_element(HTTP_RSHARE_HANDLES(share), request, http_request_datashare_compare_handles);
-+ return SUCCESS;
-+ }
-+ return FAILURE;
-+}
-+
-+PHP_HTTP_API void _http_request_datashare_detach_all(http_request_datashare *share TSRMLS_DC)
-+{
-+ zval **r;
-+
-+ while ((r = zend_llist_get_first(HTTP_RSHARE_HANDLES(share)))) {
-+ http_request_datashare_detach(share, *r);
-+ }
-+}
-+
-+PHP_HTTP_API void _http_request_datashare_dtor(http_request_datashare *share TSRMLS_DC)
-+{
-+ if (!share->persistent) {
-+ zend_llist_destroy(share->handle.list);
-+ efree(share->handle.list);
-+ }
-+ http_persistent_handle_release("http_request_datashare", &share->ch);
-+#ifdef ZTS
-+ if (share->persistent) {
-+ http_persistent_handle_release("http_request_datashare_lock", (void *) &share->handle.locks);
-+ }
-+#endif
-+}
-+
-+PHP_HTTP_API void _http_request_datashare_free(http_request_datashare **share TSRMLS_DC)
-+{
-+ http_request_datashare_dtor(*share);
-+ pefree(*share, (*share)->persistent);
-+ *share = NULL;
-+}
-+
-+PHP_HTTP_API STATUS _http_request_datashare_set(http_request_datashare *share, const char *option, size_t option_len, zend_bool enable TSRMLS_DC)
-+{
-+ curl_lock_data *opt;
-+ CURLSHcode rc;
-+
-+ if (SUCCESS == zend_hash_find(&http_request_datashare_options, (char *) option, option_len + 1, (void *) &opt)) {
-+ if (CURLSHE_OK == (rc = curl_share_setopt(share->ch, enable ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, *opt))) {
-+ return SUCCESS;
-+ }
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not %s sharing of %s data: %s", enable ? "enable" : "disable", option, curl_share_strerror(rc));
-+ }
-+ return FAILURE;
-+}
-+
-+static int http_request_datashare_compare_handles(void *h1, void *h2)
-+{
-+ return (Z_OBJ_HANDLE_PP((zval **) h1) == Z_OBJ_HANDLE_P((zval *) h2));
-+}
-+
-+static void http_request_datashare_destroy_handles(void *el)
-+{
-+ zval **r = (zval **) el;
-+ TSRMLS_FETCH();
-+
-+ { /* gcc 2.95 needs these braces */
-+ getObjectEx(http_request_object, obj, *r);
-+
-+ curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, NULL);
-+ zval_ptr_dtor(r);
-+ }
-+}
-+
-+#ifdef ZTS
-+static void *http_request_datashare_locks_init(void)
-+{
-+ int i;
-+ http_request_datashare_lock *locks = pecalloc(CURL_LOCK_DATA_LAST, sizeof(http_request_datashare_lock), 1);
-+
-+ if (locks) {
-+ for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) {
-+ locks[i].mx = tsrm_mutex_alloc();
-+ }
-+ }
-+
-+ return locks;
-+}
-+
-+static void http_request_datashare_locks_dtor(void *l)
-+{
-+ int i;
-+ http_request_datashare_lock *locks = (http_request_datashare_lock *) l;
-+
-+ for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) {
-+ tsrm_mutex_free(locks[i].mx);
-+ }
-+ pefree(locks, 1);
-+}
-+
-+static void http_request_datashare_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr)
-+{
-+ http_request_datashare_lock *locks = (http_request_datashare_lock *) userptr;
-+
-+ /* TSRM can't distinguish shared/exclusive locks */
-+ tsrm_mutex_lock(locks[data].mx);
-+ locks[data].ch = handle;
-+}
-+
-+static void http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr)
-+{
-+ http_request_datashare_lock *locks = (http_request_datashare_lock *) userptr;
-+
-+ if (locks[data].ch == handle) {
-+ tsrm_mutex_unlock(locks[data].mx);
-+ }
-+}
-+#endif
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_request_info.c
-@@ -0,0 +1,213 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_info.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#ifdef HTTP_HAVE_CURL
-+#include "php_http_request_api.h"
-+
-+/* {{{ void http_request_info(http_request *, HashTable *) */
-+PHP_HTTP_API void _http_request_info(http_request *request, HashTable *info)
-+{
-+ char *c;
-+ long l;
-+ double d;
-+ struct curl_slist *s, *p;
-+ zval *subarray, array;
-+ INIT_ZARR(array, info);
-+
-+ /* BEGIN */
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_EFFECTIVE_URL, &c)) {
-+ add_assoc_string_ex(&array, "effective_url", sizeof("effective_url"), c ? c : "", 1);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_RESPONSE_CODE, &l)) {
-+ add_assoc_long_ex(&array, "response_code", sizeof("response_code"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_TOTAL_TIME, &d)) {
-+ add_assoc_double_ex(&array, "total_time", sizeof("total_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_NAMELOOKUP_TIME, &d)) {
-+ add_assoc_double_ex(&array, "namelookup_time", sizeof("namelookup_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONNECT_TIME, &d)) {
-+ add_assoc_double_ex(&array, "connect_time", sizeof("connect_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PRETRANSFER_TIME, &d)) {
-+ add_assoc_double_ex(&array, "pretransfer_time", sizeof("pretransfer_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SIZE_UPLOAD, &d)) {
-+ add_assoc_double_ex(&array, "size_upload", sizeof("size_upload"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SIZE_DOWNLOAD, &d)) {
-+ add_assoc_double_ex(&array, "size_download", sizeof("size_download"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SPEED_DOWNLOAD, &d)) {
-+ add_assoc_double_ex(&array, "speed_download", sizeof("speed_download"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SPEED_UPLOAD, &d)) {
-+ add_assoc_double_ex(&array, "speed_upload", sizeof("speed_upload"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HEADER_SIZE, &l)) {
-+ add_assoc_long_ex(&array, "header_size", sizeof("header_size"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REQUEST_SIZE, &l)) {
-+ add_assoc_long_ex(&array, "request_size", sizeof("request_size"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SSL_VERIFYRESULT, &l)) {
-+ add_assoc_long_ex(&array, "ssl_verifyresult", sizeof("ssl_verifyresult"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_FILETIME, &l)) {
-+ add_assoc_long_ex(&array, "filetime", sizeof("filetime"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) {
-+ add_assoc_double_ex(&array, "content_length_download", sizeof("content_length_download"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_LENGTH_UPLOAD, &d)) {
-+ add_assoc_double_ex(&array, "content_length_upload", sizeof("content_length_upload"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_STARTTRANSFER_TIME, &d)) {
-+ add_assoc_double_ex(&array, "starttransfer_time", sizeof("starttransfer_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_TYPE, &c)) {
-+ add_assoc_string_ex(&array, "content_type", sizeof("content_type"), c ? c : "", 1);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REDIRECT_TIME, &d)) {
-+ add_assoc_double_ex(&array, "redirect_time", sizeof("redirect_time"), d);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REDIRECT_COUNT, &l)) {
-+ add_assoc_long_ex(&array, "redirect_count", sizeof("redirect_count"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HTTP_CONNECTCODE, &l)) {
-+ add_assoc_long_ex(&array, "connect_code", sizeof("connect_code"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HTTPAUTH_AVAIL, &l)) {
-+ add_assoc_long_ex(&array, "httpauth_avail", sizeof("httpauth_avail"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PROXYAUTH_AVAIL, &l)) {
-+ add_assoc_long_ex(&array, "proxyauth_avail", sizeof("proxyauth_avail"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_OS_ERRNO, &l)) {
-+ add_assoc_long_ex(&array, "os_errno", sizeof("os_errno"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_NUM_CONNECTS, &l)) {
-+ add_assoc_long_ex(&array, "num_connects", sizeof("num_connects"), l);
-+ }
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SSL_ENGINES, &s)) {
-+ MAKE_STD_ZVAL(subarray);
-+ array_init(subarray);
-+ for (p = s; p; p = p->next) {
-+ if (p->data) {
-+ add_next_index_string(subarray, p->data, 1);
-+ }
-+ }
-+ add_assoc_zval_ex(&array, "ssl_engines", sizeof("ssl_engines"), subarray);
-+ curl_slist_free_all(s);
-+ }
-+#if HTTP_CURL_VERSION(7,14,1)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_COOKIELIST, &s)) {
-+ MAKE_STD_ZVAL(subarray);
-+ array_init(subarray);
-+ for (p = s; p; p = p->next) {
-+ if (p->data) {
-+ add_next_index_string(subarray, p->data, 1);
-+ }
-+ }
-+ add_assoc_zval_ex(&array, "cookies", sizeof("cookies"), subarray);
-+ curl_slist_free_all(s);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,18,2)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REDIRECT_URL, &c)) {
-+ add_assoc_string_ex(&array, "redirect_url", sizeof("redirect_url"), c ? c : "", 1);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,19,0)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PRIMARY_IP, &c)) {
-+ add_assoc_string_ex(&array, "primary_ip", sizeof("primary_ip"), c ? c : "", 1);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,19,0)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_APPCONNECT_TIME, &d)) {
-+ add_assoc_double_ex(&array, "appconnect_time", sizeof("appconnect_time"), d);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,19,4)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONDITION_UNMET, &l)) {
-+ add_assoc_long_ex(&array, "condition_unmet", sizeof("condition_unmet"), l);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,21,0)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PRIMARY_PORT, &l)) {
-+ add_assoc_long_ex(&array, "primary_port", sizeof("primary_port"), l);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,21,0)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_LOCAL_IP, &c)) {
-+ add_assoc_string_ex(&array, "local_ip", sizeof("local_ip"), c ? c : "", 1);
-+ }
-+#endif
-+#if HTTP_CURL_VERSION(7,21,0)
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_LOCAL_PORT, &l)) {
-+ add_assoc_long_ex(&array, "local_port", sizeof("local_port"), l);
-+ }
-+#endif
-+/* END */
-+#if HTTP_CURL_VERSION(7,19,1) && defined(HTTP_HAVE_OPENSSL)
-+ {
-+ int i;
-+ zval *ci_array;
-+ struct curl_certinfo *ci;
-+ char *colon, *keyname;
-+
-+ if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CERTINFO, &ci)) {
-+ MAKE_STD_ZVAL(ci_array);
-+ array_init(ci_array);
-+
-+ for (i = 0; i < ci->num_of_certs; ++i) {
-+ s = ci->certinfo[i];
-+
-+ MAKE_STD_ZVAL(subarray);
-+ array_init(subarray);
-+ for (p = s; p; p = p->next) {
-+ if (p->data) {
-+ if ((colon = strchr(p->data, ':'))) {
-+ keyname = estrndup(p->data, colon - p->data);
-+ add_assoc_string_ex(subarray, keyname, colon - p->data + 1, colon + 1, 1);
-+ efree(keyname);
-+ } else {
-+ add_next_index_string(subarray, p->data, 1);
-+ }
-+ }
-+ }
-+ add_next_index_zval(ci_array, subarray);
-+ }
-+ add_assoc_zval_ex(&array, "certinfo", sizeof("certinfo"), ci_array);
-+ }
-+ }
-+#endif
-+ add_assoc_string_ex(&array, "error", sizeof("error"), http_request_storage_get(request->ch)->errorbuffer, 1);
-+}
-+/* }}} */
-+
-+#endif /* HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/http_request_method_api.c
-@@ -0,0 +1,322 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_method_api.c 323406 2012-02-21 10:05:52Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_method_api.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
-+# include "php_http_request_object.h"
-+#endif
-+
-+/* {{{ char *http_request_methods[] */
-+static const char *const http_request_methods[] = {
-+ "UNKNOWN",
-+ /* HTTP/1.1 */
-+ "GET",
-+ "HEAD",
-+ "POST",
-+ "PUT",
-+ "DELETE",
-+ "OPTIONS",
-+ "TRACE",
-+ "CONNECT",
-+ /* WebDAV - RFC 2518 */
-+ "PROPFIND",
-+ "PROPPATCH",
-+ "MKCOL",
-+ "COPY",
-+ "MOVE",
-+ "LOCK",
-+ "UNLOCK",
-+ /* WebDAV Versioning - RFC 3253 */
-+ "VERSION-CONTROL",
-+ "REPORT",
-+ "CHECKOUT",
-+ "CHECKIN",
-+ "UNCHECKOUT",
-+ "MKWORKSPACE",
-+ "UPDATE",
-+ "LABEL",
-+ "MERGE",
-+ "BASELINE-CONTROL",
-+ "MKACTIVITY",
-+ /* WebDAV Access Control - RFC 3744 */
-+ "ACL",
-+ NULL
-+};
-+/* }}} */
-+
-+/* {{{ */
-+PHP_MINIT_FUNCTION(http_request_method)
-+{
-+ /* HTTP/1.1 */
-+ HTTP_LONG_CONSTANT("HTTP_METH_GET", HTTP_GET);
-+ HTTP_LONG_CONSTANT("HTTP_METH_HEAD", HTTP_HEAD);
-+ HTTP_LONG_CONSTANT("HTTP_METH_POST", HTTP_POST);
-+ HTTP_LONG_CONSTANT("HTTP_METH_PUT", HTTP_PUT);
-+ HTTP_LONG_CONSTANT("HTTP_METH_DELETE", HTTP_DELETE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_OPTIONS", HTTP_OPTIONS);
-+ HTTP_LONG_CONSTANT("HTTP_METH_TRACE", HTTP_TRACE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_CONNECT", HTTP_CONNECT);
-+ /* WebDAV - RFC 2518 */
-+ HTTP_LONG_CONSTANT("HTTP_METH_PROPFIND", HTTP_PROPFIND);
-+ HTTP_LONG_CONSTANT("HTTP_METH_PROPPATCH", HTTP_PROPPATCH);
-+ HTTP_LONG_CONSTANT("HTTP_METH_MKCOL", HTTP_MKCOL);
-+ HTTP_LONG_CONSTANT("HTTP_METH_COPY", HTTP_COPY);
-+ HTTP_LONG_CONSTANT("HTTP_METH_MOVE", HTTP_MOVE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_LOCK", HTTP_LOCK);
-+ HTTP_LONG_CONSTANT("HTTP_METH_UNLOCK", HTTP_UNLOCK);
-+ /* WebDAV Versioning - RFC 3253 */
-+ HTTP_LONG_CONSTANT("HTTP_METH_VERSION_CONTROL", HTTP_VERSION_CONTROL);
-+ HTTP_LONG_CONSTANT("HTTP_METH_REPORT", HTTP_REPORT);
-+ HTTP_LONG_CONSTANT("HTTP_METH_CHECKOUT", HTTP_CHECKOUT);
-+ HTTP_LONG_CONSTANT("HTTP_METH_CHECKIN", HTTP_CHECKIN);
-+ HTTP_LONG_CONSTANT("HTTP_METH_UNCHECKOUT", HTTP_UNCHECKOUT);
-+ HTTP_LONG_CONSTANT("HTTP_METH_MKWORKSPACE", HTTP_MKWORKSPACE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_UPDATE", HTTP_UPDATE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_LABEL", HTTP_LABEL);
-+ HTTP_LONG_CONSTANT("HTTP_METH_MERGE", HTTP_MERGE);
-+ HTTP_LONG_CONSTANT("HTTP_METH_BASELINE_CONTROL", HTTP_BASELINE_CONTROL);
-+ HTTP_LONG_CONSTANT("HTTP_METH_MKACTIVITY", HTTP_MKACTIVITY);
-+ /* WebDAV Access Control - RFC 3744 */
-+ HTTP_LONG_CONSTANT("HTTP_METH_ACL", HTTP_ACL);
-+
-+ return SUCCESS;
-+}
-+
-+static void free_method(void *el)
-+{
-+ efree(*(char **)el);
-+}
-+
-+static void unregister_method(const char *name TSRMLS_DC)
-+{
-+ char *ptr, tmp[sizeof("HTTP_METH_") + HTTP_REQUEST_METHOD_MAXLEN] = "HTTP_METH_";
-+
-+ strlcpy(tmp + lenof("HTTP_METH_"), name, HTTP_REQUEST_METHOD_MAXLEN);
-+ for (ptr = tmp + lenof("HTTP_METH_"); *ptr; ++ptr) {
-+ if (*ptr == '-') {
-+ *ptr = '_';
-+ }
-+ }
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
-+ if (SUCCESS != zend_hash_del(&http_request_object_ce->constants_table, tmp + lenof("HTTP_"), strlen(tmp + lenof("HTTP_")) + 1)) {
-+ http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Could not unregister request method: HttpRequest::%s", tmp + lenof("HTTP_"));
-+ }
-+#endif
-+ if (SUCCESS != zend_hash_del(EG(zend_constants), tmp, strlen(tmp) + 1)) {
-+ http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Could not unregister request method: %s", tmp);
-+ }
-+}
-+
-+PHP_RINIT_FUNCTION(http_request_method)
-+{
-+ HashTable ht;
-+
-+ zend_hash_init(&HTTP_G->request.methods.registered, 0, NULL, free_method, 0);
-+#define HTTP_METH_REG(m) \
-+ { \
-+ char *_m=estrdup(m); \
-+ zend_hash_next_index_insert(&HTTP_G->request.methods.registered, (void *) &_m, sizeof(char *), NULL); \
-+ }
-+ HTTP_METH_REG("UNKNOWN");
-+ /* HTTP/1.1 */
-+ HTTP_METH_REG("GET");
-+ HTTP_METH_REG("HEAD");
-+ HTTP_METH_REG("POST");
-+ HTTP_METH_REG("PUT");
-+ HTTP_METH_REG("DELETE");
-+ HTTP_METH_REG("OPTIONS");
-+ HTTP_METH_REG("TRACE");
-+ HTTP_METH_REG("CONNECT");
-+ /* WebDAV - RFC 2518 */
-+ HTTP_METH_REG("PROPFIND");
-+ HTTP_METH_REG("PROPPATCH");
-+ HTTP_METH_REG("MKCOL");
-+ HTTP_METH_REG("COPY");
-+ HTTP_METH_REG("MOVE");
-+ HTTP_METH_REG("LOCK");
-+ HTTP_METH_REG("UNLOCK");
-+ /* WebDAV Versioning - RFC 3253 */
-+ HTTP_METH_REG("VERSION-CONTROL");
-+ HTTP_METH_REG("REPORT");
-+ HTTP_METH_REG("CHECKOUT");
-+ HTTP_METH_REG("CHECKIN");
-+ HTTP_METH_REG("UNCHECKOUT");
-+ HTTP_METH_REG("MKWORKSPACE");
-+ HTTP_METH_REG("UPDATE");
-+ HTTP_METH_REG("LABEL");
-+ HTTP_METH_REG("MERGE");
-+ HTTP_METH_REG("BASELINE-CONTROL");
-+ HTTP_METH_REG("MKACTIVITY");
-+ /* WebDAV Access Control - RFC 3744 */
-+ HTTP_METH_REG("ACL");
-+
-+ zend_hash_init(&ht, 0, NULL, ZVAL_PTR_DTOR, 0);
-+ if (*HTTP_G->request.methods.custom && SUCCESS == http_parse_params(HTTP_G->request.methods.custom, HTTP_PARAMS_DEFAULT, &ht)) {
-+ HashPosition pos;
-+ zval **val;
-+
-+ FOREACH_HASH_VAL(pos, &ht, val) {
-+ if (Z_TYPE_PP(val) == IS_STRING) {
-+ http_request_method_register(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
-+ }
-+ }
-+ }
-+ zend_hash_destroy(&ht);
-+
-+ return SUCCESS;
-+}
-+
-+PHP_RSHUTDOWN_FUNCTION(http_request_method)
-+{
-+ char **name;
-+ int i, c = zend_hash_next_free_element(&HTTP_G->request.methods.registered);
-+
-+ for (i = HTTP_MAX_REQUEST_METHOD; i < c; ++i) {
-+ if (SUCCESS == zend_hash_index_find(&HTTP_G->request.methods.registered, i, (void *) &name)) {
-+ unregister_method(*name TSRMLS_CC);
-+ }
-+ }
-+
-+ zend_hash_destroy(&HTTP_G->request.methods.registered);
-+ return SUCCESS;
-+}
-+
-+#define http_request_method_cncl(m, c) _http_request_method_cncl_ex((m), strlen(m), (c) TSRMLS_CC)
-+#define http_request_method_cncl_ex(m, l, c) _http_request_method_cncl_ex((m), (l), (c) TSRMLS_CC)
-+static STATUS _http_request_method_cncl_ex(const char *method_name, int method_name_len, char **cnst TSRMLS_DC)
-+{
-+ int i;
-+ char *cncl;
-+
-+ if (method_name_len >= HTTP_REQUEST_METHOD_MAXLEN) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Request method too long (%s)", method_name);
-+ }
-+ cncl = emalloc(method_name_len + 1);
-+
-+ for (i = 0; i < method_name_len; ++i) {
-+ switch (method_name[i]) {
-+ case '-':
-+ case '_':
-+ cncl[i] = method_name[i];
-+ break;
-+
-+ default:
-+ if (!HTTP_IS_CTYPE(alnum, method_name[i])) {
-+ efree(cncl);
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Request method contains illegal characters (%s)", method_name);
-+ return FAILURE;
-+ }
-+ cncl[i] = HTTP_TO_CTYPE(upper, method_name[i]);
-+ break;
-+ }
-+ }
-+ cncl[method_name_len] = '\0';
-+
-+ *cnst = cncl;
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API const char *_http_request_method_name(http_request_method m TSRMLS_DC)
-+{
-+ char **name;
-+
-+ if (SUCCESS == zend_hash_index_find(&HTTP_G->request.methods.registered, m, (void *) &name)) {
-+ return *name;
-+ }
-+ return "UNKNOWN";
-+}
-+
-+PHP_HTTP_API int _http_request_method_exists(int by_name, http_request_method id_num, const char *id_str TSRMLS_DC)
-+{
-+ char *id_dup;
-+
-+ if (by_name && (SUCCESS == http_request_method_cncl(id_str, &id_dup))) {
-+ char **name;
-+ HashPosition pos;
-+ HashKey key = initHashKey(0);
-+
-+ FOREACH_HASH_KEYVAL(pos, &HTTP_G->request.methods.registered, key, name) {
-+ if (key.type == HASH_KEY_IS_LONG && !strcmp(*name, id_dup)) {
-+ efree(id_dup);
-+ return key.num;
-+ }
-+ }
-+ efree(id_dup);
-+ } else if (zend_hash_index_exists(&HTTP_G->request.methods.registered, id_num)){
-+ return id_num;
-+ }
-+ return 0;
-+}
-+
-+PHP_HTTP_API int _http_request_method_register(const char *method_str, int method_len TSRMLS_DC)
-+{
-+ char *method_dup, *ptr, tmp[sizeof("HTTP_METH_") + HTTP_REQUEST_METHOD_MAXLEN] = "HTTP_METH_";
-+ int method_num = http_request_method_exists(1, 0, method_str);
-+
-+ if (!method_num && (SUCCESS == http_request_method_cncl_ex(method_str, method_len, &method_dup))) {
-+ method_num = zend_hash_next_free_element(&HTTP_G->request.methods.registered);
-+ zend_hash_index_update(&HTTP_G->request.methods.registered, method_num, (void *) &method_dup, sizeof(char *), NULL);
-+
-+ strlcpy(tmp + lenof("HTTP_METH_"), method_dup, HTTP_REQUEST_METHOD_MAXLEN);
-+ for (ptr = tmp + lenof("HTTP_METH_"); *ptr; ++ptr) {
-+ if (*ptr == '-') {
-+ *ptr = '_';
-+ }
-+ }
-+
-+ zend_register_long_constant(tmp, strlen(tmp) + 1, method_num, CONST_CS, http_module_number TSRMLS_CC);
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
-+ zend_declare_class_constant_long(http_request_object_ce, tmp + lenof("HTTP_"), strlen(tmp + lenof("HTTP_")), method_num TSRMLS_CC);
-+#endif
-+ }
-+
-+ return method_num;
-+}
-+
-+PHP_HTTP_API STATUS _http_request_method_unregister(int method TSRMLS_DC)
-+{
-+ char **name;
-+
-+ if (HTTP_STD_REQUEST_METHOD(method)) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Standard request methods cannot be unregistered");
-+ return FAILURE;
-+ }
-+
-+ if (SUCCESS != zend_hash_index_find(&HTTP_G->request.methods.registered, method, (void *) &name)) {
-+ http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Custom request method with id %d does not exist", method);
-+ return FAILURE;
-+ }
-+
-+ unregister_method(*name TSRMLS_CC);
-+
-+ zend_hash_index_del(&HTTP_G->request.methods.registered, method);
-+ return SUCCESS;
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_request_object.c
-@@ -0,0 +1,1931 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+
-+#include "zend_interfaces.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_cookie_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_message_api.h"
-+#include "php_http_message_object.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+#include "php_http_request_pool_api.h"
-+#include "php_http_url_api.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpRequest, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpRequest, method, 0)
-+#define HTTP_REQUEST_ME(method, visibility) PHP_ME(HttpRequest, method, HTTP_ARGS(HttpRequest, method), visibility)
-+#define HTTP_REQUEST_ALIAS(method, func) HTTP_STATIC_ME_ALIAS(method, func, HTTP_ARGS(HttpRequest, method))
-+#define HTTP_REQUEST_MALIAS(me, al, vis) ZEND_FENTRY(me, ZEND_MN(HttpRequest_##al), HTTP_ARGS(HttpRequest, al), vis)
-+
-+HTTP_BEGIN_ARGS(__construct, 0)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(method, 0)
-+ HTTP_ARG_VAL(options, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(method, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getOptions);
-+HTTP_BEGIN_ARGS(setOptions, 0)
-+ HTTP_ARG_VAL(options, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getSslOptions);
-+HTTP_BEGIN_ARGS(setSslOptions, 0)
-+ HTTP_ARG_VAL(ssl_options, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addSslOptions, 0)
-+ HTTP_ARG_VAL(ssl_optins, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getHeaders);
-+HTTP_BEGIN_ARGS(setHeaders, 0)
-+ HTTP_ARG_VAL(headers, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addHeaders, 1)
-+ HTTP_ARG_VAL(headers, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getCookies);
-+HTTP_BEGIN_ARGS(setCookies, 0)
-+ HTTP_ARG_VAL(cookies, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addCookies, 1)
-+ HTTP_ARG_VAL(cookies, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(enableCookies);
-+HTTP_BEGIN_ARGS(resetCookies, 0)
-+ HTTP_ARG_VAL(session_only, 0)
-+HTTP_END_ARGS;
-+HTTP_EMPTY_ARGS(flushCookies);
-+
-+HTTP_EMPTY_ARGS(getUrl);
-+HTTP_BEGIN_ARGS(setUrl, 1)
-+ HTTP_ARG_VAL(url, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getMethod);
-+HTTP_BEGIN_ARGS(setMethod, 1)
-+ HTTP_ARG_VAL(request_method, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getContentType);
-+HTTP_BEGIN_ARGS(setContentType, 1)
-+ HTTP_ARG_VAL(content_type, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getQueryData);
-+HTTP_BEGIN_ARGS(setQueryData, 0)
-+ HTTP_ARG_VAL(query_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addQueryData, 1)
-+ HTTP_ARG_VAL(query_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getPostFields);
-+HTTP_BEGIN_ARGS(setPostFields, 0)
-+ HTTP_ARG_VAL(post_fields, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addPostFields, 1)
-+ HTTP_ARG_VAL(post_fields, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getPostFiles);
-+HTTP_BEGIN_ARGS(setPostFiles, 0)
-+ HTTP_ARG_VAL(post_files, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addPostFile, 2)
-+ HTTP_ARG_VAL(formname, 0)
-+ HTTP_ARG_VAL(filename, 0)
-+ HTTP_ARG_VAL(content_type, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getBody);
-+HTTP_BEGIN_ARGS(setBody, 0)
-+ HTTP_ARG_VAL(request_body_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addBody, 1)
-+ HTTP_ARG_VAL(request_body_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getPutFile);
-+HTTP_BEGIN_ARGS(setPutFile, 0)
-+ HTTP_ARG_VAL(filename, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getPutData);
-+HTTP_BEGIN_ARGS(setPutData, 0)
-+ HTTP_ARG_VAL(put_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(addPutData, 1)
-+ HTTP_ARG_VAL(put_data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getResponseData);
-+HTTP_BEGIN_ARGS(getResponseHeader, 0)
-+ HTTP_ARG_VAL(name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(getResponseCookies, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+ HTTP_ARG_VAL(allowed_extras, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getResponseBody);
-+HTTP_EMPTY_ARGS(getResponseCode);
-+HTTP_EMPTY_ARGS(getResponseStatus);
-+HTTP_BEGIN_ARGS(getResponseInfo, 0)
-+ HTTP_ARG_VAL(name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getMessageClass);
-+HTTP_BEGIN_ARGS(setMessageClass, 1)
-+ HTTP_ARG_VAL(message_class_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getResponseMessage);
-+HTTP_EMPTY_ARGS(getRawResponseMessage);
-+HTTP_EMPTY_ARGS(getRequestMessage);
-+HTTP_EMPTY_ARGS(getRawRequestMessage);
-+HTTP_EMPTY_ARGS(getHistory);
-+HTTP_EMPTY_ARGS(clearHistory);
-+HTTP_EMPTY_ARGS(send);
-+
-+HTTP_BEGIN_ARGS(get, 1)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(head, 1)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(postData, 2)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(data, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(postFields, 2)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(data, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(putData, 2)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(data, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(putFile, 2)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(file, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(putStream, 2)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(stream, 0)
-+ HTTP_ARG_VAL(options, 0)
-+ HTTP_ARG_VAL(info, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(methodRegister, 1)
-+ HTTP_ARG_VAL(method_name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(methodUnregister, 1)
-+ HTTP_ARG_VAL(method, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(methodName, 1)
-+ HTTP_ARG_VAL(method_id, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(methodExists, 1)
-+ HTTP_ARG_VAL(method, 0)
-+HTTP_END_ARGS;
-+
-+#ifdef HAVE_CURL_FORMGET
-+HTTP_BEGIN_ARGS(encodeBody, 2)
-+ HTTP_ARG_VAL(fields, 0)
-+ HTTP_ARG_VAL(files, 0)
-+HTTP_END_ARGS;
-+#endif
-+
-+#define THIS_CE http_request_object_ce
-+zend_class_entry *http_request_object_ce;
-+zend_function_entry http_request_object_fe[] = {
-+ HTTP_REQUEST_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+
-+ HTTP_REQUEST_ME(setOptions, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getOptions, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(setSslOptions, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getSslOptions, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addSslOptions, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(addHeaders, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getHeaders, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(setHeaders, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(addCookies, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getCookies, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(setCookies, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(enableCookies, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(resetCookies, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(flushCookies, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setMethod, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getMethod, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setUrl, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getUrl, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setContentType, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getContentType, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setQueryData, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getQueryData, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addQueryData, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setPostFields, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getPostFields, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addPostFields, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setBody, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getBody, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addBody, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_MALIAS(setRawPostData, setBody, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
-+ HTTP_REQUEST_MALIAS(getRawPostData, getBody, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
-+ HTTP_REQUEST_MALIAS(addRawPostData, addBody, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
-+
-+ HTTP_REQUEST_ME(setPostFiles, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addPostFile, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getPostFiles, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setPutFile, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getPutFile, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(setPutData, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getPutData, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(addPutData, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(send, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(getResponseData, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseHeader, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseCookies, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseCode, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseStatus, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseBody, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseInfo, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getResponseMessage, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getRawResponseMessage, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getRequestMessage, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getRawRequestMessage, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(getHistory, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(clearHistory, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(getMessageClass, ZEND_ACC_PUBLIC)
-+ HTTP_REQUEST_ME(setMessageClass, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQUEST_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+
-+ HTTP_REQUEST_ALIAS(get, http_get)
-+ HTTP_REQUEST_ALIAS(head, http_head)
-+ HTTP_REQUEST_ALIAS(postData, http_post_data)
-+ HTTP_REQUEST_ALIAS(postFields, http_post_fields)
-+ HTTP_REQUEST_ALIAS(putData, http_put_data)
-+ HTTP_REQUEST_ALIAS(putFile, http_put_file)
-+ HTTP_REQUEST_ALIAS(putStream, http_put_stream)
-+
-+ HTTP_REQUEST_ALIAS(methodRegister, http_request_method_register)
-+ HTTP_REQUEST_ALIAS(methodUnregister, http_request_method_unregister)
-+ HTTP_REQUEST_ALIAS(methodName, http_request_method_name)
-+ HTTP_REQUEST_ALIAS(methodExists, http_request_method_exists)
-+#ifdef HAVE_CURL_FORMGET
-+ HTTP_REQUEST_ALIAS(encodeBody, http_request_body_encode)
-+#endif
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_request_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_request_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpRequest, http_request_object, NULL, 0);
-+ http_request_object_handlers.clone_obj = _http_request_object_clone_obj;
-+
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("options")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("postFields")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("postFiles")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("responseInfo")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("responseMessage")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("responseCode")-1, 0, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("responseStatus")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("method")-1, HTTP_GET, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("url")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("contentType")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("requestBody")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("queryData")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("putFile")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("putData")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("history")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("recordHistory")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+ zend_declare_property_string(THIS_CE, ZEND_STRS("messageClass")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
-+
-+#ifndef WONKY
-+ /*
-+ * Request Method Constants
-+ */
-+ /* HTTP/1.1 */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_GET")-1, HTTP_GET TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_HEAD")-1, HTTP_HEAD TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_POST")-1, HTTP_POST TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_PUT")-1, HTTP_PUT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_DELETE")-1, HTTP_DELETE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_OPTIONS")-1, HTTP_OPTIONS TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_TRACE")-1, HTTP_TRACE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_CONNECT")-1, HTTP_CONNECT TSRMLS_CC);
-+ /* WebDAV - RFC 2518 */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_PROPFIND")-1, HTTP_PROPFIND TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_PROPPATCH")-1, HTTP_PROPPATCH TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_MKCOL")-1, HTTP_MKCOL TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_COPY")-1, HTTP_COPY TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_MOVE")-1, HTTP_MOVE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_LOCK")-1, HTTP_LOCK TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_UNLOCK")-1, HTTP_UNLOCK TSRMLS_CC);
-+ /* WebDAV Versioning - RFC 3253 */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_VERSION_CONTROL")-1, HTTP_VERSION_CONTROL TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_REPORT")-1, HTTP_REPORT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_CHECKOUT")-1, HTTP_CHECKOUT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_CHECKIN")-1, HTTP_CHECKIN TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_UNCHECKOUT")-1, HTTP_UNCHECKOUT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_MKWORKSPACE")-1, HTTP_MKWORKSPACE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_UPDATE")-1, HTTP_UPDATE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_LABEL")-1, HTTP_LABEL TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_MERGE")-1, HTTP_MERGE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_BASELINE_CONTROL")-1, HTTP_BASELINE_CONTROL TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_MKACTIVITY")-1, HTTP_MKACTIVITY TSRMLS_CC);
-+ /* WebDAV Access Control - RFC 3744 */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("METH_ACL")-1, HTTP_ACL TSRMLS_CC);
-+
-+ /*
-+ * HTTP Protocol Version Constants
-+ */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("VERSION_1_0")-1, CURL_HTTP_VERSION_1_0 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("VERSION_1_1")-1, CURL_HTTP_VERSION_1_1 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("VERSION_NONE")-1, CURL_HTTP_VERSION_NONE TSRMLS_CC); /* to be removed */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("VERSION_ANY")-1, CURL_HTTP_VERSION_NONE TSRMLS_CC);
-+
-+ /*
-+ * SSL Version Constants
-+ */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("SSL_VERSION_TLSv1")-1, CURL_SSLVERSION_TLSv1 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("SSL_VERSION_SSLv2")-1, CURL_SSLVERSION_SSLv2 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("SSL_VERSION_SSLv3")-1, CURL_SSLVERSION_SSLv3 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("SSL_VERSION_ANY")-1, CURL_SSLVERSION_DEFAULT TSRMLS_CC);
-+
-+ /*
-+ * DNS IPvX resolving
-+ */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("IPRESOLVE_V4")-1, CURL_IPRESOLVE_V4 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("IPRESOLVE_V6")-1, CURL_IPRESOLVE_V6 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("IPRESOLVE_ANY")-1, CURL_IPRESOLVE_WHATEVER TSRMLS_CC);
-+
-+ /*
-+ * Auth Constants
-+ */
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_BASIC")-1, CURLAUTH_BASIC TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_DIGEST")-1, CURLAUTH_DIGEST TSRMLS_CC);
-+#if HTTP_CURL_VERSION(7,19,3)
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_DIGEST_IE")-1, CURLAUTH_DIGEST_IE TSRMLS_CC);
-+#endif
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_NTLM")-1, CURLAUTH_NTLM TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_GSSNEG")-1, CURLAUTH_GSSNEGOTIATE TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("AUTH_ANY")-1, CURLAUTH_ANY TSRMLS_CC);
-+
-+ /*
-+ * Proxy Type Constants
-+ */
-+# if HTTP_CURL_VERSION(7,15,2)
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS4")-1, CURLPROXY_SOCKS4 TSRMLS_CC);
-+# endif
-+#if HTTP_CURL_VERSION(7,18,0)
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS4A")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS5_HOSTNAME")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
-+#endif
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_SOCKS5")-1, CURLPROXY_SOCKS5 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_HTTP")-1, CURLPROXY_HTTP TSRMLS_CC);
-+# if HTTP_CURL_VERSION(7,19,4)
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("PROXY_HTTP_1_0")-1, CURLPROXY_HTTP_1_0 TSRMLS_CC);
-+# endif
-+#endif /* WONKY */
-+
-+ /*
-+ * Post Redirection Constants
-+ */
-+#if HTTP_CURL_VERSION(7,19,1)
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("POSTREDIR_301")-1, CURL_REDIR_POST_301 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("POSTREDIR_302")-1, CURL_REDIR_POST_302 TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("POSTREDIR_ALL")-1, CURL_REDIR_POST_ALL TSRMLS_CC);
-+#endif
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_request_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_request_object_new_ex(zend_class_entry *ce, CURL *ch, http_request_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_request_object *o;
-+
-+ o = ecalloc(1, sizeof(http_request_object));
-+ o->zo.ce = ce;
-+ o->request = http_request_init_ex(NULL, ch, 0, NULL);
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_request_object, o);
-+ ov.handlers = &http_request_object_handlers;
-+
-+ return ov;
-+}
-+
-+zend_object_value _http_request_object_clone_obj(zval *this_ptr TSRMLS_DC)
-+{
-+ zend_object_value new_ov;
-+ http_request_object *new_obj;
-+ getObject(http_request_object, old_obj);
-+
-+ new_ov = http_request_object_new_ex(old_obj->zo.ce, NULL, &new_obj);
-+ if (old_obj->request->ch) {
-+ http_curl_init_ex(http_curl_copy(old_obj->request->ch), new_obj->request);
-+ }
-+
-+ zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
-+ phpstr_append(&new_obj->request->conv.request, old_obj->request->conv.request.data, old_obj->request->conv.request.used);
-+ phpstr_append(&new_obj->request->conv.response, old_obj->request->conv.response.data, old_obj->request->conv.response.used);
-+
-+ return new_ov;
-+}
-+
-+void _http_request_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_request_object *o = (http_request_object *) object;
-+
-+ http_request_free(&o->request);
-+ freeObject(o);
-+}
-+
-+#define http_request_object_check_request_content_type(t) _http_request_object_check_request_content_type((t) TSRMLS_CC)
-+static inline void _http_request_object_check_request_content_type(zval *this_ptr TSRMLS_DC)
-+{
-+ zval *ctype = zend_read_property(THIS_CE, getThis(), ZEND_STRS("contentType")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(ctype)) {
-+ zval **headers, *opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+
-+ if ( (Z_TYPE_P(opts) == IS_ARRAY) &&
-+ (SUCCESS == zend_hash_find(Z_ARRVAL_P(opts), "headers", sizeof("headers"), (void *) &headers)) &&
-+ (Z_TYPE_PP(headers) == IS_ARRAY)) {
-+ zval **ct_header;
-+
-+ /* only override if not already set */
-+ if ((SUCCESS != zend_hash_find(Z_ARRVAL_PP(headers), "Content-Type", sizeof("Content-Type"), (void *) &ct_header))) {
-+ add_assoc_stringl(*headers, "Content-Type", Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
-+ } else
-+ /* or not a string, zero length string or a string of spaces */
-+ if ((Z_TYPE_PP(ct_header) != IS_STRING) || !Z_STRLEN_PP(ct_header)) {
-+ add_assoc_stringl(*headers, "Content-Type", Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
-+ } else {
-+ int i, only_space = 1;
-+
-+ /* check for spaces only */
-+ for (i = 0; i < Z_STRLEN_PP(ct_header); ++i) {
-+ if (!HTTP_IS_CTYPE(space, Z_STRVAL_PP(ct_header)[i])) {
-+ only_space = 0;
-+ break;
-+ }
-+ }
-+ if (only_space) {
-+ add_assoc_stringl(*headers, "Content-Type", Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
-+ }
-+ }
-+ } else {
-+ zval *headers;
-+
-+ MAKE_STD_ZVAL(headers);
-+ array_init(headers);
-+ add_assoc_stringl(headers, "Content-Type", Z_STRVAL_P(ctype), Z_STRLEN_P(ctype), 1);
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addheaders", NULL, headers);
-+ zval_ptr_dtor(&headers);
-+ }
-+ }
-+}
-+
-+#define http_request_object_message(zo, msg) _http_request_object_message((zo), (msg) TSRMLS_CC)
-+static inline zend_object_value _http_request_object_message(zval *this_ptr, http_message *msg TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ zval *zcn = zend_read_property(THIS_CE, getThis(), ZEND_STRS("messageClass")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(zcn) && (SUCCESS == http_object_new(&ov, Z_STRVAL_P(zcn), Z_STRLEN_P(zcn), _http_message_object_new_ex, http_message_object_ce, msg, NULL))) {
-+ return ov;
-+ } else {
-+ return http_message_object_new_ex(http_message_object_ce, msg, NULL);
-+ }
-+}
-+
-+STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr TSRMLS_DC)
-+{
-+ STATUS status = SUCCESS;
-+ char *url = http_absolute_url(Z_STRVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("url")-1, 0 TSRMLS_CC)));
-+
-+ if (!url) {
-+ return FAILURE;
-+ }
-+
-+ http_request_reset(obj->request);
-+ obj->request->url = url;
-+ HTTP_CHECK_CURL_INIT(obj->request->ch, http_curl_init(obj->request), return FAILURE);
-+
-+ switch (obj->request->meth = Z_LVAL_P(zend_read_property(THIS_CE, getThis(), ZEND_STRS("method")-1, 0 TSRMLS_CC)))
-+ {
-+ case HTTP_GET:
-+ case HTTP_HEAD:
-+ break;
-+
-+ case HTTP_PUT:
-+ {
-+ zval *put_file = zend_read_property(THIS_CE, getThis(), ZEND_STRS("putFile")-1, 0 TSRMLS_CC);
-+
-+ http_request_object_check_request_content_type(getThis());
-+
-+ if (Z_STRLEN_P(put_file)) {
-+ php_stream_statbuf ssb;
-+ php_stream *stream = php_stream_open_wrapper_ex(Z_STRVAL_P(put_file), "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT);
-+
-+ if (stream && SUCCESS == php_stream_stat(stream, &ssb)) {
-+ obj->request->body = http_request_body_init_ex(obj->request->body, HTTP_REQUEST_BODY_UPLOADFILE, stream, ssb.sb.st_size, 1);
-+ } else {
-+ status = FAILURE;
-+ }
-+ } else {
-+ zval *put_data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("putData")-1, 0 TSRMLS_CC);
-+ obj->request->body = http_request_body_init_ex(obj->request->body, HTTP_REQUEST_BODY_CSTRING,
-+ estrndup(Z_STRVAL_P(put_data), Z_STRLEN_P(put_data)), Z_STRLEN_P(put_data), 1);
-+ }
-+ break;
-+ }
-+
-+ case HTTP_POST:
-+ default:
-+ {
-+ /* check for raw request body */
-+ zval *raw_data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(raw_data)) {
-+ http_request_object_check_request_content_type(getThis());
-+ obj->request->body = http_request_body_init_ex(obj->request->body, HTTP_REQUEST_BODY_CSTRING,
-+ estrndup(Z_STRVAL_P(raw_data), Z_STRLEN_P(raw_data)), Z_STRLEN_P(raw_data), 1);
-+ } else {
-+ zval *zfields = zend_read_property(THIS_CE, getThis(), ZEND_STRS("postFields")-1, 0 TSRMLS_CC), *zfiles = zend_read_property(THIS_CE, getThis(), ZEND_STRS("postFiles")-1, 0 TSRMLS_CC);
-+ HashTable *fields;
-+ HashTable *files;
-+
-+ fields = (Z_TYPE_P(zfields) == IS_ARRAY) ? Z_ARRVAL_P(zfields) : NULL;
-+ files = (Z_TYPE_P(zfiles) == IS_ARRAY) ? Z_ARRVAL_P(zfiles) : NULL;
-+
-+ if ((fields && zend_hash_num_elements(fields)) || (files && zend_hash_num_elements(files))) {
-+ if (!(obj->request->body = http_request_body_fill(obj->request->body, fields, files))) {
-+ status = FAILURE;
-+ }
-+ }
-+ }
-+ break;
-+ }
-+ }
-+
-+ if (status == SUCCESS) {
-+ zval *qdata = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryData")-1, 0 TSRMLS_CC);
-+ zval *options = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(qdata)) {
-+ if (!strchr(obj->request->url, '?')) {
-+ strlcat(obj->request->url, "?", HTTP_URL_MAXLEN);
-+ } else {
-+ strlcat(obj->request->url, "&", HTTP_URL_MAXLEN);
-+ }
-+ strlcat(obj->request->url, Z_STRVAL_P(qdata), HTTP_URL_MAXLEN);
-+ }
-+
-+ http_request_prepare(obj->request, Z_ARRVAL_P(options));
-+
-+ /* check if there's a onProgress method and add it as progress callback if one isn't already set */
-+ if (zend_hash_exists(&Z_OBJCE_P(getThis())->function_table, "onprogress", sizeof("onprogress"))) {
-+ zval **entry, *pcb;
-+
-+ if ( (Z_TYPE_P(options) != IS_ARRAY)
-+ || (SUCCESS != zend_hash_find(Z_ARRVAL_P(options), "onprogress", sizeof("onprogress"), (void *) &entry)
-+ || (!HTTP_IS_CALLABLE(*entry, 0, NULL)))) {
-+ MAKE_STD_ZVAL(pcb);
-+ array_init(pcb);
-+ ZVAL_ADDREF(getThis());
-+ add_next_index_zval(pcb, getThis());
-+ add_next_index_stringl(pcb, "onprogress", lenof("onprogress"), 1);
-+ http_request_set_progress_callback(obj->request, pcb);
-+ zval_ptr_dtor(&pcb);
-+ }
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this_ptr TSRMLS_DC)
-+{
-+ STATUS ret;
-+ zval *info;
-+ http_message *msg;
-+
-+ /* always fetch info */
-+ MAKE_STD_ZVAL(info);
-+ array_init(info);
-+ http_request_info(obj->request, Z_ARRVAL_P(info));
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("responseInfo")-1, info TSRMLS_CC);
-+ zval_ptr_dtor(&info);
-+
-+ /* parse response message */
-+ phpstr_fix(&obj->request->conv.request);
-+ phpstr_fix(&obj->request->conv.response);
-+
-+ if ((msg = http_message_parse(PHPSTR_VAL(&obj->request->conv.response), PHPSTR_LEN(&obj->request->conv.response)))) {
-+ zval *message;
-+
-+ if (i_zend_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
-+ zval *hist, *history = zend_read_property(THIS_CE, getThis(), ZEND_STRS("history")-1, 0 TSRMLS_CC);
-+ http_message *response = http_message_parse(PHPSTR_VAL(&obj->request->conv.response), PHPSTR_LEN(&obj->request->conv.response));
-+ http_message *request = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request));
-+
-+ MAKE_STD_ZVAL(hist);
-+ ZVAL_OBJVAL(hist, http_request_object_message(getThis(), http_message_interconnect(response, request)), 0);
-+ if (Z_TYPE_P(history) == IS_OBJECT) {
-+ http_message_object_prepend(hist, history);
-+ }
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("history")-1, hist TSRMLS_CC);
-+ zval_ptr_dtor(&hist);
-+ }
-+
-+ zend_update_property_long(THIS_CE, getThis(), ZEND_STRS("responseCode")-1, msg->http.info.response.code TSRMLS_CC);
-+ zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("responseStatus")-1, STR_PTR(msg->http.info.response.status) TSRMLS_CC);
-+
-+ MAKE_STD_ZVAL(message);
-+ ZVAL_OBJVAL(message, http_request_object_message(getThis(), msg), 0);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, message TSRMLS_CC);
-+ zval_ptr_dtor(&message);
-+
-+ ret = SUCCESS;
-+ } else {
-+ /* update properties with empty values*/
-+ zval *znull;
-+
-+ MAKE_STD_ZVAL(znull);
-+ ZVAL_NULL(znull);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, znull TSRMLS_CC);
-+ zval_ptr_dtor(&znull);
-+
-+ zend_update_property_long(THIS_CE, getThis(), ZEND_STRS("responseCode")-1, 0 TSRMLS_CC);
-+ zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("responseStatus")-1, "" TSRMLS_CC);
-+
-+ /* append request message to history */
-+ if (i_zend_is_true(zend_read_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, 0 TSRMLS_CC))) {
-+ http_message *request;
-+
-+ if ((request = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request)))) {
-+ zval *hist, *history = zend_read_property(THIS_CE, getThis(), ZEND_STRS("history")-1, 0 TSRMLS_CC);
-+
-+ MAKE_STD_ZVAL(hist);
-+ ZVAL_OBJVAL(hist, http_request_object_message(getThis(), request), 0);
-+ if (Z_TYPE_P(history) == IS_OBJECT) {
-+ http_message_object_prepend(hist, history);
-+ }
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("history")-1, hist TSRMLS_CC);
-+ zval_ptr_dtor(&hist);
-+ }
-+ }
-+
-+ ret = FAILURE;
-+ }
-+
-+ http_request_set_progress_callback(obj->request, NULL);
-+
-+ if (!EG(exception) && zend_hash_exists(&Z_OBJCE_P(getThis())->function_table, "onfinish", sizeof("onfinish"))) {
-+ zval *param;
-+
-+ MAKE_STD_ZVAL(param);
-+ ZVAL_BOOL(param, ret == SUCCESS);
-+ with_error_handling(EH_NORMAL, NULL) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "onfinish", NULL, param);
-+ } end_error_handling();
-+ zval_ptr_dtor(¶m);
-+ }
-+
-+ return ret;
-+}
-+#ifdef ZEND_ENGINE_2_4
-+# define APK_DC TSRMLS_DC
-+#else
-+# define APK_DC
-+#endif
-+static int apply_pretty_key(void *pDest APK_DC, int num_args, va_list args, zend_hash_key *hash_key)
-+{
-+ if (hash_key->arKey && hash_key->nKeyLength > 1) {
-+ hash_key->h = zend_hash_func(pretty_key(hash_key->arKey, hash_key->nKeyLength - 1, 1, 0), hash_key->nKeyLength);
-+ }
-+ return ZEND_HASH_APPLY_KEEP;
-+}
-+
-+#define http_request_object_set_options_subr(key, ow, pk) \
-+ _http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU, (key), sizeof(key), (ow), (pk))
-+static inline void _http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAMETERS, char *key, size_t len, int overwrite, int prettify_keys)
-+{
-+ zval *old_opts, *new_opts, *opts = NULL, **entry = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &opts)) {
-+ RETURN_FALSE;
-+ }
-+
-+ MAKE_STD_ZVAL(new_opts);
-+ array_init(new_opts);
-+ old_opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(old_opts) == IS_ARRAY) {
-+ array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts));
-+ }
-+
-+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(new_opts), key, len, (void *) &entry)) {
-+ if (overwrite) {
-+ zend_hash_clean(Z_ARRVAL_PP(entry));
-+ }
-+ if (opts && zend_hash_num_elements(Z_ARRVAL_P(opts))) {
-+ if (overwrite) {
-+ array_copy(Z_ARRVAL_P(opts), Z_ARRVAL_PP(entry));
-+ } else {
-+ array_join(Z_ARRVAL_P(opts), Z_ARRVAL_PP(entry), 0, prettify_keys ? ARRAY_JOIN_PRETTIFY : 0);
-+ }
-+ }
-+ } else if (opts) {
-+ if (prettify_keys) {
-+ zend_hash_apply_with_arguments(Z_ARRVAL_P(opts) HTTP_ZAPI_HASH_TSRMLS_CC, apply_pretty_key, 0, NULL);
-+ }
-+ ZVAL_ADDREF(opts);
-+ add_assoc_zval_ex(new_opts, key, len, opts);
-+ }
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("options")-1, new_opts TSRMLS_CC);
-+ zval_ptr_dtor(&new_opts);
-+
-+ RETURN_TRUE;
-+}
-+
-+#define http_request_object_get_options_subr(key) \
-+ _http_request_get_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU, (key), sizeof(key))
-+static inline void _http_request_get_options_subr(INTERNAL_FUNCTION_PARAMETERS, char *key, size_t len)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *opts, **options;
-+
-+ opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+ array_init(return_value);
-+
-+ if ( (Z_TYPE_P(opts) == IS_ARRAY) &&
-+ (SUCCESS == zend_hash_find(Z_ARRVAL_P(opts), key, len, (void *) &options))) {
-+ convert_to_array(*options);
-+ array_copy(Z_ARRVAL_PP(options), Z_ARRVAL_P(return_value));
-+ }
-+ }
-+}
-+
-+
-+/* ### USERLAND ### */
-+
-+/* {{{ proto void HttpRequest::__construct([string url[, int request_method = HTTP_METH_GET[, array options]]])
-+ Create a new HttpRequest object instance. */
-+PHP_METHOD(HttpRequest, __construct)
-+{
-+ char *URL = NULL;
-+ int URL_len;
-+ long meth = -1;
-+ zval *options = NULL;
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sla!", &URL, &URL_len, &meth, &options)) {
-+ if (URL) {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("url")-1, URL, URL_len TSRMLS_CC);
-+ }
-+ if (meth > -1) {
-+ zend_update_property_long(THIS_CE, getThis(), ZEND_STRS("method")-1, meth TSRMLS_CC);
-+ }
-+ if (options) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setoptions", NULL, options);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpRequest HttpRequest::factory([string url[, int request_method HTTP_METH_GET[, array options[, string class_name = "HttpRequest"]]]])
-+ Create a new HttpRequest object instance. */
-+PHP_METHOD(HttpRequest, factory)
-+{
-+ char *cn = NULL, *URL = NULL;
-+ int cl = 0, URL_len = 0;
-+ long meth = -1;
-+ zval *options = NULL;
-+ zend_object_value ov;
-+
-+ SET_EH_THROW_HTTP();
-+ if ( SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sla!s", &URL, &URL_len, &meth, &options, &cn, &cl) &&
-+ SUCCESS == http_object_new(&ov, cn, cl, _http_request_object_new_ex, http_request_object_ce, NULL, NULL)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ getThis() = return_value;
-+ if (URL) {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("url")-1, URL, URL_len TSRMLS_CC);
-+ }
-+ if (meth > -1) {
-+ zend_update_property_long(THIS_CE, getThis(), ZEND_STRS("method")-1, meth TSRMLS_CC);
-+ }
-+ if (options) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setoptions", NULL, options);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setOptions([array options])
-+ Set the request options to use. See http_get() for a full list of available options. */
-+PHP_METHOD(HttpRequest, setOptions)
-+{
-+ HashKey key = initHashKey(0);
-+ HashPosition pos;
-+ zval *opts = NULL, *old_opts, *new_opts, *add_opts, **opt;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
-+ RETURN_FALSE;
-+ }
-+
-+ MAKE_STD_ZVAL(new_opts);
-+ array_init(new_opts);
-+
-+ if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) {
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("options")-1, new_opts TSRMLS_CC);
-+ zval_ptr_dtor(&new_opts);
-+ RETURN_TRUE;
-+ }
-+
-+ MAKE_STD_ZVAL(add_opts);
-+ array_init(add_opts);
-+ /* some options need extra attention -- thus cannot use array_merge() directly */
-+ FOREACH_KEYVAL(pos, opts, key, opt) {
-+ if (key.type == HASH_KEY_IS_STRING) {
-+#define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s))
-+ if (KEYMATCH(key, "headers")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addheaders", NULL, *opt);
-+ } else if (KEYMATCH(key, "cookies")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addcookies", NULL, *opt);
-+ } else if (KEYMATCH(key, "ssl")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addssloptions", NULL, *opt);
-+ } else if (KEYMATCH(key, "url") || KEYMATCH(key, "uri")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "seturl", NULL, *opt);
-+ } else if (KEYMATCH(key, "method")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setmethod", NULL, *opt);
-+ } else if (KEYMATCH(key, "flushcookies")) {
-+ getObject(http_request_object, obj);
-+ if (i_zend_is_true(*opt)) {
-+ http_request_flush_cookies(obj->request);
-+ }
-+ } else if (KEYMATCH(key, "resetcookies")) {
-+ getObject(http_request_object, obj);
-+ http_request_reset_cookies(obj->request, (zend_bool) i_zend_is_true(*opt));
-+ } else if (KEYMATCH(key, "enablecookies")) {
-+ getObject(http_request_object, obj);
-+ http_request_enable_cookies(obj->request);
-+ } else if (KEYMATCH(key, "recordHistory")) {
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("recordHistory")-1, *opt TSRMLS_CC);
-+ } else if (KEYMATCH(key, "messageClass")) {
-+ zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setmessageclass", NULL, *opt);
-+ } else if (Z_TYPE_PP(opt) == IS_NULL) {
-+ old_opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(old_opts) == IS_ARRAY) {
-+ zend_hash_del(Z_ARRVAL_P(old_opts), key.str, key.len);
-+ }
-+ } else {
-+ ZVAL_ADDREF(*opt);
-+ add_assoc_zval_ex(add_opts, key.str, key.len, *opt);
-+ }
-+ }
-+ }
-+
-+ old_opts = zend_read_property(THIS_CE, getThis(), ZEND_STRS("options")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(old_opts) == IS_ARRAY) {
-+ array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts));
-+ }
-+ array_join(Z_ARRVAL_P(add_opts), Z_ARRVAL_P(new_opts), 0, 0);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("options")-1, new_opts TSRMLS_CC);
-+ zval_ptr_dtor(&new_opts);
-+ zval_ptr_dtor(&add_opts);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getOptions()
-+ Get currently set options. */
-+PHP_METHOD(HttpRequest, getOptions)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(options);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setSslOptions([array options])
-+ Set SSL options. */
-+PHP_METHOD(HttpRequest, setSslOptions)
-+{
-+ http_request_object_set_options_subr("ssl", 1, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addSslOptions(array options)
-+ Set additional SSL options. */
-+PHP_METHOD(HttpRequest, addSslOptions)
-+{
-+ http_request_object_set_options_subr("ssl", 0, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getSslOtpions()
-+ Get previously set SSL options. */
-+PHP_METHOD(HttpRequest, getSslOptions)
-+{
-+ http_request_object_get_options_subr("ssl");
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addHeaders(array headers)
-+ Add request header name/value pairs. */
-+PHP_METHOD(HttpRequest, addHeaders)
-+{
-+ http_request_object_set_options_subr("headers", 0, 1);
-+}
-+
-+/* {{{ proto bool HttpRequest::setHeaders([array headers])
-+ Set request header name/value pairs. */
-+PHP_METHOD(HttpRequest, setHeaders)
-+{
-+ http_request_object_set_options_subr("headers", 1, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getHeaders()
-+ Get previously set request headers. */
-+PHP_METHOD(HttpRequest, getHeaders)
-+{
-+ http_request_object_get_options_subr("headers");
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setCookies([array cookies])
-+ Set cookies. */
-+PHP_METHOD(HttpRequest, setCookies)
-+{
-+ http_request_object_set_options_subr("cookies", 1, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addCookies(array cookies)
-+ Add cookies. */
-+PHP_METHOD(HttpRequest, addCookies)
-+{
-+ http_request_object_set_options_subr("cookies", 0, 0);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getCookies()
-+ Get previously set cookies. */
-+PHP_METHOD(HttpRequest, getCookies)
-+{
-+ http_request_object_get_options_subr("cookies");
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::enableCookies()
-+ Enable automatic sending of received cookies. Note that customly set cookies will be sent anyway. */
-+PHP_METHOD(HttpRequest, enableCookies)
-+{
-+ NO_ARGS {
-+ getObject(http_request_object, obj);
-+ RETURN_SUCCESS(http_request_enable_cookies(obj->request));
-+ }
-+
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::resetCookies([bool session_only = FALSE])
-+ Reset all automatically received/sent cookies. Note that customly set cookies are not affected. */
-+PHP_METHOD(HttpRequest, resetCookies)
-+{
-+ zend_bool session_only = 0;
-+ getObject(http_request_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &session_only)) {
-+ RETURN_FALSE;
-+ }
-+ RETURN_SUCCESS(http_request_reset_cookies(obj->request, session_only));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::flushCookies()
-+ Flush internal cookies to the cookiestore file */
-+PHP_METHOD(HttpRequest, flushCookies)
-+{
-+ NO_ARGS {
-+ getObject(http_request_object, obj);
-+ RETURN_SUCCESS(http_request_flush_cookies(obj->request));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setUrl(string url)
-+ Set the request URL. */
-+PHP_METHOD(HttpRequest, setUrl)
-+{
-+ char *URL = NULL;
-+ int URL_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &URL, &URL_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("url")-1, URL, URL_len TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getUrl()
-+ Get the previously set request URL. */
-+PHP_METHOD(HttpRequest, getUrl)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(url);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setMethod(int request_method)
-+ Set the request method. */
-+PHP_METHOD(HttpRequest, setMethod)
-+{
-+ long meth;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &meth)) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_property_long(THIS_CE, getThis(), ZEND_STRS("method")-1, meth TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpRequest::getMethod()
-+ Get the previously set request method. */
-+PHP_METHOD(HttpRequest, getMethod)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(method);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setContentType(string content_type)
-+ Set the content type the post request should have. */
-+PHP_METHOD(HttpRequest, setContentType)
-+{
-+ char *ctype;
-+ int ct_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ctype, &ct_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (ct_len) {
-+ HTTP_CHECK_CONTENT_TYPE(ctype, RETURN_FALSE);
-+ }
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("contentType")-1, ctype, ct_len TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getContentType()
-+ Get the previously content type. */
-+PHP_METHOD(HttpRequest, getContentType)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(contentType);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setQueryData([mixed query_data])
-+ Set the URL query parameters to use, overwriting previously set query parameters. */
-+PHP_METHOD(HttpRequest, setQueryData)
-+{
-+ zval *qdata = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if ((!qdata) || Z_TYPE_P(qdata) == IS_NULL) {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, "", 0 TSRMLS_CC);
-+ } else if ((Z_TYPE_P(qdata) == IS_ARRAY) || (Z_TYPE_P(qdata) == IS_OBJECT)) {
-+ char *query_data = NULL;
-+
-+ if (SUCCESS != http_urlencode_hash(HASH_OF(qdata), &query_data)) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("queryData")-1, query_data TSRMLS_CC);
-+ efree(query_data);
-+ } else {
-+ zval *data = http_zsep(IS_STRING, qdata);
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, Z_STRVAL_P(data), Z_STRLEN_P(data) TSRMLS_CC);
-+ zval_ptr_dtor(&data);
-+ }
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getQueryData()
-+ Get the current query data in form of an urlencoded query string. */
-+PHP_METHOD(HttpRequest, getQueryData)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(queryData);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addQueryData(array query_params)
-+ Add parameters to the query parameter list, leaving previously set unchanged. */
-+PHP_METHOD(HttpRequest, addQueryData)
-+{
-+ zval *qdata, *old_qdata;
-+ char *query_data = NULL;
-+ size_t query_data_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &qdata)) {
-+ RETURN_FALSE;
-+ }
-+
-+ old_qdata = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryData")-1, 0 TSRMLS_CC);
-+
-+ if (SUCCESS != http_urlencode_hash_ex(HASH_OF(qdata), 1, Z_STRVAL_P(old_qdata), Z_STRLEN_P(old_qdata), &query_data, &query_data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, query_data, query_data_len TSRMLS_CC);
-+ efree(query_data);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addPostFields(array post_data)
-+ Adds POST data entries, leaving previously set unchanged, unless a post entry with the same name already exists. */
-+PHP_METHOD(HttpRequest, addPostFields)
-+{
-+ zval *post_data, *old_post, *new_post;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &post_data)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (zend_hash_num_elements(Z_ARRVAL_P(post_data))) {
-+ MAKE_STD_ZVAL(new_post);
-+ array_init(new_post);
-+ old_post = zend_read_property(THIS_CE, getThis(), ZEND_STRS("postFields")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(old_post) == IS_ARRAY) {
-+ array_copy(Z_ARRVAL_P(old_post), Z_ARRVAL_P(new_post));
-+ }
-+ array_join(Z_ARRVAL_P(post_data), Z_ARRVAL_P(new_post), 0, 0);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("postFields")-1, new_post TSRMLS_CC);
-+ zval_ptr_dtor(&new_post);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setPostFields([array post_data])
-+ Set the POST data entries, overwriting previously set POST data. */
-+PHP_METHOD(HttpRequest, setPostFields)
-+{
-+ zval *post, *post_data = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!", &post_data)) {
-+ RETURN_FALSE;
-+ }
-+
-+ MAKE_STD_ZVAL(post);
-+ array_init(post);
-+ if (post_data && zend_hash_num_elements(Z_ARRVAL_P(post_data))) {
-+ array_copy(Z_ARRVAL_P(post_data), Z_ARRVAL_P(post));
-+ }
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("postFields")-1, post TSRMLS_CC);
-+ zval_ptr_dtor(&post);
-+
-+ RETURN_TRUE;
-+}
-+/* }}}*/
-+
-+/* {{{ proto array HttpRequest::getPostFields()
-+ Get previously set POST data. */
-+PHP_METHOD(HttpRequest, getPostFields)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(postFields);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setBody([string request_body_data])
-+ Set request body to send, overwriting previously set request body. Don't forget to specify a content type. */
-+PHP_METHOD(HttpRequest, setBody)
-+{
-+ char *raw_data = NULL;
-+ int data_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &raw_data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!raw_data) {
-+ raw_data = "";
-+ }
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, raw_data, data_len TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addBody(string request_body_data)
-+ Add request body data, leaving previously set request body data unchanged. */
-+PHP_METHOD(HttpRequest, addBody)
-+{
-+ char *raw_data;
-+ int data_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &raw_data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (data_len) {
-+ zval *data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(data)) {
-+ Z_STRVAL_P(data) = erealloc(Z_STRVAL_P(data), (Z_STRLEN_P(data) += data_len) + 1);
-+ Z_STRVAL_P(data)[Z_STRLEN_P(data)] = '\0';
-+ memcpy(Z_STRVAL_P(data) + Z_STRLEN_P(data) - data_len, raw_data, data_len);
-+ } else {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("requestBody")-1, raw_data, data_len TSRMLS_CC);
-+ }
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getBody()
-+ Get previously set request body data. */
-+PHP_METHOD(HttpRequest, getBody)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(requestBody);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addPostFile(string name, string file[, string content_type = "application/x-octetstream"])
-+ Add a file to the POST request, leaving previously set files unchanged. */
-+PHP_METHOD(HttpRequest, addPostFile)
-+{
-+ zval *entry, *old_post, *new_post;
-+ char *name, *file, *type = NULL;
-+ int name_len, file_len, type_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &name, &name_len, &file, &file_len, &type, &type_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (type_len) {
-+ HTTP_CHECK_CONTENT_TYPE(type, RETURN_FALSE);
-+ } else {
-+ type = "application/x-octetstream";
-+ type_len = sizeof("application/x-octetstream") - 1;
-+ }
-+
-+ MAKE_STD_ZVAL(entry);
-+ array_init(entry);
-+
-+ add_assoc_stringl(entry, "name", name, name_len, 1);
-+ add_assoc_stringl(entry, "type", type, type_len, 1);
-+ add_assoc_stringl(entry, "file", file, file_len, 1);
-+
-+ MAKE_STD_ZVAL(new_post);
-+ array_init(new_post);
-+ old_post = zend_read_property(THIS_CE, getThis(), ZEND_STRS("postFiles")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(old_post) == IS_ARRAY) {
-+ array_copy(Z_ARRVAL_P(old_post), Z_ARRVAL_P(new_post));
-+ }
-+ add_next_index_zval(new_post, entry);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("postFiles")-1, new_post TSRMLS_CC);
-+ zval_ptr_dtor(&new_post);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setPostFiles([array post_files])
-+ Set files to post, overwriting previously set post files. */
-+PHP_METHOD(HttpRequest, setPostFiles)
-+{
-+ zval *files = NULL, *post;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!/", &files)) {
-+ RETURN_FALSE;
-+ }
-+
-+ MAKE_STD_ZVAL(post);
-+ array_init(post);
-+ if (files && (Z_TYPE_P(files) == IS_ARRAY)) {
-+ array_copy(Z_ARRVAL_P(files), Z_ARRVAL_P(post));
-+ }
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("postFiles")-1, post TSRMLS_CC);
-+ zval_ptr_dtor(&post);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getPostFiles()
-+ Get all previously added POST files. */
-+PHP_METHOD(HttpRequest, getPostFiles)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(postFiles);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setPutFile([string file])
-+ Set file to put. Affects only PUT requests. */
-+PHP_METHOD(HttpRequest, setPutFile)
-+{
-+ char *file = "";
-+ int file_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &file, &file_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("putFile")-1, file, file_len TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getPutFile()
-+ Get previously set put file. */
-+PHP_METHOD(HttpRequest, getPutFile)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(putFile);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::setPutData([string put_data])
-+ Set PUT data to send, overwriting previously set PUT data. */
-+PHP_METHOD(HttpRequest, setPutData)
-+{
-+ char *put_data = NULL;
-+ int data_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &put_data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (!put_data) {
-+ put_data = "";
-+ }
-+
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("putData")-1, put_data, data_len TSRMLS_CC);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequest::addPutData(string put_data)
-+ Add PUT data, leaving previously set PUT data unchanged. */
-+PHP_METHOD(HttpRequest, addPutData)
-+{
-+ char *put_data;
-+ int data_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &put_data, &data_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (data_len) {
-+ zval *data = zend_read_property(THIS_CE, getThis(), ZEND_STRS("putData")-1, 0 TSRMLS_CC);
-+
-+ if (Z_STRLEN_P(data)) {
-+ Z_STRVAL_P(data) = erealloc(Z_STRVAL_P(data), (Z_STRLEN_P(data) += data_len) + 1);
-+ Z_STRVAL_P(data)[Z_STRLEN_P(data)] = '\0';
-+ memcpy(Z_STRVAL_P(data) + Z_STRLEN_P(data) - data_len, put_data, data_len);
-+ } else {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("putData")-1, put_data, data_len TSRMLS_CC);
-+ }
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getPutData()
-+ Get previously set PUT data. */
-+PHP_METHOD(HttpRequest, getPutData)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(putData);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getResponseData()
-+ Get all response data after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseData)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ char *body;
-+ size_t body_len;
-+ zval *headers, *message = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC);
-+
-+ if (Z_TYPE_P(message) == IS_OBJECT) {
-+ getObjectEx(http_message_object, msg, message);
-+
-+ array_init(return_value);
-+
-+ MAKE_STD_ZVAL(headers);
-+ array_init(headers);
-+ zend_hash_copy(Z_ARRVAL_P(headers), &msg->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ add_assoc_zval(return_value, "headers", headers);
-+
-+ phpstr_data(PHPSTR(msg->message), &body, &body_len);
-+ add_assoc_stringl(return_value, "body", body, body_len, 0);
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed HttpRequest::getResponseHeader([string name])
-+ Get response header(s) after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseHeader)
-+{
-+ if (return_value_used) {
-+ zval *header;
-+ char *header_name = NULL;
-+ int header_len = 0;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &header_name, &header_len)) {
-+ zval *message = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC);
-+
-+ if (Z_TYPE_P(message) == IS_OBJECT) {
-+ getObjectEx(http_message_object, msg, message);
-+
-+ if (header_len) {
-+ if ((header = http_message_header_ex(msg->message, pretty_key(header_name, header_len, 1, 1), header_len + 1, 0))) {
-+ RETURN_ZVAL(header, 1, 1);
-+ }
-+ } else {
-+ array_init(return_value);
-+ zend_hash_copy(Z_ARRVAL_P(return_value), &msg->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+ return;
-+ }
-+ }
-+ }
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequest::getResponseCookies([int flags[, array allowed_extras]])
-+ Get response cookie(s) after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseCookies)
-+{
-+ if (return_value_used) {
-+ long flags = 0;
-+ zval *allowed_extras_array = NULL;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|la!", &flags, &allowed_extras_array)) {
-+ int i = 0;
-+ HashKey key = initHashKey(0);
-+ char **allowed_extras = NULL;
-+ zval **header = NULL, **entry = NULL, *message = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC);
-+ HashPosition pos, pos1, pos2;
-+
-+ if (Z_TYPE_P(message) == IS_OBJECT) {
-+ getObjectEx(http_message_object, msg, message);
-+
-+ array_init(return_value);
-+
-+ if (allowed_extras_array) {
-+ allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
-+ FOREACH_VAL(pos, allowed_extras_array, entry) {
-+ zval *data = http_zsep(IS_STRING, *entry);
-+ allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
-+ zval_ptr_dtor(&data);
-+ }
-+ }
-+
-+ FOREACH_HASH_KEYVAL(pos1, &msg->message->hdrs, key, header) {
-+ if (key.type == HASH_KEY_IS_STRING && !strcasecmp(key.str, "Set-Cookie")) {
-+ http_cookie_list list;
-+
-+ if (Z_TYPE_PP(header) == IS_ARRAY) {
-+ zval **single_header;
-+
-+ FOREACH_VAL(pos2, *header, single_header) {
-+ zval *data = http_zsep(IS_STRING, *single_header);
-+
-+ if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
-+ zval *cookie;
-+
-+ MAKE_STD_ZVAL(cookie);
-+ object_init(cookie);
-+ http_cookie_list_tostruct(&list, cookie);
-+ add_next_index_zval(return_value, cookie);
-+ http_cookie_list_dtor(&list);
-+ }
-+ zval_ptr_dtor(&data);
-+ }
-+ } else {
-+ zval *data = http_zsep(IS_STRING, *header);
-+ if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
-+ zval *cookie;
-+
-+ MAKE_STD_ZVAL(cookie);
-+ object_init(cookie);
-+ http_cookie_list_tostruct(&list, cookie);
-+ add_next_index_zval(return_value, cookie);
-+ http_cookie_list_dtor(&list);
-+ }
-+ zval_ptr_dtor(&data);
-+ }
-+ }
-+ }
-+
-+ if (allowed_extras) {
-+ for (i = 0; allowed_extras[i]; ++i) {
-+ efree(allowed_extras[i]);
-+ }
-+ efree(allowed_extras);
-+ }
-+
-+ return;
-+ }
-+ }
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getResponseBody()
-+ Get the response body after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseBody)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *message = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC);
-+
-+ if (Z_TYPE_P(message) == IS_OBJECT) {
-+ getObjectEx(http_message_object, msg, message);
-+ RETURN_PHPSTR_DUP(&msg->message->body);
-+ } else {
-+ RETURN_FALSE;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpRequest::getResponseCode()
-+ Get the response code after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseCode)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(responseCode);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getResponseStatus()
-+ Get the response status (i.e. the string after the response code) after the message has been sent. */
-+PHP_METHOD(HttpRequest, getResponseStatus)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP(responseStatus);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed HttpRequest::getResponseInfo([string name])
-+ Get response info after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseInfo)
-+{
-+ if (return_value_used) {
-+ zval *info, **infop;
-+ char *info_name = NULL;
-+ int info_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &info_name, &info_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ info = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseInfo")-1, 0 TSRMLS_CC);
-+
-+ if (Z_TYPE_P(info) != IS_ARRAY) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (info_len && info_name) {
-+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(info), pretty_key(info_name, info_len, 0, 0), info_len + 1, (void *) &infop)) {
-+ RETURN_ZVAL(*infop, 1, 0);
-+ } else {
-+ http_error_ex(HE_NOTICE, HTTP_E_INVALID_PARAM, "Could not find response info named %s", info_name);
-+ RETURN_FALSE;
-+ }
-+ } else {
-+ RETURN_ZVAL(info, 1, 0);
-+ }
-+ }
-+}
-+/* }}}*/
-+
-+/* {{{ proto HttpMessage HttpRequest::getResponseMessage()
-+ Get the full response as HttpMessage object after the request has been sent. */
-+PHP_METHOD(HttpRequest, getResponseMessage)
-+{
-+ NO_ARGS {
-+ zval *message;
-+
-+ SET_EH_THROW_HTTP();
-+ message = zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(message) == IS_OBJECT) {
-+ RETVAL_OBJECT(message, 1);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "HttpRequest does not contain a response message");
-+ }
-+ SET_EH_NORMAL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpRequest::getRequestMessage()
-+ Get sent HTTP message. */
-+PHP_METHOD(HttpRequest, getRequestMessage)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ http_message *msg;
-+ getObject(http_request_object, obj);
-+
-+ SET_EH_THROW_HTTP();
-+ if ((msg = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request)))) {
-+ RETVAL_OBJVAL(http_request_object_message(getThis(), msg), 0);
-+ }
-+ SET_EH_NORMAL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getRawRequestMessage()
-+ Get sent HTTP message. */
-+PHP_METHOD(HttpRequest, getRawRequestMessage)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_request_object, obj);
-+
-+ RETURN_PHPSTR_DUP(&obj->request->conv.request);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getRawResponseMessage()
-+ Get the entire HTTP response. */
-+PHP_METHOD(HttpRequest, getRawResponseMessage)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_request_object, obj);
-+
-+ RETURN_PHPSTR_DUP(&obj->request->conv.response);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpRequest::getHistory()
-+ Get all sent requests and received responses as an HttpMessage object. */
-+PHP_METHOD(HttpRequest, getHistory)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *hist;
-+
-+ SET_EH_THROW_HTTP();
-+ hist = zend_read_property(THIS_CE, getThis(), ZEND_STRS("history")-1, 0 TSRMLS_CC);
-+ if (Z_TYPE_P(hist) == IS_OBJECT) {
-+ RETVAL_OBJECT(hist, 1);
-+ } else {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "The history is empty");
-+ }
-+ SET_EH_NORMAL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpRequest::clearHistory()
-+ Clear the history. */
-+PHP_METHOD(HttpRequest, clearHistory)
-+{
-+ NO_ARGS {
-+ zval *hist;
-+
-+ MAKE_STD_ZVAL(hist);
-+ ZVAL_NULL(hist);
-+ zend_update_property(THIS_CE, getThis(), ZEND_STRS("history")-1, hist TSRMLS_CC);
-+ zval_ptr_dtor(&hist);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto string HttpRequest::getMessageClass()
-+ Get the message class name. */
-+PHP_METHOD(HttpRequest, getMessageClass)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ RETURN_PROP("messageClass");
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void setMessageClass(string class_name)
-+ Set the message class name. */
-+PHP_METHOD(HttpRequest, setMessageClass)
-+{
-+ char *cn;
-+ int cl;
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cn, &cl)) {
-+ zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("messageClass")-1, cn, cl TSRMLS_CC);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpMessage HttpRequest::send()
-+ Send the HTTP request. */
-+PHP_METHOD(HttpRequest, send)
-+{
-+ getObject(http_request_object, obj);
-+
-+ NO_ARGS;
-+
-+ SET_EH_THROW_HTTP();
-+
-+ RETVAL_FALSE;
-+
-+ if (obj->pool) {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot perform HttpRequest::send() while attached to an HttpRequestPool");
-+ } else if (SUCCESS == http_request_object_requesthandler(obj, getThis())) {
-+ http_request_exec(obj->request);
-+ if (SUCCESS == http_request_object_responsehandler(obj, getThis())) {
-+ RETVAL_OBJECT(zend_read_property(THIS_CE, getThis(), ZEND_STRS("responseMessage")-1, 0 TSRMLS_CC), 1);
-+ }
-+ }
-+
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_request_pool_api.c
-@@ -0,0 +1,660 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_request_pool_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#define HTTP_WANT_EVENT
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+
-+#include "php_http_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_persistent_handle_api.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+#include "php_http_request_pool_api.h"
-+#include "php_http_requestpool_object.h"
-+
-+#ifndef HTTP_DEBUG_REQPOOLS
-+# define HTTP_DEBUG_REQPOOLS 0
-+#endif
-+
-+#ifdef HTTP_HAVE_EVENT
-+typedef struct _http_request_pool_event_t {
-+ struct event evnt;
-+ http_request_pool *pool;
-+} http_request_pool_event;
-+
-+static void http_request_pool_timeout_callback(int socket, short action, void *event_data);
-+static void http_request_pool_event_callback(int socket, short action, void *event_data);
-+static int http_request_pool_socket_callback(CURL *easy, curl_socket_t s, int action, void *, void *);
-+static void http_request_pool_timer_callback(CURLM *multi, long timeout_ms, void *timer_data);
-+#endif
-+
-+static int http_request_pool_compare_handles(void *h1, void *h2);
-+
-+PHP_MINIT_FUNCTION(http_request_pool)
-+{
-+ if (SUCCESS != http_persistent_handle_provide("http_request_pool", curl_multi_init, (http_persistent_handle_dtor) curl_multi_cleanup, NULL)) {
-+ return FAILURE;
-+ }
-+ return SUCCESS;
-+}
-+
-+#ifdef HTTP_HAVE_EVENT
-+PHP_RINIT_FUNCTION(http_request_pool)
-+{
-+ if (!HTTP_G->request.pool.event.base && !(HTTP_G->request.pool.event.base = event_init())) {
-+ return FAILURE;
-+ }
-+
-+ return SUCCESS;
-+}
-+#endif
-+
-+/* {{{ http_request_pool *http_request_pool_init(http_request_pool *) */
-+PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool TSRMLS_DC)
-+{
-+ zend_bool free_pool;
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Initializing request pool %p\n", pool);
-+#endif
-+
-+ if ((free_pool = (!pool))) {
-+ pool = emalloc(sizeof(http_request_pool));
-+ pool->ch = NULL;
-+ }
-+
-+ if (SUCCESS != http_persistent_handle_acquire("http_request_pool", &pool->ch)) {
-+ if (free_pool) {
-+ efree(pool);
-+ }
-+ return NULL;
-+ }
-+
-+ TSRMLS_SET_CTX(pool->tsrm_ls);
-+
-+#ifdef HTTP_HAVE_EVENT
-+ pool->timeout = ecalloc(1, sizeof(struct event));
-+ curl_multi_setopt(pool->ch, CURLMOPT_SOCKETDATA, pool);
-+ curl_multi_setopt(pool->ch, CURLMOPT_SOCKETFUNCTION, http_request_pool_socket_callback);
-+ curl_multi_setopt(pool->ch, CURLMOPT_TIMERDATA, pool);
-+ curl_multi_setopt(pool->ch, CURLMOPT_TIMERFUNCTION, http_request_pool_timer_callback);
-+#endif
-+
-+ pool->unfinished = 0;
-+ zend_llist_init(&pool->finished, sizeof(zval *), (llist_dtor_func_t) ZVAL_PTR_DTOR, 0);
-+ zend_llist_init(&pool->handles, sizeof(zval *), (llist_dtor_func_t) ZVAL_PTR_DTOR, 0);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Initialized request pool %p\n", pool);
-+#endif
-+
-+ return pool;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_pool_attach(http_request_pool *, zval *) */
-+PHP_HTTP_API STATUS _http_request_pool_attach(http_request_pool *pool, zval *request)
-+{
-+#ifdef ZTS
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+#endif
-+ getObjectEx(http_request_object, req, request);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Attaching HttpRequest(#%d) %p to pool %p\n", Z_OBJ_HANDLE_P(request), req, pool);
-+#endif
-+
-+ if (req->pool) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "HttpRequest object(#%d) is already member of %s HttpRequestPool", Z_OBJ_HANDLE_P(request), req->pool == pool ? "this" : "another");
-+ } else if (SUCCESS != http_request_object_requesthandler(req, request)) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not initialize HttpRequest object(#%d) for attaching to the HttpRequestPool", Z_OBJ_HANDLE_P(request));
-+ } else {
-+ CURLMcode code = curl_multi_add_handle(pool->ch, req->request->ch);
-+
-+ if (CURLM_OK != code) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_POOL, "Could not attach HttpRequest object(#%d) to the HttpRequestPool: %s", Z_OBJ_HANDLE_P(request), curl_multi_strerror(code));
-+ } else {
-+ req->pool = pool;
-+
-+ ZVAL_ADDREF(request);
-+ zend_llist_add_element(&pool->handles, &request);
-+ ++pool->unfinished;
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "> %d HttpRequests attached to pool %p\n", zend_llist_count(&pool->handles), pool);
-+#endif
-+ return SUCCESS;
-+ }
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_pool_detach(http_request_pool *, zval *) */
-+PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *request)
-+{
-+ CURLMcode code;
-+#ifdef ZTS
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+#endif
-+ getObjectEx(http_request_object, req, request);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Detaching HttpRequest(#%d) %p from pool %p\n", Z_OBJ_HANDLE_P(request), req, pool);
-+#endif
-+
-+ if (!req->pool) {
-+ /* not attached to any pool */
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "HttpRequest object(#%d) %p is not attached to any HttpRequestPool\n", Z_OBJ_HANDLE_P(request), req);
-+#endif
-+ } else if (req->pool != pool) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "HttpRequest object(#%d) is not attached to this HttpRequestPool", Z_OBJ_HANDLE_P(request));
-+ } else if (req->request->_in_progress_cb) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_POOL, "HttpRequest object(#%d) cannot be detached from the HttpRequestPool while executing the progress callback", Z_OBJ_HANDLE_P(request));
-+ } else if (CURLM_OK != (code = curl_multi_remove_handle(pool->ch, req->request->ch))) {
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST_POOL, "Could not detach HttpRequest object(#%d) from the HttpRequestPool: %s", Z_OBJ_HANDLE_P(request), curl_multi_strerror(code));
-+ } else {
-+ req->pool = NULL;
-+ zend_llist_del_element(&pool->finished, request, http_request_pool_compare_handles);
-+ zend_llist_del_element(&pool->handles, request, http_request_pool_compare_handles);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "> %d HttpRequests remaining in pool %p\n", zend_llist_count(&pool->handles), pool);
-+#endif
-+
-+ return SUCCESS;
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_pool_apply(http_request_pool *, http_request_pool_apply_func) */
-+PHP_HTTP_API void _http_request_pool_apply(http_request_pool *pool, http_request_pool_apply_func cb)
-+{
-+ int count = zend_llist_count(&pool->handles);
-+
-+ if (count) {
-+ int i = 0;
-+ zend_llist_position pos;
-+ zval **handle, **handles = emalloc(count * sizeof(zval *));
-+
-+ for (handle = zend_llist_get_first_ex(&pool->handles, &pos); handle; handle = zend_llist_get_next_ex(&pool->handles, &pos)) {
-+ handles[i++] = *handle;
-+ }
-+
-+ /* should never happen */
-+ if (i != count) {
-+ zend_error(E_ERROR, "number of fetched request handles do not match overall count");
-+ count = i;
-+ }
-+
-+ for (i = 0; i < count; ++i) {
-+ if (cb(pool, handles[i])) {
-+ break;
-+ }
-+ }
-+ efree(handles);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_pool_apply_with_arg(http_request_pool *, http_request_pool_apply_with_arg_func, void *) */
-+PHP_HTTP_API void _http_request_pool_apply_with_arg(http_request_pool *pool, http_request_pool_apply_with_arg_func cb, void *arg)
-+{
-+ int count = zend_llist_count(&pool->handles);
-+
-+ if (count) {
-+ int i = 0;
-+ zend_llist_position pos;
-+ zval **handle, **handles = emalloc(count * sizeof(zval *));
-+
-+ for (handle = zend_llist_get_first_ex(&pool->handles, &pos); handle; handle = zend_llist_get_next_ex(&pool->handles, &pos)) {
-+ handles[i++] = *handle;
-+ }
-+
-+ /* should never happen */
-+ if (i != count) {
-+ zend_error(E_ERROR, "number of fetched request handles do not match overall count");
-+ count = i;
-+ }
-+
-+ for (i = 0; i < count; ++i) {
-+ if (cb(pool, handles[i], arg)) {
-+ break;
-+ }
-+ }
-+ efree(handles);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_pool_detach_all(http_request_pool *) */
-+PHP_HTTP_API void _http_request_pool_detach_all(http_request_pool *pool)
-+{
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Detaching %d requests from pool %p\n", zend_llist_count(&pool->handles), pool);
-+#endif
-+ http_request_pool_apply(pool, _http_request_pool_detach);
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_pool_send(http_request_pool *) */
-+PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool)
-+{
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Attempt to send %d requests of pool %p\n", zend_llist_count(&pool->handles), pool);
-+#endif
-+
-+#ifdef HTTP_HAVE_EVENT
-+ if (pool->useevents) {
-+ do {
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "& Starting event dispatcher of pool %p\n", pool);
-+#endif
-+ event_base_dispatch(HTTP_G->request.pool.event.base);
-+ } while (pool->unfinished);
-+ } else
-+#endif
-+ {
-+ while (http_request_pool_perform(pool)) {
-+ if (SUCCESS != http_request_pool_select(pool)) {
-+#ifdef PHP_WIN32
-+ /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */
-+ http_error_ex(HE_WARNING, HTTP_E_SOCKET, "WinSock error: %d", WSAGetLastError());
-+#else
-+ http_error(HE_WARNING, HTTP_E_SOCKET, strerror(errno));
-+#endif
-+ return FAILURE;
-+ }
-+ }
-+ }
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Finished sending %d HttpRequests of pool %p (still unfinished: %d)\n", zend_llist_count(&pool->handles), pool, pool->unfinished);
-+#endif
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_pool_dtor(http_request_pool *) */
-+PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool)
-+{
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Destructing request pool %p\n", pool);
-+#endif
-+
-+#ifdef HTTP_HAVE_EVENT
-+ efree(pool->timeout);
-+#endif
-+
-+ http_request_pool_detach_all(pool);
-+
-+ pool->unfinished = 0;
-+ zend_llist_clean(&pool->finished);
-+ zend_llist_clean(&pool->handles);
-+ http_persistent_handle_release("http_request_pool", &pool->ch);
-+}
-+/* }}} */
-+
-+#ifdef PHP_WIN32
-+# define SELECT_ERROR SOCKET_ERROR
-+#else
-+# define SELECT_ERROR -1
-+#endif
-+
-+/* {{{ STATUS http_request_pool_select(http_request_pool *) */
-+PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool)
-+{
-+ return http_request_pool_select_ex(pool, NULL);
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_request_pool_select_ex(http_request_pool *, struct timeval *) */
-+PHP_HTTP_API STATUS _http_request_pool_select_ex(http_request_pool *pool, struct timeval *custom_timeout)
-+{
-+ int MAX;
-+ fd_set R, W, E;
-+ struct timeval timeout;
-+
-+#ifdef HTTP_HAVE_EVENT
-+ if (pool->useevents) {
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "not implemented; use HttpRequest callbacks");
-+ return FAILURE;
-+ }
-+#endif
-+
-+ if (custom_timeout && timerisset(custom_timeout)) {
-+ timeout = *custom_timeout;
-+ } else {
-+ http_request_pool_timeout(pool, &timeout);
-+ }
-+
-+ FD_ZERO(&R);
-+ FD_ZERO(&W);
-+ FD_ZERO(&E);
-+
-+ if (CURLM_OK == curl_multi_fdset(pool->ch, &R, &W, &E, &MAX)) {
-+ if (MAX == -1) {
-+ http_sleep((double) timeout.tv_sec + (double) (timeout.tv_usec / HTTP_MCROSEC));
-+ return SUCCESS;
-+ } else if (SELECT_ERROR != select(MAX + 1, &R, &W, &E, &timeout)) {
-+ return SUCCESS;
-+ }
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ int http_request_pool_perform(http_request_pool *) */
-+PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool)
-+{
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+#ifdef HTTP_HAVE_EVENT
-+ if (pool->useevents) {
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "not implemented; use HttpRequest callbacks");
-+ return FAILURE;
-+ }
-+#endif
-+
-+ while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(pool->ch, &pool->unfinished));
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "%u unfinished requests of pool %p remaining\n", pool->unfinished, pool);
-+#endif
-+
-+ http_request_pool_responsehandler(pool);
-+
-+ return pool->unfinished;
-+}
-+/* }}} */
-+
-+/* {{{ void http_request_pool_responsehandler(http_request_pool *) */
-+void _http_request_pool_responsehandler(http_request_pool *pool)
-+{
-+ CURLMsg *msg;
-+ int remaining = 0;
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+ do {
-+ msg = curl_multi_info_read(pool->ch, &remaining);
-+ if (msg && CURLMSG_DONE == msg->msg) {
-+ if (CURLE_OK != msg->data.result) {
-+ http_request_storage *st = http_request_storage_get(msg->easy_handle);
-+ http_error_ex(HE_WARNING, HTTP_E_REQUEST, "%s; %s (%s)", curl_easy_strerror(msg->data.result), st?st->errorbuffer:"", st?st->url:"");
-+ }
-+ http_request_pool_apply_with_arg(pool, _http_request_pool_apply_responsehandler, msg->easy_handle);
-+ }
-+ } while (remaining);
-+}
-+/* }}} */
-+
-+/* {{{ int http_request_pool_apply_responsehandler(http_request_pool *, zval *, void *) */
-+int _http_request_pool_apply_responsehandler(http_request_pool *pool, zval *req, void *ch)
-+{
-+#ifdef ZTS
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+#endif
-+ getObjectEx(http_request_object, obj, req);
-+
-+ if ((!ch) || obj->request->ch == (CURL *) ch) {
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Fetching data from HttpRequest(#%d) %p of pool %p\n", Z_OBJ_HANDLE_P(req), obj, obj->pool);
-+#endif
-+
-+ ZVAL_ADDREF(req);
-+ zend_llist_add_element(&obj->pool->finished, &req);
-+ http_request_object_responsehandler(obj, req);
-+ return 1;
-+ }
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ struct timeval *_http_request_pool_timeout(http_request_pool *, struct timeval *) */
-+struct timeval *_http_request_pool_timeout(http_request_pool *pool, struct timeval *timeout)
-+{
-+#ifdef HAVE_CURL_MULTI_TIMEOUT
-+ long max_tout = 1000;
-+
-+ if ((CURLM_OK == curl_multi_timeout(pool->ch, &max_tout)) && (max_tout > 0)) {
-+ timeout->tv_sec = max_tout / 1000;
-+ timeout->tv_usec = (max_tout % 1000) * 1000;
-+ } else {
-+#endif
-+ timeout->tv_sec = 0;
-+ timeout->tv_usec = 1000;
-+#ifdef HAVE_CURL_MULTI_TIMEOUT
-+ }
-+#endif
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Calculating timeout (%lu, %lu) of pool %p\n", (ulong) timeout->tv_sec, (ulong) timeout->tv_usec, pool);
-+#endif
-+
-+ return timeout;
-+}
-+/* }}} */
-+
-+/*#*/
-+
-+/* {{{ static int http_request_pool_compare_handles(void *, void *) */
-+static int http_request_pool_compare_handles(void *h1, void *h2)
-+{
-+ return (Z_OBJ_HANDLE_PP((zval **) h1) == Z_OBJ_HANDLE_P((zval *) h2));
-+}
-+/* }}} */
-+
-+#ifdef HTTP_HAVE_EVENT
-+/* {{{ static void http_request_pool_timeout_callback(int, short, void *) */
-+static void http_request_pool_timeout_callback(int socket, short action, void *event_data)
-+{
-+ http_request_pool *pool = event_data;
-+
-+ if (pool->useevents) {
-+ CURLMcode rc;
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Timeout occurred of pool %p\n", pool);
-+#endif
-+
-+ while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket(pool->ch, CURL_SOCKET_TIMEOUT, &pool->unfinished)));
-+
-+ if (CURLM_OK != rc) {
-+ http_error(HE_WARNING, HTTP_E_SOCKET, curl_multi_strerror(rc));
-+ }
-+
-+ http_request_pool_responsehandler(pool);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ static void http_request_pool_event_callback(int, short, void *) */
-+static void http_request_pool_event_callback(int socket, short action, void *event_data)
-+{
-+ http_request_pool_event *ev = event_data;
-+ http_request_pool *pool = ev->pool;
-+
-+ if (pool->useevents) {
-+ CURLMcode rc = CURLE_OK;
-+ TSRMLS_FETCH_FROM_CTX(ev->pool->tsrm_ls);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ {
-+ static const char event_strings[][20] = {"NONE","TIMEOUT","READ","TIMEOUT|READ","WRITE","TIMEOUT|WRITE","READ|WRITE","TIMEOUT|READ|WRITE","SIGNAL"};
-+ fprintf(stderr, "Event on socket %d (%s) event %p of pool %p\n", socket, event_strings[action], ev, pool);
-+ }
-+#endif
-+
-+ /* don't use 'ev' below this loop as it might 've been freed in the socket callback */
-+ do {
-+#ifdef HAVE_CURL_MULTI_SOCKET_ACTION
-+ switch (action & (EV_READ|EV_WRITE)) {
-+ case EV_READ:
-+ rc = curl_multi_socket_action(pool->ch, socket, CURL_CSELECT_IN, &pool->unfinished);
-+ break;
-+ case EV_WRITE:
-+ rc = curl_multi_socket_action(pool->ch, socket, CURL_CSELECT_OUT, &pool->unfinished);
-+ break;
-+ case EV_READ|EV_WRITE:
-+ rc = curl_multi_socket_action(pool->ch, socket, CURL_CSELECT_IN|CURL_CSELECT_OUT, &pool->unfinished);
-+ break;
-+ default:
-+ http_error_ex(HE_WARNING, HTTP_E_SOCKET, "Unknown event %d", (int) action);
-+ return;
-+ }
-+#else
-+ rc = curl_multi_socket(pool->ch, socket, &pool->unfinished);
-+#endif
-+ } while (CURLM_CALL_MULTI_PERFORM == rc);
-+
-+ switch (rc) {
-+ case CURLM_BAD_SOCKET:
-+#if 0
-+ fprintf(stderr, "!!! Bad socket: %d (%d)\n", socket, (int) action);
-+#endif
-+ case CURLM_OK:
-+ break;
-+ default:
-+ http_error(HE_WARNING, HTTP_E_SOCKET, curl_multi_strerror(rc));
-+ break;
-+ }
-+
-+ http_request_pool_responsehandler(pool);
-+
-+ /* remove timeout if there are no transfers left */
-+ if (!pool->unfinished && event_initialized(pool->timeout) && event_pending(pool->timeout, EV_TIMEOUT, NULL)) {
-+ event_del(pool->timeout);
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Removed timeout of pool %p\n", pool);
-+#endif
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ static int http_request_pool_socket_callback(CURL *, curl_socket_t, int, void *, void *) */
-+static int http_request_pool_socket_callback(CURL *easy, curl_socket_t sock, int action, void *socket_data, void *assign_data)
-+{
-+ http_request_pool *pool = socket_data;
-+
-+ if (pool->useevents) {
-+ int events = EV_PERSIST;
-+ http_request_pool_event *ev = assign_data;
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+
-+ if (!ev) {
-+ ev = ecalloc(1, sizeof(http_request_pool_event));
-+ ev->pool = pool;
-+ curl_multi_assign(pool->ch, sock, ev);
-+ event_base_set(HTTP_G->request.pool.event.base, &ev->evnt);
-+ } else {
-+ event_del(&ev->evnt);
-+ }
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ {
-+ static const char action_strings[][8] = {"NONE", "IN", "OUT", "INOUT", "REMOVE"};
-+ http_request *r;
-+ curl_easy_getinfo(easy, CURLINFO_PRIVATE, &r);
-+ fprintf(stderr, "Callback on socket %2d (%8s) event %p of pool %p (%d)\n", (int) sock, action_strings[action], ev, pool, pool->unfinished);
-+ }
-+#endif
-+
-+ switch (action) {
-+ case CURL_POLL_IN:
-+ events |= EV_READ;
-+ break;
-+ case CURL_POLL_OUT:
-+ events |= EV_WRITE;
-+ break;
-+ case CURL_POLL_INOUT:
-+ events |= EV_READ|EV_WRITE;
-+ break;
-+
-+ case CURL_POLL_REMOVE:
-+ efree(ev);
-+ case CURL_POLL_NONE:
-+ return 0;
-+
-+ default:
-+ http_error_ex(HE_WARNING, HTTP_E_SOCKET, "Unknown socket action %d", action);
-+ return -1;
-+ }
-+
-+ event_set(&ev->evnt, sock, events, http_request_pool_event_callback, ev);
-+ event_add(&ev->evnt, NULL);
-+ }
-+
-+ return 0;
-+}
-+/* }}} */
-+
-+/* {{{ static void http_request_pool_timer_callback(CURLM *, long, void*) */
-+static void http_request_pool_timer_callback(CURLM *multi, long timeout_ms, void *timer_data)
-+{
-+ http_request_pool *pool = timer_data;
-+
-+ if (pool->useevents) {
-+ TSRMLS_FETCH_FROM_CTX(pool->tsrm_ls);
-+ struct timeval timeout;
-+
-+ if (!event_initialized(pool->timeout)) {
-+ event_set(pool->timeout, -1, 0, http_request_pool_timeout_callback, pool);
-+ event_base_set(HTTP_G->request.pool.event.base, pool->timeout);
-+ } else if (event_pending(pool->timeout, EV_TIMEOUT, NULL)) {
-+ event_del(pool->timeout);
-+ }
-+
-+ if (timeout_ms > 0) {
-+ timeout.tv_sec = timeout_ms / 1000;
-+ timeout.tv_usec = (timeout_ms % 1000) * 1000;
-+ } else {
-+ http_request_pool_timeout(pool, &timeout);
-+ }
-+
-+ event_add(pool->timeout, &timeout);
-+
-+#if HTTP_DEBUG_REQPOOLS
-+ fprintf(stderr, "Updating timeout %lu (%lu, %lu) of pool %p\n", (ulong) timeout_ms, (ulong) timeout.tv_sec, (ulong) timeout.tv_usec, pool);
-+#endif
-+ }
-+}
-+/* }}} */
-+#endif /* HTTP_HAVE_EVENT */
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_requestdatashare_object.c
-@@ -0,0 +1,332 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_requestdatashare_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+
-+#include "zend_interfaces.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+#include "php_http_request_datashare_api.h"
-+#include "php_http_requestdatashare_object.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpRequestDataShare, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpRequestDataShare, method, 0)
-+#define HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpRequestDataShare, method, HTTP_ARGS(HttpRequestDataShare, method), visibility)
-+
-+#if defined(HAVE_SPL) && !defined(WONKY)
-+/* SPL doesn't install its headers */
-+extern PHPAPI zend_class_entry *spl_ce_Countable;
-+#endif
-+
-+HTTP_EMPTY_ARGS(__destruct);
-+HTTP_EMPTY_ARGS(count);
-+
-+HTTP_BEGIN_ARGS(attach, 1)
-+ HTTP_ARG_OBJ(HttpRequest, request, 0)
-+HTTP_END_ARGS;
-+HTTP_BEGIN_ARGS(detach, 1)
-+ HTTP_ARG_OBJ(HttpRequest, request, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(reset);
-+
-+HTTP_BEGIN_ARGS(factory, 0)
-+ HTTP_ARG_VAL(global, 0)
-+ HTTP_ARG_VAL(class_name, 0)
-+HTTP_END_ARGS;
-+
-+#ifndef WONKY
-+HTTP_BEGIN_ARGS(singleton, 0)
-+ HTTP_ARG_VAL(global, 0)
-+HTTP_END_ARGS;
-+#endif
-+
-+
-+#define http_requestdatashare_object_read_prop _http_requestdatashare_object_read_prop
-+static zval *_http_requestdatashare_object_read_prop(zval *object, zval *member, int type ZEND_LITERAL_KEY_DC TSRMLS_DC);
-+#define http_requestdatashare_object_write_prop _http_requestdatashare_object_write_prop
-+static void _http_requestdatashare_object_write_prop(zval *object, zval *member, zval *value ZEND_LITERAL_KEY_DC TSRMLS_DC);
-+#define http_requestdatashare_instantiate(t, g) _http_requestdatashare_instantiate((t), (g) TSRMLS_CC)
-+static inline zval *_http_requestdatashare_instantiate(zval *this_ptr, zend_bool global TSRMLS_DC);
-+
-+#define THIS_CE http_requestdatashare_object_ce
-+zend_class_entry *http_requestdatashare_object_ce;
-+zend_function_entry http_requestdatashare_object_fe[] = {
-+ HTTP_RSHARE_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
-+ HTTP_RSHARE_ME(count, ZEND_ACC_PUBLIC)
-+ HTTP_RSHARE_ME(attach, ZEND_ACC_PUBLIC)
-+ HTTP_RSHARE_ME(detach, ZEND_ACC_PUBLIC)
-+ HTTP_RSHARE_ME(reset, ZEND_ACC_PUBLIC)
-+ HTTP_RSHARE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+#ifndef WONKY
-+ HTTP_RSHARE_ME(singleton, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-+#endif
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_requestdatashare_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_requestdatashare_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpRequestDataShare, http_requestdatashare_object, NULL, 0);
-+ http_requestdatashare_object_handlers.clone_obj = NULL;
-+ http_requestdatashare_object_handlers.read_property = http_requestdatashare_object_read_prop;
-+ http_requestdatashare_object_handlers.write_property = http_requestdatashare_object_write_prop;
-+
-+#if defined(HAVE_SPL) && !defined(WONKY)
-+ zend_class_implements(http_requestdatashare_object_ce TSRMLS_CC, 1, spl_ce_Countable);
-+#endif
-+
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("instance")-1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("cookie")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("dns")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("ssl")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("connect")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_requestdatashare_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ return http_requestdatashare_object_new_ex(ce, NULL, NULL);
-+}
-+
-+zend_object_value _http_requestdatashare_object_new_ex(zend_class_entry *ce, http_request_datashare *share, http_requestdatashare_object **ptr TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_requestdatashare_object *o;
-+
-+ o = ecalloc(1, sizeof(http_requestdatashare_object));
-+ o->zo.ce = ce;
-+
-+ if (share) {
-+ o->share = share;
-+ } else {
-+ o->share = http_request_datashare_new();
-+ }
-+
-+ if (ptr) {
-+ *ptr = o;
-+ }
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_requestdatashare_object, o);
-+ ov.handlers = &http_requestdatashare_object_handlers;
-+
-+ return ov;
-+}
-+
-+void _http_requestdatashare_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_requestdatashare_object *o = (http_requestdatashare_object *) object;
-+
-+ if (!o->share->persistent) {
-+ http_request_datashare_free(&o->share);
-+ }
-+ freeObject(o);
-+}
-+
-+static zval *_http_requestdatashare_object_read_prop(zval *object, zval *member, int type ZEND_LITERAL_KEY_DC TSRMLS_DC)
-+{
-+ if (type == BP_VAR_W &&
-+#ifdef ZEND_ENGINE_2_4
-+ zend_hash_exists(&THIS_CE->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
-+#else
-+ zend_hash_exists(&THIS_CE->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
-+#endif
-+ ) {
-+ zend_error(E_ERROR, "Cannot access HttpRequestDataShare default properties by reference or array key/index");
-+ return NULL;
-+ }
-+
-+ return zend_get_std_object_handlers()->read_property(object, member, type ZEND_LITERAL_KEY_CC TSRMLS_CC);
-+}
-+
-+static void _http_requestdatashare_object_write_prop(zval *object, zval *member, zval *value ZEND_LITERAL_KEY_DC TSRMLS_DC)
-+{
-+ if (
-+#ifdef ZEND_ENGINE_2_4
-+ zend_hash_exists(&THIS_CE->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
-+#else
-+ zend_hash_exists(&THIS_CE->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
-+#endif
-+ ) {
-+ int status;
-+ getObjectEx(http_requestdatashare_object, obj, object);
-+
-+ status = http_request_datashare_set(obj->share, Z_STRVAL_P(member), Z_STRLEN_P(member), (zend_bool) i_zend_is_true(value));
-+ if (SUCCESS != status) {
-+ return;
-+ }
-+ }
-+
-+ zend_get_std_object_handlers()->write_property(object, member, value ZEND_LITERAL_KEY_CC TSRMLS_CC);
-+}
-+
-+/* {{{ proto void HttpRequestDataShare::__destruct()
-+ Clean up HttpRequestDataShare object. */
-+PHP_METHOD(HttpRequestDataShare, __destruct)
-+{
-+ NO_ARGS {
-+ getObject(http_requestdatashare_object, obj);
-+ http_request_datashare_detach_all(obj->share);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpRequestDataShare::count()
-+ Implements Countable::count(). */
-+PHP_METHOD(HttpRequestDataShare, count)
-+{
-+ getObject(http_requestdatashare_object, obj);
-+
-+ NO_ARGS;
-+
-+ RETURN_LONG(zend_llist_count(HTTP_RSHARE_HANDLES(obj->share)));
-+}
-+/* }}} */
-+
-+PHP_METHOD(HttpRequestDataShare, attach)
-+{
-+ zval *request;
-+ getObject(http_requestdatashare_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_request_datashare_attach(obj->share, request));
-+}
-+
-+PHP_METHOD(HttpRequestDataShare, detach)
-+{
-+ zval *request;
-+ getObject(http_requestdatashare_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(http_request_datashare_detach(obj->share, request));
-+}
-+
-+PHP_METHOD(HttpRequestDataShare, reset)
-+{
-+ NO_ARGS {
-+ getObject(http_requestdatashare_object, obj);
-+ http_request_datashare_detach_all(obj->share);
-+ }
-+}
-+
-+PHP_METHOD(HttpRequestDataShare, factory)
-+{
-+ zend_bool global = 0;
-+ char *cn = NULL;
-+ int cl = 0;
-+ zend_object_value ov;
-+
-+ SET_EH_THROW_HTTP();
-+ if ( SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &global, &cn, &cl) &&
-+ SUCCESS == http_object_new(&ov, cn, cl, _http_requestdatashare_object_new_ex, http_requestdatashare_object_ce, NULL, NULL)) {
-+ RETVAL_OBJVAL(ov, 0);
-+ http_requestdatashare_instantiate(return_value, global);
-+ }
-+ SET_EH_NORMAL();
-+}
-+
-+#ifndef WONKY
-+/* {{{ proto static HttpRequestDataShare HttpRequestDataShare::singleton([bool global = false])
-+ Get a single instance (differentiates between the global setting). */
-+PHP_METHOD(HttpRequestDataShare, singleton)
-+{
-+ zend_bool global = 0;
-+ zval *instance = *zend_std_get_static_property(THIS_CE, ZEND_STRS("instance")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &global)) {
-+ zval **zobj_ptr = NULL, *zobj = NULL;
-+
-+ if (Z_TYPE_P(instance) == IS_ARRAY) {
-+ if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(instance), global, (void *) &zobj_ptr)) {
-+ RETVAL_ZVAL(*zobj_ptr, 1, 0);
-+ } else {
-+ zobj = http_requestdatashare_instantiate(NULL, global);
-+ add_index_zval(instance, global, zobj);
-+ RETVAL_OBJECT(zobj, 1);
-+ }
-+ } else {
-+ MAKE_STD_ZVAL(instance);
-+ array_init(instance);
-+
-+ zobj = http_requestdatashare_instantiate(NULL, global);
-+ add_index_zval(instance, global, zobj);
-+ RETVAL_OBJECT(zobj, 1);
-+
-+ zend_update_static_property(THIS_CE, ZEND_STRS("instance")-1, instance TSRMLS_CC);
-+ zval_ptr_dtor(&instance);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+#endif /* !WONKY */
-+
-+static inline zval *_http_requestdatashare_instantiate(zval *this_ptr, zend_bool global TSRMLS_DC)
-+{
-+ if (!this_ptr) {
-+ MAKE_STD_ZVAL(this_ptr);
-+ Z_TYPE_P(this_ptr) = IS_OBJECT;
-+ this_ptr->value.obj = http_requestdatashare_object_new_ex(http_requestdatashare_object_ce, global ? http_request_datashare_global_get() : NULL, NULL);
-+ }
-+ if (global) {
-+ if (HTTP_G->request.datashare.cookie) {
-+ zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("cookie")-1, HTTP_G->request.datashare.cookie TSRMLS_CC);
-+ }
-+ if (HTTP_G->request.datashare.dns) {
-+ zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("dns")-1, HTTP_G->request.datashare.dns TSRMLS_CC);
-+ }
-+ if (HTTP_G->request.datashare.ssl) {
-+ zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("ssl")-1, HTTP_G->request.datashare.ssl TSRMLS_CC);
-+ }
-+ if (HTTP_G->request.datashare.connect) {
-+ zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("connect")-1, HTTP_G->request.datashare.connect TSRMLS_CC);
-+ }
-+ }
-+ return this_ptr;
-+}
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_requestpool_object.c
-@@ -0,0 +1,471 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_requestpool_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_CURL
-+#include "php_http.h"
-+
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+
-+#include "zend_interfaces.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_request_api.h"
-+#include "php_http_request_object.h"
-+#include "php_http_request_pool_api.h"
-+#include "php_http_requestpool_object.h"
-+
-+#if defined(HAVE_SPL) && !defined(WONKY)
-+/* SPL doesn't install its headers */
-+extern PHPAPI zend_class_entry *spl_ce_Countable;
-+#endif
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpRequestPool, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpRequestPool, method, 0)
-+#define HTTP_REQPOOL_ME(method, visibility) PHP_ME(HttpRequestPool, method, HTTP_ARGS(HttpRequestPool, method), visibility)
-+
-+HTTP_EMPTY_ARGS(__construct);
-+
-+HTTP_EMPTY_ARGS(__destruct);
-+HTTP_EMPTY_ARGS(reset);
-+
-+HTTP_BEGIN_ARGS(attach, 1)
-+ HTTP_ARG_OBJ(HttpRequest, request, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(detach, 1)
-+ HTTP_ARG_OBJ(HttpRequest, request, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(send);
-+HTTP_EMPTY_ARGS(socketPerform);
-+HTTP_BEGIN_ARGS(socketSelect, 0)
-+ HTTP_ARG_VAL(timeout, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(valid);
-+HTTP_EMPTY_ARGS(current);
-+HTTP_EMPTY_ARGS(key);
-+HTTP_EMPTY_ARGS(next);
-+HTTP_EMPTY_ARGS(rewind);
-+
-+HTTP_EMPTY_ARGS(count);
-+
-+HTTP_EMPTY_ARGS(getAttachedRequests);
-+HTTP_EMPTY_ARGS(getFinishedRequests);
-+
-+HTTP_BEGIN_ARGS(enablePipelining, 0)
-+ HTTP_ARG_VAL(enable, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(enableEvents, 0)
-+ HTTP_ARG_VAL(enable, 0)
-+HTTP_END_ARGS;
-+
-+zend_class_entry *http_requestpool_object_ce;
-+zend_function_entry http_requestpool_object_fe[] = {
-+ HTTP_REQPOOL_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-+ HTTP_REQPOOL_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
-+ HTTP_REQPOOL_ME(attach, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(detach, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(send, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(reset, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQPOOL_ME(socketPerform, ZEND_ACC_PROTECTED)
-+ HTTP_REQPOOL_ME(socketSelect, ZEND_ACC_PROTECTED)
-+
-+ /* implements Iterator */
-+ HTTP_REQPOOL_ME(valid, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(current, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(key, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(next, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(rewind, ZEND_ACC_PUBLIC)
-+
-+ /* implmenents Countable */
-+ HTTP_REQPOOL_ME(count, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQPOOL_ME(getAttachedRequests, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(getFinishedRequests, ZEND_ACC_PUBLIC)
-+
-+ HTTP_REQPOOL_ME(enablePipelining, ZEND_ACC_PUBLIC)
-+ HTTP_REQPOOL_ME(enableEvents, ZEND_ACC_PUBLIC)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+static zend_object_handlers http_requestpool_object_handlers;
-+
-+PHP_MINIT_FUNCTION(http_requestpool_object)
-+{
-+ HTTP_REGISTER_CLASS_EX(HttpRequestPool, http_requestpool_object, NULL, 0);
-+ http_requestpool_object_handlers.clone_obj = NULL;
-+
-+#if defined(HAVE_SPL) && !defined(WONKY)
-+ zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 2, spl_ce_Countable, zend_ce_iterator);
-+#else
-+ zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 1, zend_ce_iterator);
-+#endif
-+
-+ return SUCCESS;
-+}
-+
-+zend_object_value _http_requestpool_object_new(zend_class_entry *ce TSRMLS_DC)
-+{
-+ zend_object_value ov;
-+ http_requestpool_object *o;
-+
-+ o = ecalloc(1, sizeof(http_requestpool_object));
-+ o->zo.ce = ce;
-+
-+ http_request_pool_init(&o->pool);
-+
-+#ifdef ZEND_ENGINE_2_4
-+ zend_object_std_init(o, ce TSRMLS_CC);
-+ object_properties_init(o, ce);
-+#else
-+ ALLOC_HASHTABLE(OBJ_PROP(o));
-+ zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
-+ zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
-+#endif
-+
-+ ov.handle = putObject(http_requestpool_object, o);
-+ ov.handlers = &http_requestpool_object_handlers;
-+
-+ return ov;
-+}
-+
-+void _http_requestpool_object_free(zend_object *object TSRMLS_DC)
-+{
-+ http_requestpool_object *o = (http_requestpool_object *) object;
-+
-+ http_request_pool_dtor(&o->pool);
-+ freeObject(o);
-+}
-+
-+#define http_requestpool_object_llist2array _http_requestpool_object_llist2array
-+static void _http_requestpool_object_llist2array(zval **req, zval *array TSRMLS_DC)
-+{
-+ ZVAL_ADDREF(*req);
-+ add_next_index_zval(array, *req);
-+}
-+
-+/* ### USERLAND ### */
-+
-+/* {{{ proto void HttpRequestPool::__construct([HttpRequest request[, ...]])
-+ Creates a new HttpRequestPool object instance. */
-+PHP_METHOD(HttpRequestPool, __construct)
-+{
-+ int argc = ZEND_NUM_ARGS();
-+ zval ***argv = safe_emalloc(argc, sizeof(zval *), 0);
-+ getObject(http_requestpool_object, obj);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_get_parameters_array_ex(argc, argv)) {
-+ int i;
-+
-+ for (i = 0; i < argc; ++i) {
-+ if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), http_request_object_ce TSRMLS_CC)) {
-+ http_request_pool_attach(&obj->pool, *(argv[i]));
-+ }
-+ }
-+ }
-+ efree(argv);
-+ http_final(HTTP_EX_CE(request_pool));
-+ SET_EH_NORMAL();
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpRequestPool::__destruct()
-+ Clean up HttpRequestPool object. */
-+PHP_METHOD(HttpRequestPool, __destruct)
-+{
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ http_request_pool_detach_all(&obj->pool);
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpRequestPool::reset()
-+ Detach all attached HttpRequest objects. */
-+PHP_METHOD(HttpRequestPool, reset)
-+{
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ obj->iterator.pos = 0;
-+ http_request_pool_detach_all(&obj->pool);
-+}
-+
-+/* {{{ proto bool HttpRequestPool::attach(HttpRequest request)
-+ Attach an HttpRequest object to this HttpRequestPool. WARNING: set all options prior attaching! */
-+PHP_METHOD(HttpRequestPool, attach)
-+{
-+ zval *request;
-+ STATUS status = FAILURE;
-+ getObject(http_requestpool_object, obj);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
-+ if (obj->iterator.pos > 0 && obj->iterator.pos < zend_llist_count(&obj->pool.handles)) {
-+ http_error(HE_THROW, HTTP_E_REQUEST_POOL, "Cannot attach to the HttpRequestPool while the iterator is active");
-+ } else {
-+ status = http_request_pool_attach(&obj->pool, request);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+ RETURN_SUCCESS(status);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequestPool::detach(HttpRequest request)
-+ Detach an HttpRequest object from this HttpRequestPool. */
-+PHP_METHOD(HttpRequestPool, detach)
-+{
-+ zval *request;
-+ STATUS status = FAILURE;
-+ getObject(http_requestpool_object, obj);
-+
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
-+ obj->iterator.pos = -1;
-+ status = http_request_pool_detach(&obj->pool, request);
-+ }
-+ SET_EH_NORMAL();
-+ RETURN_SUCCESS(status);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequestPool::send()
-+ Send all attached HttpRequest objects in parallel. */
-+PHP_METHOD(HttpRequestPool, send)
-+{
-+ STATUS status;
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ SET_EH_THROW_HTTP();
-+ status = http_request_pool_send(&obj->pool);
-+ SET_EH_NORMAL();
-+
-+ /* rethrow as HttpRequestPoolException */
-+ http_final(HTTP_EX_CE(request_pool));
-+
-+ RETURN_SUCCESS(status);
-+}
-+/* }}} */
-+
-+/* {{{ proto protected bool HttpRequestPool::socketPerform()
-+ Returns TRUE until each request has finished its transaction. */
-+PHP_METHOD(HttpRequestPool, socketPerform)
-+{
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ if (0 < http_request_pool_perform(&obj->pool)) {
-+ RETURN_TRUE;
-+ } else {
-+ RETURN_FALSE;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto protected bool HttpRequestPool::socketSelect([double timeout]) */
-+PHP_METHOD(HttpRequestPool, socketSelect)
-+{
-+ double timeout = 0;
-+ struct timeval custom_timeout, *custom_timeout_ptr = NULL;
-+ getObject(http_requestpool_object, obj);
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|d", &timeout)) {
-+ RETURN_FALSE;
-+ }
-+ if (ZEND_NUM_ARGS() && timeout > 0) {
-+ custom_timeout.tv_sec = (time_t) timeout;
-+ custom_timeout.tv_usec = HTTP_USEC(timeout) % HTTP_MCROSEC;
-+ custom_timeout_ptr = &custom_timeout;
-+ }
-+
-+ RETURN_SUCCESS(http_request_pool_select_ex(&obj->pool, custom_timeout_ptr));
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequestPool::valid()
-+ Implements Iterator::valid(). */
-+PHP_METHOD(HttpRequestPool, valid)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_requestpool_object, obj);
-+ RETURN_BOOL(obj->iterator.pos >= 0 && obj->iterator.pos < zend_llist_count(&obj->pool.handles));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto HttpRequest HttpRequestPool::current()
-+ Implements Iterator::current(). */
-+PHP_METHOD(HttpRequestPool, current)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ long pos = 0;
-+ zval **current = NULL;
-+ zend_llist_position lpos;
-+ getObject(http_requestpool_object, obj);
-+
-+ if (obj->iterator.pos < zend_llist_count(&obj->pool.handles)) {
-+ for ( current = zend_llist_get_first_ex(&obj->pool.handles, &lpos);
-+ current && obj->iterator.pos != pos++;
-+ current = zend_llist_get_next_ex(&obj->pool.handles, &lpos));
-+ if (current) {
-+ RETURN_OBJECT(*current, 1);
-+ }
-+ }
-+ RETURN_NULL();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpRequestPool::key()
-+ Implements Iterator::key(). */
-+PHP_METHOD(HttpRequestPool, key)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ getObject(http_requestpool_object, obj);
-+ RETURN_LONG(obj->iterator.pos);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpRequestPool::next()
-+ Implements Iterator::next(). */
-+PHP_METHOD(HttpRequestPool, next)
-+{
-+ NO_ARGS {
-+ getObject(http_requestpool_object, obj);
-+ ++(obj->iterator.pos);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto void HttpRequestPool::rewind()
-+ Implements Iterator::rewind(). */
-+PHP_METHOD(HttpRequestPool, rewind)
-+{
-+ NO_ARGS {
-+ getObject(http_requestpool_object, obj);
-+ obj->iterator.pos = 0;
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto int HttpRequestPool::count()
-+ Implements Countable::count(). */
-+PHP_METHOD(HttpRequestPool, count)
-+{
-+ NO_ARGS {
-+ getObject(http_requestpool_object, obj);
-+ RETURN_LONG((long) zend_llist_count(&obj->pool.handles));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequestPool::getAttachedRequests()
-+ Get attached HttpRequest objects. */
-+PHP_METHOD(HttpRequestPool, getAttachedRequests)
-+{
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ array_init(return_value);
-+ zend_llist_apply_with_argument(&obj->pool.handles,
-+ (llist_apply_with_arg_func_t) http_requestpool_object_llist2array,
-+ return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto array HttpRequestPool::getFinishedRequests()
-+ Get attached HttpRequest objects that already have finished their work. */
-+PHP_METHOD(HttpRequestPool, getFinishedRequests)
-+{
-+ getObject(http_requestpool_object, obj);
-+
-+ NO_ARGS;
-+
-+ array_init(return_value);
-+ zend_llist_apply_with_argument(&obj->pool.finished,
-+ (llist_apply_with_arg_func_t) http_requestpool_object_llist2array,
-+ return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequestPool::enablePipelining([bool enable = true])
-+ Enables pipelining support for all attached requests if support in libcurl is given. */
-+PHP_METHOD(HttpRequestPool, enablePipelining)
-+{
-+ zend_bool enable = 1;
-+#if defined(HAVE_CURL_MULTI_SETOPT) && HTTP_CURL_VERSION(7,16,0)
-+ getObject(http_requestpool_object, obj);
-+#endif
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) {
-+ RETURN_FALSE;
-+ }
-+#if defined(HAVE_CURL_MULTI_SETOPT) && HTTP_CURL_VERSION(7,16,0)
-+ if (CURLM_OK == curl_multi_setopt(obj->pool.ch, CURLMOPT_PIPELINING, (long) enable)) {
-+ RETURN_TRUE;
-+ }
-+#endif
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool HttpRequestPool::enableEvents([bool enable = true])
-+ Enables event-driven I/O if support in libcurl is given. */
-+PHP_METHOD(HttpRequestPool, enableEvents)
-+{
-+ zend_bool enable = 1;
-+#if defined(HTTP_HAVE_EVENT)
-+ getObject(http_requestpool_object, obj);
-+#endif
-+
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) {
-+#if defined(HTTP_HAVE_EVENT)
-+ obj->pool.useevents = enable;
-+ RETURN_TRUE;
-+#endif
-+ }
-+ RETURN_FALSE;
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_response_object.c
-@@ -0,0 +1,927 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_response_object.c 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_MAGIC
-+#include "php_http.h"
-+
-+/* broken static properties in PHP 5.0 */
-+#if defined(ZEND_ENGINE_2) && !defined(WONKY)
-+
-+#include "php_ini.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_cache_api.h"
-+#include "php_http_exception_object.h"
-+#include "php_http_headers_api.h"
-+#include "php_http_response_object.h"
-+#include "php_http_send_api.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpResponse, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpResponse, method, 0)
-+#define HTTP_RESPONSE_ME(method, visibility) PHP_ME(HttpResponse, method, HTTP_ARGS(HttpResponse, method), visibility|ZEND_ACC_STATIC)
-+#define HTTP_RESPONSE_ALIAS(method, func) HTTP_STATIC_ME_ALIAS(method, func, HTTP_ARGS(HttpResponse, method))
-+
-+HTTP_BEGIN_ARGS(setHeader, 1)
-+ HTTP_ARG_VAL(name, 0)
-+ HTTP_ARG_VAL(value, 0)
-+ HTTP_ARG_VAL(replace, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(getHeader, 0)
-+ HTTP_ARG_VAL(name, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getETag);
-+HTTP_BEGIN_ARGS(setETag, 1)
-+ HTTP_ARG_VAL(etag, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getLastModified);
-+HTTP_BEGIN_ARGS(setLastModified, 1)
-+ HTTP_ARG_VAL(timestamp, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getCache);
-+HTTP_BEGIN_ARGS(setCache, 1)
-+ HTTP_ARG_VAL(cache, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getGzip);
-+HTTP_BEGIN_ARGS(setGzip, 1)
-+ HTTP_ARG_VAL(gzip, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getCacheControl);
-+HTTP_BEGIN_ARGS(setCacheControl, 1)
-+ HTTP_ARG_VAL(cache_control, 0)
-+ HTTP_ARG_VAL(max_age, 0)
-+ HTTP_ARG_VAL(must_revalidate, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getContentType);
-+HTTP_BEGIN_ARGS(setContentType, 1)
-+ HTTP_ARG_VAL(content_type, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(guessContentType, 1)
-+ HTTP_ARG_VAL(magic_file, 0)
-+ HTTP_ARG_VAL(magic_mode, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getContentDisposition);
-+HTTP_BEGIN_ARGS(setContentDisposition, 1)
-+ HTTP_ARG_VAL(filename, 0)
-+ HTTP_ARG_VAL(send_inline, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getThrottleDelay);
-+HTTP_BEGIN_ARGS(setThrottleDelay, 1)
-+ HTTP_ARG_VAL(seconds, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getBufferSize);
-+HTTP_BEGIN_ARGS(setBufferSize, 1)
-+ HTTP_ARG_VAL(bytes, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getData);
-+HTTP_BEGIN_ARGS(setData, 1)
-+ HTTP_ARG_VAL(data, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getStream);
-+HTTP_BEGIN_ARGS(setStream, 1)
-+ HTTP_ARG_VAL(stream, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getFile);
-+HTTP_BEGIN_ARGS(setFile, 1)
-+ HTTP_ARG_VAL(filepath, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(send, 0)
-+ HTTP_ARG_VAL(clean_ob, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(capture);
-+
-+HTTP_BEGIN_ARGS(redirect, 0)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(params, 0)
-+ HTTP_ARG_VAL(session, 0)
-+ HTTP_ARG_VAL(permanent, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(status, 1)
-+ HTTP_ARG_VAL(code, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_EMPTY_ARGS(getRequestHeaders);
-+HTTP_EMPTY_ARGS(getRequestBody);
-+HTTP_EMPTY_ARGS(getRequestBodyStream);
-+
-+#define THIS_CE http_response_object_ce
-+zend_class_entry *http_response_object_ce;
-+zend_function_entry http_response_object_fe[] = {
-+
-+ HTTP_RESPONSE_ME(setHeader, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getHeader, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setETag, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getETag, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setLastModified, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getLastModified, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setContentDisposition, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getContentDisposition, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setContentType, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getContentType, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(guessContentType, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setCache, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getCache, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setCacheControl, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getCacheControl, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setGzip, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getGzip, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setThrottleDelay, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getThrottleDelay, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setBufferSize, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getBufferSize, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setData, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getData, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setFile, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getFile, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(setStream, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(getStream, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ME(send, ZEND_ACC_PUBLIC)
-+ HTTP_RESPONSE_ME(capture, ZEND_ACC_PUBLIC)
-+
-+ HTTP_RESPONSE_ALIAS(redirect, http_redirect)
-+ HTTP_RESPONSE_ALIAS(status, http_send_status)
-+ HTTP_RESPONSE_ALIAS(getRequestHeaders, http_get_request_headers)
-+ HTTP_RESPONSE_ALIAS(getRequestBody, http_get_request_body)
-+ HTTP_RESPONSE_ALIAS(getRequestBodyStream, http_get_request_body_stream)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+
-+PHP_MINIT_FUNCTION(http_response_object)
-+{
-+ HTTP_REGISTER_CLASS(HttpResponse, http_response_object, NULL, 0);
-+
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("sent")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("catch")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("mode")-1, -1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("stream")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("file")-1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("data")-1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("cache")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_bool(THIS_CE, ZEND_STRS("gzip")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("eTag")-1, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("lastModified")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("cacheControl")-1, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("contentType")-1, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_null(THIS_CE, ZEND_STRS("contentDisposition")-1, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_long(THIS_CE, ZEND_STRS("bufferSize")-1, 0, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+ zend_declare_property_double(THIS_CE, ZEND_STRS("throttleDelay")-1, 0.0, (ZEND_ACC_STATIC|ZEND_ACC_PROTECTED) TSRMLS_CC);
-+
-+#ifndef WONKY
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT")-1, HTTP_REDIRECT TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT_PERM")-1, HTTP_REDIRECT_PERM TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT_FOUND")-1, HTTP_REDIRECT_FOUND TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT_POST")-1, HTTP_REDIRECT_POST TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT_PROXY")-1, HTTP_REDIRECT_PROXY TSRMLS_CC);
-+ zend_declare_class_constant_long(THIS_CE, ZEND_STRS("REDIRECT_TEMP")-1, HTTP_REDIRECT_TEMP TSRMLS_CC);
-+#endif /* WONKY */
-+
-+ return SUCCESS;
-+}
-+
-+/* ### USERLAND ### */
-+
-+/* {{{ proto static bool HttpResponse::setHeader(string name[, mixed value[, bool replace = true]])
-+ Send an HTTP header. */
-+PHP_METHOD(HttpResponse, setHeader)
-+{
-+ zend_bool replace = 1;
-+ char *name;
-+ int name_len = 0;
-+ zval *value = NULL;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/!b", &name, &name_len, &value, &replace)) {
-+ RETURN_FALSE;
-+ }
-+ if (SG(headers_sent)) {
-+ http_error(HE_WARNING, HTTP_E_HEADER, "Cannot add another header when headers have already been sent");
-+ RETURN_FALSE;
-+ }
-+ if (!name_len) {
-+ http_error(HE_WARNING, HTTP_E_HEADER, "Cannot send anonymous headers");
-+ RETURN_FALSE;
-+ }
-+ http_send_header_zval_ex(name, name_len, &value, replace);
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto static mixed HttpResponse::getHeader([string name])
-+ Get header(s) about to be sent. */
-+PHP_METHOD(HttpResponse, getHeader)
-+{
-+ char *name = NULL;
-+ int name_len = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (name && name_len) {
-+ zval **header;
-+ HashTable headers_ht;
-+
-+ zend_hash_init(&headers_ht, sizeof(zval *), NULL, ZVAL_PTR_DTOR, 0);
-+ if ( (SUCCESS == http_get_response_headers(&headers_ht)) &&
-+ (SUCCESS == zend_hash_find(&headers_ht, name, name_len + 1, (void *) &header))) {
-+ RETVAL_ZVAL(*header, 1, 0);
-+ } else {
-+ RETVAL_NULL();
-+ }
-+ zend_hash_destroy(&headers_ht);
-+ } else {
-+ array_init(return_value);
-+ http_get_response_headers(Z_ARRVAL_P(return_value));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setCache(bool cache)
-+ Whether it should be attempted to cache the entity. */
-+PHP_METHOD(HttpResponse, setCache)
-+{
-+ zend_bool do_cache = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &do_cache)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(zend_update_static_property_bool(THIS_CE, ZEND_STRS("cache")-1, do_cache TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::getCache()
-+ Get current caching setting. */
-+PHP_METHOD(HttpResponse, getCache)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *cache = http_zsep(IS_BOOL, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cache")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(cache, 1, 1);
-+ }
-+}
-+/* }}}*/
-+
-+/* {{{ proto static bool HttpResponse::setGzip(bool gzip)
-+ Enable on-thy-fly gzipping of the sent entity. */
-+PHP_METHOD(HttpResponse, setGzip)
-+{
-+ zend_bool do_gzip = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &do_gzip)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(zend_update_static_property_bool(THIS_CE, ZEND_STRS("gzip")-1, do_gzip TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::getGzip()
-+ Get current gzipping setting. */
-+PHP_METHOD(HttpResponse, getGzip)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *gzip = http_zsep(IS_BOOL, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("gzip")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(gzip, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setCacheControl(string control[, int max_age = 0[, bool must_revalidate = true]])
-+ Set a custom cache-control header, usually being "private" or "public"; The max_age parameter controls how long the cache entry is valid on the client side. */
-+PHP_METHOD(HttpResponse, setCacheControl)
-+{
-+ char *ccontrol, *cctl;
-+ int cc_len;
-+ long max_age = 0;
-+ zend_bool must_revalidate = 1;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &ccontrol, &cc_len, &max_age, &must_revalidate)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (strcmp(ccontrol, "public") && strcmp(ccontrol, "private") && strcmp(ccontrol, "no-cache")) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol);
-+ RETURN_FALSE;
-+ } else {
-+ size_t cctl_len = spprintf(&cctl, 0, "%s,%s max-age=%ld", ccontrol, must_revalidate?" must-revalidate,":"", max_age);
-+ RETVAL_SUCCESS(zend_update_static_property_stringl(THIS_CE, ZEND_STRS("cacheControl")-1, cctl, cctl_len TSRMLS_CC));
-+ efree(cctl);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getCacheControl()
-+ Get current Cache-Control header setting. */
-+PHP_METHOD(HttpResponse, getCacheControl)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *cctl = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(cctl, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setContentType(string content_type)
-+ Set the content-type of the sent entity. */
-+PHP_METHOD(HttpResponse, setContentType)
-+{
-+ char *ctype;
-+ int ctype_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ctype, &ctype_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ HTTP_CHECK_CONTENT_TYPE(ctype, RETURN_FALSE);
-+ RETURN_SUCCESS(zend_update_static_property_stringl(THIS_CE, ZEND_STRS("contentType")-1, ctype, ctype_len TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getContentType()
-+ Get current Content-Type header setting. */
-+PHP_METHOD(HttpResponse, getContentType)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *ctype = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(ctype, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::guessContentType(string magic_file[, int magic_mode = MAGIC_MIME])
-+ Attempts to guess the content type of supplied payload through libmagic. */
-+PHP_METHOD(HttpResponse, guessContentType)
-+{
-+#ifdef HTTP_HAVE_MAGIC
-+ char *magic_file, *ct = NULL;
-+ int magic_file_len;
-+ long magic_mode = MAGIC_MIME;
-+
-+ RETVAL_FALSE;
-+ SET_EH_THROW_HTTP();
-+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &magic_file, &magic_file_len, &magic_mode)) {
-+ switch (Z_LVAL_P(*zend_std_get_static_property(THIS_CE, ZEND_STRS("mode")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC))) {
-+ case SEND_DATA:
-+ {
-+ zval *data = *zend_std_get_static_property(THIS_CE, ZEND_STRS("data")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+ ct = http_guess_content_type(magic_file, magic_mode, Z_STRVAL_P(data), Z_STRLEN_P(data), SEND_DATA);
-+ break;
-+ }
-+
-+ case SEND_RSRC:
-+ {
-+ php_stream *s;
-+ zval *z = *zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+ z->type = IS_RESOURCE;
-+ php_stream_from_zval(s, &z);
-+ ct = http_guess_content_type(magic_file, magic_mode, s, 0, SEND_RSRC);
-+ break;
-+ }
-+
-+ default:
-+ ct = http_guess_content_type(magic_file, magic_mode, Z_STRVAL_P(*zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)), 0, -1);
-+ break;
-+ }
-+ if (ct) {
-+ zend_update_static_property_string(THIS_CE, ZEND_STRS("contentType")-1, ct TSRMLS_CC);
-+ RETVAL_STRING(ct, 0);
-+ }
-+ }
-+ SET_EH_NORMAL();
-+#else
-+ http_error(HE_THROW, HTTP_E_RUNTIME, "Cannot guess Content-Type; libmagic not available");
-+ RETURN_FALSE;
-+#endif
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setContentDisposition(string filename[, bool inline = false])
-+ Set the Content-Disposition. */
-+PHP_METHOD(HttpResponse, setContentDisposition)
-+{
-+ char *file, *cd;
-+ int file_len;
-+ size_t cd_len;
-+ zend_bool send_inline = 0;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &file, &file_len, &send_inline)) {
-+ RETURN_FALSE;
-+ }
-+
-+ cd_len = spprintf(&cd, 0, "%s; filename=\"%s\"", send_inline ? "inline" : "attachment", file);
-+ RETVAL_SUCCESS(zend_update_static_property_stringl(THIS_CE, ZEND_STRS("contentDisposition")-1, cd, cd_len TSRMLS_CC));
-+ efree(cd);
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getContentDisposition()
-+ Get current Content-Disposition setting. */
-+PHP_METHOD(HttpResponse, getContentDisposition)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *cdisp = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(cdisp, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setETag(string etag)
-+ Set a custom ETag. Use this only if you know what you're doing. */
-+PHP_METHOD(HttpResponse, setETag)
-+{
-+ char *etag;
-+ int etag_len;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &etag, &etag_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(zend_update_static_property_stringl(THIS_CE, ZEND_STRS("eTag")-1, etag, etag_len TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getETag()
-+ Get calculated or previously set custom ETag. */
-+PHP_METHOD(HttpResponse, getETag)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *etag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(etag, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setLastModified(int timestamp)
-+ Set a custom Last-Modified date. */
-+PHP_METHOD(HttpResponse, setLastModified)
-+{
-+ long lm;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lm)) {
-+ RETURN_FALSE;
-+ }
-+
-+ RETURN_SUCCESS(zend_update_static_property_long(THIS_CE, ZEND_STRS("lastModified")-1, lm TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static int HttpResponse::getLastModified()
-+ Get calculated or previously set custom Last-Modified date. */
-+PHP_METHOD(HttpResponse, getLastModified)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *lmod = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(lmod, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setThrottleDelay(double seconds)
-+ Sets the throttle delay for use with HttpResponse::setBufferSize(). */
-+PHP_METHOD(HttpResponse, setThrottleDelay)
-+{
-+ double seconds;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds)) {
-+ RETURN_FALSE;
-+ }
-+ RETURN_SUCCESS(zend_update_static_property_double(THIS_CE, ZEND_STRS("throttleDelay")-1, seconds TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static double HttpResponse::getThrottleDelay()
-+ Get the current throttle delay. */
-+PHP_METHOD(HttpResponse, getThrottleDelay)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *tdel = http_zsep(IS_DOUBLE, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(tdel, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setBufferSize(int bytes)
-+ Sets the send buffer size for use with HttpResponse::setThrottleDelay(). */
-+PHP_METHOD(HttpResponse, setBufferSize)
-+{
-+ long bytes;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bytes)) {
-+ RETURN_FALSE;
-+ }
-+ RETURN_SUCCESS(zend_update_static_property_long(THIS_CE, ZEND_STRS("bufferSize")-1, bytes TSRMLS_CC));
-+}
-+/* }}} */
-+
-+/* {{{ proto static int HttpResponse::getBufferSize()
-+ Get current buffer size. */
-+PHP_METHOD(HttpResponse, getBufferSize)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *bsize = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(bsize, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setData(mixed data)
-+ Set the data to be sent. */
-+PHP_METHOD(HttpResponse, setData)
-+{
-+ char *etag;
-+ zval *the_data;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &the_data)) {
-+ RETURN_FALSE;
-+ }
-+ if (Z_TYPE_P(the_data) != IS_STRING) {
-+ convert_to_string(the_data);
-+ }
-+
-+ if ( (SUCCESS != zend_update_static_property(THIS_CE, ZEND_STRS("data")-1, the_data TSRMLS_CC)) ||
-+ (SUCCESS != zend_update_static_property_long(THIS_CE, ZEND_STRS("mode")-1, SEND_DATA TSRMLS_CC))) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_static_property_long(THIS_CE, ZEND_STRS("lastModified")-1, http_last_modified(the_data, SEND_DATA) TSRMLS_CC);
-+ if ((etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA))) {
-+ zend_update_static_property_string(THIS_CE, ZEND_STRS("eTag")-1, etag TSRMLS_CC);
-+ efree(etag);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getData()
-+ Get the previously set data to be sent. */
-+PHP_METHOD(HttpResponse, getData)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *the_data = *zend_std_get_static_property(THIS_CE, ZEND_STRS("data")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+
-+ RETURN_ZVAL(the_data, 1, 0);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setStream(resource stream)
-+ Set the resource to be sent. */
-+PHP_METHOD(HttpResponse, setStream)
-+{
-+ char *etag;
-+ zval *the_stream;
-+ php_stream *the_real_stream;
-+ php_stream_statbuf ssb;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &the_stream)) {
-+ RETURN_FALSE;
-+ }
-+
-+ php_stream_from_zval(the_real_stream, &the_stream);
-+ if (php_stream_stat(the_real_stream, &ssb)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if ( (SUCCESS != zend_update_static_property_long(THIS_CE, ZEND_STRS("stream")-1, Z_LVAL_P(the_stream) TSRMLS_CC)) ||
-+ (SUCCESS != zend_update_static_property_long(THIS_CE, ZEND_STRS("mode")-1, SEND_RSRC TSRMLS_CC))) {
-+ RETURN_FALSE;
-+ }
-+ zend_list_addref(Z_LVAL_P(the_stream));
-+
-+ zend_update_static_property_long(THIS_CE, ZEND_STRS("lastModified")-1, http_last_modified(the_real_stream, SEND_RSRC) TSRMLS_CC);
-+ if ((etag = http_etag(the_real_stream, 0, SEND_RSRC))) {
-+ zend_update_static_property_string(THIS_CE, ZEND_STRS("eTag")-1, etag TSRMLS_CC);
-+ efree(etag);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto static resource HttpResponse::getStream()
-+ Get the previously set resource to be sent. */
-+PHP_METHOD(HttpResponse, getStream)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *stream = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_RESOURCE(Z_LVAL_P(stream));
-+ zval_ptr_dtor(&stream);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::setFile(string file)
-+ Set the file to be sent. */
-+PHP_METHOD(HttpResponse, setFile)
-+{
-+ char *the_file, *etag;
-+ int file_len;
-+ php_stream_statbuf ssb;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &the_file, &file_len)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if (php_stream_stat_path(the_file, &ssb)) {
-+ RETURN_FALSE;
-+ }
-+
-+ if ( (SUCCESS != zend_update_static_property_stringl(THIS_CE, ZEND_STRS("file")-1, the_file, file_len TSRMLS_CC)) ||
-+ (SUCCESS != zend_update_static_property_long(THIS_CE, ZEND_STRS("mode")-1, -1 TSRMLS_CC))) {
-+ RETURN_FALSE;
-+ }
-+
-+ zend_update_static_property_long(THIS_CE, ZEND_STRS("lastModified")-1, http_last_modified(the_file, -1) TSRMLS_CC);
-+ if ((etag = http_etag(the_file, 0, -1))) {
-+ zend_update_static_property_string(THIS_CE, ZEND_STRS("eTag")-1, etag TSRMLS_CC);
-+ efree(etag);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto static string HttpResponse::getFile()
-+ Get the previously set file to be sent. */
-+PHP_METHOD(HttpResponse, getFile)
-+{
-+ NO_ARGS;
-+
-+ if (return_value_used) {
-+ zval *file = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_ZVAL(file, 1, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static bool HttpResponse::send([bool clean_ob = true])
-+ Finally send the entity. */
-+PHP_METHOD(HttpResponse, send)
-+{
-+ zval *sent;
-+ zend_bool clean_ob = 1;
-+
-+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean_ob)) {
-+ RETURN_FALSE;
-+ }
-+
-+ HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
-+
-+ sent = *zend_std_get_static_property(THIS_CE, ZEND_STRS("sent")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC);
-+ if (Z_LVAL_P(sent)) {
-+ http_error(HE_WARNING, HTTP_E_RESPONSE, "Cannot send HttpResponse, response has already been sent");
-+ RETURN_FALSE;
-+ } else {
-+ Z_LVAL_P(sent) = 1;
-+ }
-+
-+ /* capture mode */
-+ if (i_zend_is_true(*zend_std_get_static_property(THIS_CE, ZEND_STRS("catch")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC))) {
-+ zval *zetag, *the_data;
-+
-+ MAKE_STD_ZVAL(the_data);
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_get_contents(the_data TSRMLS_CC);
-+#else
-+ php_ob_get_buffer(the_data TSRMLS_CC);
-+#endif
-+ zend_update_static_property(THIS_CE, ZEND_STRS("data")-1, the_data TSRMLS_CC);
-+ ZVAL_LONG(*zend_std_get_static_property(THIS_CE, ZEND_STRS("mode")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC), SEND_DATA);
-+
-+ zetag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ if (!Z_STRLEN_P(zetag)) {
-+ char *etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA);
-+ if (etag) {
-+ zend_update_static_property_string(THIS_CE, ZEND_STRS("eTag")-1, etag TSRMLS_CC);
-+ efree(etag);
-+ }
-+ }
-+ zval_ptr_dtor(&the_data);
-+ zval_ptr_dtor(&zetag);
-+
-+ clean_ob = 1;
-+ }
-+
-+ if (clean_ob) {
-+ /* interrupt on-the-fly etag generation */
-+ HTTP_G->etag.started = 0;
-+ /* discard previous output buffers */
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_discard_all(TSRMLS_C);
-+#else
-+ php_end_ob_buffers(0 TSRMLS_CC);
-+#endif
-+ }
-+
-+ /* caching */
-+ if (i_zend_is_true(*zend_std_get_static_property(THIS_CE, ZEND_STRS("cache")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC))) {
-+ zval *cctl, *etag, *lmod;
-+
-+ lmod = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ etag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ cctl = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+
-+ if (Z_LVAL_P(lmod) || Z_STRLEN_P(etag)) {
-+ if (Z_STRLEN_P(cctl)) {
-+ http_send_cache_control(Z_STRVAL_P(cctl), Z_STRLEN_P(cctl));
-+ } else {
-+ http_send_cache_control(HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL));
-+ }
-+ if (Z_STRLEN_P(etag)) {
-+ http_send_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag));
-+ }
-+ if (Z_LVAL_P(lmod)) {
-+ http_send_last_modified(Z_LVAL_P(lmod));
-+ }
-+ }
-+
-+ zval_ptr_dtor(&etag);
-+ zval_ptr_dtor(&lmod);
-+ zval_ptr_dtor(&cctl);
-+ }
-+
-+ /* content type */
-+ {
-+ zval *ctype = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ if (Z_STRLEN_P(ctype)) {
-+ http_send_content_type(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype));
-+ } else {
-+ char *ctypes = INI_STR("default_mimetype");
-+ size_t ctlen = ctypes ? strlen(ctypes) : 0;
-+
-+ if (ctlen) {
-+ http_send_content_type(ctypes, ctlen);
-+ } else {
-+ http_send_content_type("application/x-octetstream", lenof("application/x-octetstream"));
-+ }
-+ }
-+ zval_ptr_dtor(&ctype);
-+ }
-+
-+ /* content disposition */
-+ {
-+ zval *cd = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ if (Z_STRLEN_P(cd)) {
-+ http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1, NULL);
-+ }
-+ zval_ptr_dtor(&cd);
-+ }
-+
-+ /* throttling */
-+ {
-+ zval *bsize = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ zval *delay = http_zsep(IS_DOUBLE, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ HTTP_G->send.buffer_size = Z_LVAL_P(bsize);
-+ HTTP_G->send.throttle_delay = Z_DVAL_P(delay);
-+ zval_ptr_dtor(&bsize);
-+ zval_ptr_dtor(&delay);
-+ }
-+
-+ /* gzip */
-+ HTTP_G->send.deflate.response = i_zend_is_true(*zend_std_get_static_property(THIS_CE, ZEND_STRS("gzip")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC));
-+
-+ /* send */
-+ switch (Z_LVAL_P(*zend_std_get_static_property(THIS_CE, ZEND_STRS("mode")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC))) {
-+ case SEND_DATA:
-+ {
-+ zval *zdata = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("data")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
-+ zval_ptr_dtor(&zdata);
-+ return;
-+ }
-+
-+ case SEND_RSRC:
-+ {
-+ php_stream *the_real_stream;
-+ zval *the_stream = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ the_stream->type = IS_RESOURCE;
-+ php_stream_from_zval(the_real_stream, &the_stream);
-+ RETVAL_SUCCESS(http_send_stream(the_real_stream));
-+ zval_ptr_dtor(&the_stream);
-+ return;
-+ }
-+
-+ default:
-+ {
-+ zval *file = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 ZEND_LITERAL_NIL_CC TSRMLS_CC)));
-+ RETVAL_SUCCESS(http_send_file(Z_STRVAL_P(file)));
-+ zval_ptr_dtor(&file);
-+ return;
-+ }
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto static void HttpResponse::capture()
-+ Capture script output.
-+ */
-+PHP_METHOD(HttpResponse, capture)
-+{
-+ NO_ARGS;
-+
-+ HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
-+
-+ zend_update_static_property_long(THIS_CE, ZEND_STRS("catch")-1, 1 TSRMLS_CC);
-+#ifdef PHP_OUTPUT_NEWAPI
-+ php_output_discard_all(TSRMLS_C);
-+ php_output_start_default(TSRMLS_C);
-+#else
-+ php_end_ob_buffers(0 TSRMLS_CC);
-+ php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC);
-+#endif
-+
-+ /* register shutdown function */
-+ {
-+ zval func, retval, arg, *argp[1];
-+
-+ INIT_PZVAL(&arg);
-+ INIT_PZVAL(&func);
-+ INIT_PZVAL(&retval);
-+ ZVAL_STRINGL(&func, "register_shutdown_function", lenof("register_shutdown_function"), 0);
-+
-+ array_init(&arg);
-+ add_next_index_stringl(&arg, "HttpResponse", lenof("HttpResponse"), 1);
-+ add_next_index_stringl(&arg, "send", lenof("send"), 1);
-+ argp[0] = &arg;
-+ call_user_function(EG(function_table), NULL, &func, &retval, 1, argp TSRMLS_CC);
-+ zval_dtor(&arg);
-+ }
-+}
-+/* }}} */
-+
-+#endif /* ZEND_ENGINE_2 && !WONKY */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_send_api.c
-@@ -0,0 +1,611 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_send_api.c 312028 2011-06-10 22:03:12Z felipe $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_ZLIB
-+#define HTTP_WANT_MAGIC
-+#include "php_http.h"
-+
-+#include "php_streams.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_cache_api.h"
-+#include "php_http_date_api.h"
-+#include "php_http_encoding_api.h"
-+#include "php_http_headers_api.h"
-+#include "php_http_send_api.h"
-+
-+/* {{{ http_flush() */
-+#define http_flush(d, l) _http_flush(NULL, (d), (l) TSRMLS_CC)
-+static inline void _http_flush(void *nothing, const char *data, size_t data_len TSRMLS_DC)
-+{
-+ PHPWRITE(data, data_len);
-+ /* we really only need to flush when throttling is enabled,
-+ because we push the data as fast as possible anyway if not */
-+ if (HTTP_G->send.throttle_delay >= HTTP_DIFFSEC) {
-+#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID >= 50399)
-+ php_output_end_all(TSRMLS_C);
-+#else
-+ if (OG(ob_nesting_level)) {
-+ php_end_ob_buffer(1, 1 TSRMLS_CC);
-+ }
-+ if (!OG(implicit_flush)) {
-+ sapi_flush(TSRMLS_C);
-+ }
-+#endif
-+ http_sleep(HTTP_G->send.throttle_delay);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ http_send_response_start */
-+#define http_send_response_start(b, cl) _http_send_response_start((b), (cl) TSRMLS_CC)
-+static inline void _http_send_response_start(void **buffer, size_t content_length TSRMLS_DC)
-+{
-+ int encoding;
-+
-+ if ((encoding = http_encoding_response_start(content_length, 0))) {
-+#ifdef HTTP_HAVE_ZLIB
-+ *((http_encoding_stream **) buffer) = http_encoding_deflate_stream_init(NULL,
-+ (encoding == HTTP_ENCODING_GZIP) ?
-+ HTTP_DEFLATE_TYPE_GZIP : HTTP_DEFLATE_TYPE_ZLIB);
-+#endif
-+ }
-+ /* flush headers */
-+ sapi_flush(TSRMLS_C);
-+}
-+/* }}} */
-+
-+/* {{{ http_send_response_data_plain */
-+#define http_send_response_data_plain(b, d, dl) _http_send_response_data_plain((b), (d), (dl) TSRMLS_CC)
-+static inline void _http_send_response_data_plain(void **buffer, const char *data, size_t data_len TSRMLS_DC)
-+{
-+ if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) {
-+#ifdef HTTP_HAVE_ZLIB
-+ char *encoded;
-+ size_t encoded_len;
-+ http_encoding_stream *s = *((http_encoding_stream **) buffer);
-+
-+ http_encoding_deflate_stream_update(s, data, data_len, &encoded, &encoded_len);
-+ if (HTTP_G->send.buffer_size) {
-+ phpstr_chunked_output((phpstr **) &s->storage, encoded, encoded_len, HTTP_G->send.buffer_size, _http_flush, NULL TSRMLS_CC);
-+ } else {
-+ http_flush(encoded, encoded_len);
-+ }
-+ efree(encoded);
-+#else
-+ http_error(HE_ERROR, HTTP_E_RESPONSE, "Attempt to send GZIP response despite being able to do so; please report this bug");
-+#endif
-+ } else if (HTTP_G->send.buffer_size) {
-+ phpstr_chunked_output((phpstr **) buffer, data, data_len, HTTP_G->send.buffer_size, _http_flush, NULL TSRMLS_CC);
-+ } else {
-+ http_flush(data, data_len);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ http_send_response_data_fetch */
-+#define http_send_response_data_fetch(b, d, l, m, s, e) _http_send_response_data_fetch((b), (d), (l), (m), (s), (e) TSRMLS_CC)
-+static inline void _http_send_response_data_fetch(void **buffer, const void *data, size_t data_len, http_send_mode mode, size_t begin, size_t end TSRMLS_DC)
-+{
-+ long bsz, got, len = end - begin;
-+
-+ if (!(bsz = HTTP_G->send.buffer_size)) {
-+ bsz = HTTP_SENDBUF_SIZE;
-+ }
-+
-+ switch (mode) {
-+ case SEND_RSRC: {
-+ php_stream *s = (php_stream *) data;
-+ if (SUCCESS == php_stream_seek(s, begin, SEEK_SET)) {
-+ char *buf = emalloc(bsz);
-+
-+ while (len > 0) {
-+ got = php_stream_read(s, buf, MIN(len, bsz));
-+ http_send_response_data_plain(buffer, buf, got);
-+ len -= got;
-+ }
-+
-+ efree(buf);
-+ }
-+ break;
-+ }
-+ case SEND_DATA: {
-+ const char *buf = ((const char *) data) + begin;
-+ while (len > 0) {
-+ got = MIN(len, bsz);
-+ http_send_response_data_plain(buffer, buf, got);
-+ len -= got;
-+ buf += got;
-+ }
-+ break;
-+ }
-+ EMPTY_SWITCH_DEFAULT_CASE();
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ http_send_response_finish */
-+#define http_send_response_finish(b) _http_send_response_finish((b) TSRMLS_CC)
-+static inline void _http_send_response_finish(void **buffer TSRMLS_DC)
-+{
-+ if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) {
-+#ifdef HTTP_HAVE_ZLIB
-+ char *encoded = NULL;
-+ size_t encoded_len = 0;
-+ http_encoding_stream *s = *((http_encoding_stream **) buffer);
-+
-+ http_encoding_deflate_stream_finish(s, &encoded, &encoded_len);
-+ if (HTTP_G->send.buffer_size) {
-+ phpstr_chunked_output((phpstr **) &s->storage, encoded, encoded_len, 0, _http_flush, NULL TSRMLS_CC);
-+ } else {
-+ http_flush(encoded, encoded_len);
-+ }
-+ http_encoding_deflate_stream_free(&s);
-+ STR_FREE(encoded);
-+#else
-+ http_error(HE_ERROR, HTTP_E_RESPONSE, "Attempt to send GZIP response despite being able to do so; please report this bug");
-+#endif
-+ } else if (HTTP_G->send.buffer_size) {
-+ phpstr_chunked_output((phpstr **) buffer, NULL, 0, 0, _http_flush, NULL TSRMLS_CC);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ */
-+PHP_MINIT_FUNCTION(http_send)
-+{
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT", HTTP_REDIRECT);
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT_PERM", HTTP_REDIRECT_PERM);
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT_FOUND", HTTP_REDIRECT_FOUND);
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT_POST", HTTP_REDIRECT_POST);
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT_PROXY", HTTP_REDIRECT_PROXY);
-+ HTTP_LONG_CONSTANT("HTTP_REDIRECT_TEMP", HTTP_REDIRECT_TEMP);
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ http_find_header */
-+typedef struct {
-+ const char *h;
-+ size_t l;
-+} http_response_header_t;
-+
-+static int http_find_header(void *data, void *arg)
-+{
-+ http_response_header_t *h = arg;
-+ sapi_header_struct *s = data;
-+
-+ return (!strncasecmp(s->header, h->h, h->l)) && s->header[h->l] == ':';
-+}
-+/* }}} */
-+
-+/* {{{ void http_hide_header(char *) */
-+PHP_HTTP_API void _http_hide_header_ex(const char *name, size_t name_len TSRMLS_DC)
-+{
-+ http_response_header_t h = {name, name_len};
-+ zend_llist_del_element(&SG(sapi_headers).headers, (void *) &h, http_find_header);
-+}
-+/* }}} */
-+
-+/* {{{ void http_send_header_zval(char*, zval **, zend_bool) */
-+PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, zval **val, zend_bool replace TSRMLS_DC)
-+{
-+ if (!val || !*val || Z_TYPE_PP(val) == IS_NULL || (Z_TYPE_PP(val) == IS_STRING && !Z_STRLEN_PP(val))) {
-+ http_hide_header_ex(name, name_len);
-+ } else if (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT) {
-+ zend_bool first = replace;
-+ zval **data_ptr;
-+ HashPosition pos;
-+
-+ FOREACH_HASH_VAL(pos, HASH_OF(*val), data_ptr) {
-+ zval *data = http_zsep(IS_STRING, *data_ptr);
-+
-+ http_send_header_ex(name, name_len, Z_STRVAL_P(data), Z_STRLEN_P(data), first, NULL);
-+ zval_ptr_dtor(&data);
-+ first = 0;
-+ }
-+ } else {
-+ zval *data = http_zsep(IS_STRING, *val);
-+
-+ http_send_header_ex(name, name_len, Z_STRVAL_P(data), Z_STRLEN_P(data), replace, NULL);
-+ zval_ptr_dtor(&data);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_header(char *, char *, zend_bool) */
-+PHP_HTTP_API STATUS _http_send_header_ex(const char *name, size_t name_len, const char *value, size_t value_len, zend_bool replace, char **sent_header TSRMLS_DC)
-+{
-+ STATUS ret;
-+
-+ if (value && value_len) {
-+ size_t header_len = sizeof(": ") + name_len + value_len + 1;
-+ char *header = emalloc(header_len + 1);
-+
-+ header[header_len] = '\0';
-+ header_len = snprintf(header, header_len, "%s: %s", name, value);
-+ ret = http_send_header_string_ex(header, header_len, replace);
-+ if (sent_header) {
-+ *sent_header = header;
-+ } else {
-+ efree(header);
-+ }
-+ } else {
-+ http_hide_header_ex(name, name_len);
-+ ret = SUCCESS;
-+ }
-+ return ret;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_status_header(int, char *) */
-+PHP_HTTP_API STATUS _http_send_status_header_ex(int status, const char *header, size_t header_len, zend_bool replace TSRMLS_DC)
-+{
-+ STATUS ret;
-+ sapi_header_line h = {(char *) header, header_len, status};
-+ if (SUCCESS != (ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, &h TSRMLS_CC))) {
-+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Could not send header: %s (%d)", header, status);
-+ }
-+ return ret;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_last_modified(int) */
-+PHP_HTTP_API STATUS _http_send_last_modified_ex(time_t t, char **sent_header TSRMLS_DC)
-+{
-+ STATUS ret;
-+ char *date = http_date(t);
-+
-+ if (!date) {
-+ return FAILURE;
-+ }
-+
-+ ret = http_send_header_ex("Last-Modified", lenof("Last-Modified"), date, strlen(date), 1, sent_header);
-+ efree(date);
-+
-+ /* remember */
-+ HTTP_G->send.last_modified = t;
-+
-+ return ret;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_etag(char *, size_t) */
-+PHP_HTTP_API STATUS _http_send_etag_ex(const char *etag, size_t etag_len, char **sent_header TSRMLS_DC)
-+{
-+ STATUS status;
-+ char *etag_header;
-+ size_t etag_header_len;
-+
-+ if (!etag_len){
-+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Attempt to send empty ETag (previous: %s)\n", HTTP_G->send.unquoted_etag);
-+ return FAILURE;
-+ }
-+
-+ etag_header_len = spprintf(&etag_header, 0, "ETag: \"%s\"", etag);
-+ status = http_send_header_string_ex(etag_header, etag_header_len, 1);
-+
-+ /* remember */
-+ STR_SET(HTTP_G->send.unquoted_etag, estrndup(etag, etag_len));
-+
-+ if (sent_header) {
-+ *sent_header = etag_header;
-+ } else {
-+ efree(etag_header);
-+ }
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_content_type(char *, size_t) */
-+PHP_HTTP_API STATUS _http_send_content_type(const char *content_type, size_t ct_len TSRMLS_DC)
-+{
-+ HTTP_CHECK_CONTENT_TYPE(content_type, return FAILURE);
-+
-+ /* remember for multiple ranges */
-+ STR_FREE(HTTP_G->send.content_type);
-+ HTTP_G->send.content_type = estrndup(content_type, ct_len);
-+
-+ return http_send_header_ex("Content-Type", lenof("Content-Type"), content_type, ct_len, 1, NULL);
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_content_disposition(char *, size_t, zend_bool) */
-+PHP_HTTP_API STATUS _http_send_content_disposition(const char *filename, size_t f_len, zend_bool send_inline TSRMLS_DC)
-+{
-+ STATUS status;
-+ char *cd_header;
-+
-+ if (send_inline) {
-+ cd_header = ecalloc(1, sizeof("Content-Disposition: inline; filename=\"\"") + f_len);
-+ sprintf(cd_header, "Content-Disposition: inline; filename=\"%s\"", filename);
-+ } else {
-+ cd_header = ecalloc(1, sizeof("Content-Disposition: attachment; filename=\"\"") + f_len);
-+ sprintf(cd_header, "Content-Disposition: attachment; filename=\"%s\"", filename);
-+ }
-+
-+ status = http_send_header_string(cd_header);
-+ efree(cd_header);
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send(void *, size_t, http_send_mode) */
-+PHP_HTTP_API STATUS _http_send_ex(const void *data_ptr, size_t data_size, http_send_mode data_mode, zend_bool no_cache TSRMLS_DC)
-+{
-+ void *s = NULL;
-+ HashTable ranges;
-+ http_range_status range_status;
-+
-+ if (!data_ptr) {
-+ return FAILURE;
-+ }
-+ if (!data_size) {
-+ return SUCCESS;
-+ }
-+
-+ /* enable partial dl and resume */
-+ http_send_header_string("Accept-Ranges: bytes");
-+
-+ zend_hash_init(&ranges, 0, NULL, ZVAL_PTR_DTOR, 0);
-+ range_status = http_get_request_ranges(&ranges, data_size);
-+
-+ switch (range_status) {
-+ case RANGE_ERR:
-+ {
-+ zend_hash_destroy(&ranges);
-+ http_send_status(416);
-+ return FAILURE;
-+ }
-+ case RANGE_OK:
-+ {
-+ /* Range Request - only send ranges if entity hasn't changed */
-+ if ( http_got_server_var("HTTP_IF_RANGE") &&
-+ !http_match_etag("HTTP_IF_RANGE", HTTP_G->send.unquoted_etag) &&
-+ !http_match_last_modified("HTTP_IF_RANGE", HTTP_G->send.last_modified)) {
-+ /* fallthrough to send full entity with 200 Ok */
-+ no_cache = 1;
-+ } else if ( !http_match_etag_ex("HTTP_IF_MATCH", HTTP_G->send.unquoted_etag, 0) ||
-+ !http_match_last_modified_ex("HTTP_IF_UNMODIFIED_SINCE", HTTP_G->send.last_modified, 0) ||
-+ !http_match_last_modified_ex("HTTP_UNLESS_MODIFIED_SINCE", HTTP_G->send.last_modified, 0)) {
-+ /* 412 Precondition failed */
-+ zend_hash_destroy(&ranges);
-+ http_send_status(412);
-+ return FAILURE;
-+ } else if (zend_hash_num_elements(&ranges) == 1) {
-+ /* single range */
-+ zval **range, **begin, **end;
-+
-+ if ( SUCCESS != zend_hash_index_find(&ranges, 0, (void *) &range) ||
-+ SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(range), 0, (void *) &begin) ||
-+ SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(range), 1, (void *) &end)) {
-+ /* this should never happen */
-+ zend_hash_destroy(&ranges);
-+ http_send_status(500);
-+ return FAILURE;
-+ } else {
-+ phpstr header;
-+
-+ phpstr_init(&header);
-+ phpstr_appendf(&header, "Content-Range: bytes %ld-%ld/%zu", Z_LVAL_PP(begin), Z_LVAL_PP(end), data_size);
-+ phpstr_fix(&header);
-+ http_send_status_header_ex(206, PHPSTR_VAL(&header), PHPSTR_LEN(&header), 1);
-+ phpstr_dtor(&header);
-+ http_send_response_start(&s, Z_LVAL_PP(end)-Z_LVAL_PP(begin)+1);
-+ http_send_response_data_fetch(&s, data_ptr, data_size, data_mode, Z_LVAL_PP(begin), Z_LVAL_PP(end) + 1);
-+ http_send_response_finish(&s);
-+ zend_hash_destroy(&ranges);
-+ return SUCCESS;
-+ }
-+ } else {
-+ /* multi range */
-+ HashPosition pos;
-+ zval **range, **begin, **end;
-+ const char *content_type = HTTP_G->send.content_type;
-+ char boundary_str[32];
-+ size_t boundary_len;
-+ phpstr header, preface;
-+
-+ boundary_len = http_boundary(boundary_str, sizeof(boundary_str));
-+ phpstr_init(&header);
-+ phpstr_appendf(&header, "Content-Type: multipart/byteranges; boundary=%s", boundary_str);
-+ phpstr_fix(&header);
-+ http_send_status_header_ex(206, PHPSTR_VAL(&header), PHPSTR_LEN(&header), 1);
-+ phpstr_dtor(&header);
-+ http_send_response_start(&s, 0);
-+
-+ if (!content_type) {
-+ content_type = "application/x-octetstream";
-+ }
-+
-+ phpstr_init(&preface);
-+ FOREACH_HASH_VAL(pos, &ranges, range) {
-+ if ( SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(range), 0, (void *) &begin) &&
-+ SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(range), 1, (void *) &end)) {
-+
-+#define HTTP_RANGE_PREFACE \
-+ HTTP_CRLF "--%s" \
-+ HTTP_CRLF "Content-Type: %s" \
-+ HTTP_CRLF "Content-Range: bytes %ld-%ld/%zu" \
-+ HTTP_CRLF HTTP_CRLF
-+
-+ phpstr_appendf(&preface, HTTP_RANGE_PREFACE, boundary_str, content_type, Z_LVAL_PP(begin), Z_LVAL_PP(end), data_size);
-+ phpstr_fix(&preface);
-+ http_send_response_data_plain(&s, PHPSTR_VAL(&preface), PHPSTR_LEN(&preface));
-+ phpstr_reset(&preface);
-+ http_send_response_data_fetch(&s, data_ptr, data_size, data_mode, Z_LVAL_PP(begin), Z_LVAL_PP(end) + 1);
-+ }
-+ }
-+ phpstr_dtor(&preface);
-+
-+ http_send_response_data_plain(&s, HTTP_CRLF "--", lenof(HTTP_CRLF "--"));
-+ http_send_response_data_plain(&s, boundary_str, boundary_len);
-+ http_send_response_data_plain(&s, "--", lenof("--"));
-+
-+ http_send_response_finish(&s);
-+ zend_hash_destroy(&ranges);
-+ return SUCCESS;
-+ }
-+ }
-+ case RANGE_NO:
-+ {
-+ zend_hash_destroy(&ranges);
-+
-+ /* send 304 Not Modified if etag matches - DON'T return on ETag generation failure */
-+ if (!no_cache && (http_interrupt_ob_etaghandler() || (HTTP_G->send.unquoted_etag != NULL))) {
-+ char *etag = NULL;
-+
-+ if (HTTP_G->send.unquoted_etag) {
-+ etag = estrdup(HTTP_G->send.unquoted_etag);
-+ }
-+
-+ if (etag || (etag = http_etag(data_ptr, data_size, data_mode))) {
-+ char *sent_header = NULL;
-+
-+ http_send_etag_ex(etag, strlen(etag), &sent_header);
-+ if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
-+ return http_exit_ex(304, sent_header, NULL, 0);
-+ } else {
-+ STR_FREE(sent_header);
-+ /* no caching for Last-Modified if ETags really don't match */
-+ no_cache = http_got_server_var("HTTP_IF_NONE_MATCH");
-+ }
-+ efree(etag);
-+ }
-+ }
-+
-+ /* send 304 Not Modified if last modified matches */
-+ if (!no_cache && HTTP_G->send.last_modified && http_match_last_modified("HTTP_IF_MODIFIED_SINCE", HTTP_G->send.last_modified)) {
-+ char *sent_header = NULL;
-+ http_send_last_modified_ex(HTTP_G->send.last_modified, &sent_header);
-+ return http_exit_ex(304, sent_header, NULL, 0);
-+ }
-+
-+ /* send full response */
-+ http_send_response_start(&s, data_size);
-+ http_send_response_data_fetch(&s, data_ptr, data_size, data_mode, 0, data_size);
-+ http_send_response_finish(&s);
-+ return SUCCESS;
-+ }
-+ }
-+ return FAILURE;
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_send_stream(php_stream *) */
-+PHP_HTTP_API STATUS _http_send_stream_ex(php_stream *file, zend_bool close_stream, zend_bool no_cache TSRMLS_DC)
-+{
-+ STATUS status;
-+ php_stream_statbuf ssb;
-+ int orig_flags;
-+
-+ if ((!file) || php_stream_stat(file, &ssb)) {
-+ char *defct = sapi_get_default_content_type(TSRMLS_C);
-+
-+ http_hide_header("Content-Disposition");
-+ http_send_content_type(defct, strlen(defct));
-+ http_error(HE_WARNING, HTTP_E_RESPONSE, "File not found; stat failed");
-+ STR_FREE(defct);
-+
-+ if (HTTP_G->send.not_found_404) {
-+ http_exit_ex(404, NULL, estrdup("File not found\n"), 0);
-+ }
-+ return FAILURE;
-+ }
-+
-+ orig_flags = file->flags;
-+ file->flags |= PHP_STREAM_FLAG_NO_BUFFER;
-+ status = http_send_ex(file, ssb.sb.st_size, SEND_RSRC, no_cache);
-+ file->flags = orig_flags;
-+
-+ if (close_stream) {
-+ php_stream_close(file);
-+ }
-+
-+ return status;
-+}
-+/* }}} */
-+
-+/* {{{ char *http_guess_content_type(char *magic_file, long magic_mode, void *data, size_t size, http_send_mode mode) */
-+PHP_HTTP_API char *_http_guess_content_type(const char *magicfile, long magicmode, void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC)
-+{
-+ char *ct = NULL;
-+
-+#ifdef HTTP_HAVE_MAGIC
-+ struct magic_set *magic = NULL;
-+
-+ HTTP_CHECK_OPEN_BASEDIR(magicfile, return NULL);
-+
-+ if (!data_ptr) {
-+ http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Supplied payload is empty");
-+ } else if (!(magic = magic_open(magicmode &~ MAGIC_MIME))) {
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid magic mode: %ld", magicmode);
-+ } else if (-1 == magic_load(magic, magicfile)) {
-+ http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Failed to load magic database '%s' (%s)", magicfile, magic_error(magic));
-+ } else {
-+ const char *ctype = NULL;
-+
-+ magic_setflags(magic, magicmode);
-+
-+ switch (data_mode) {
-+ case SEND_RSRC:
-+ {
-+ char *buffer;
-+ size_t b_len;
-+
-+ b_len = php_stream_copy_to_mem(data_ptr, &buffer, 65536, 0);
-+ ctype = magic_buffer(magic, buffer, b_len);
-+ efree(buffer);
-+ break;
-+ }
-+
-+ case SEND_DATA:
-+ ctype = magic_buffer(magic, data_ptr, data_len);
-+ break;
-+
-+ default:
-+ HTTP_CHECK_OPEN_BASEDIR(data_ptr, magic_close(magic); return NULL);
-+ ctype = magic_file(magic, data_ptr);
-+ break;
-+ }
-+
-+ if (ctype) {
-+ ct = estrdup(ctype);
-+ } else {
-+ http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Failed to guess Content-Type: %s", magic_error(magic));
-+ }
-+ }
-+ if (magic) {
-+ magic_close(magic);
-+ }
-+#else
-+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot guess Content-Type; libmagic not available");
-+#endif
-+
-+ return ct;
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_url_api.c
-@@ -0,0 +1,482 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_url_api.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#define HTTP_WANT_SAPI
-+#define HTTP_WANT_NETDB
-+#include "php_http.h"
-+
-+#include "zend_ini.h"
-+#include "php_output.h"
-+#include "ext/standard/php_string.h"
-+
-+#include "php_http_api.h"
-+#include "php_http_querystring_api.h"
-+#include "php_http_url_api.h"
-+
-+static inline char *localhostname(void)
-+{
-+ char hostname[1024] = {0};
-+
-+#ifdef PHP_WIN32
-+ if (SUCCESS == gethostname(hostname, lenof(hostname))) {
-+ return estrdup(hostname);
-+ }
-+#elif defined(HAVE_GETHOSTNAME)
-+ if (SUCCESS == gethostname(hostname, lenof(hostname))) {
-+# if defined(HAVE_GETDOMAINNAME)
-+ size_t hlen = strlen(hostname);
-+ if (hlen <= lenof(hostname) - lenof("(none)")) {
-+ hostname[hlen++] = '.';
-+ if (SUCCESS == getdomainname(&hostname[hlen], lenof(hostname) - hlen)) {
-+ if (!strcmp(&hostname[hlen], "(none)")) {
-+ hostname[hlen - 1] = '\0';
-+ }
-+ return estrdup(hostname);
-+ }
-+ }
-+# endif
-+ if (strcmp(hostname, "(none)")) {
-+ return estrdup(hostname);
-+ }
-+ }
-+#endif
-+ return estrndup("localhost", lenof("localhost"));
-+}
-+
-+PHP_MINIT_FUNCTION(http_url)
-+{
-+ HTTP_LONG_CONSTANT("HTTP_URL_REPLACE", HTTP_URL_REPLACE);
-+ HTTP_LONG_CONSTANT("HTTP_URL_JOIN_PATH", HTTP_URL_JOIN_PATH);
-+ HTTP_LONG_CONSTANT("HTTP_URL_JOIN_QUERY", HTTP_URL_JOIN_QUERY);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_USER", HTTP_URL_STRIP_USER);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_PASS", HTTP_URL_STRIP_PASS);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_AUTH", HTTP_URL_STRIP_AUTH);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_PORT", HTTP_URL_STRIP_PORT);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_PATH", HTTP_URL_STRIP_PATH);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_QUERY", HTTP_URL_STRIP_QUERY);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_FRAGMENT", HTTP_URL_STRIP_FRAGMENT);
-+ HTTP_LONG_CONSTANT("HTTP_URL_STRIP_ALL", HTTP_URL_STRIP_ALL);
-+ HTTP_LONG_CONSTANT("HTTP_URL_FROM_ENV", HTTP_URL_FROM_ENV);
-+ return SUCCESS;
-+}
-+
-+PHP_HTTP_API char *_http_absolute_url_ex(const char *url, int flags TSRMLS_DC)
-+{
-+ char *abs = NULL;
-+ php_url *purl = NULL;
-+
-+ if (url) {
-+ purl = php_url_parse(abs = estrdup(url));
-+ STR_SET(abs, NULL);
-+ if (!purl) {
-+ http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", url);
-+ return NULL;
-+ }
-+ }
-+
-+ http_build_url(flags, purl, NULL, NULL, &abs, NULL);
-+
-+ if (purl) {
-+ php_url_free(purl);
-+ }
-+
-+ return abs;
-+}
-+
-+/* {{{ void http_build_url(int flags, const php_url *, const php_url *, php_url **, char **, size_t *) */
-+PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_url *new_url, php_url **url_ptr, char **url_str, size_t *url_len TSRMLS_DC)
-+{
-+#if defined(HAVE_GETSERVBYPORT) || defined(HAVE_GETSERVBYNAME)
-+ struct servent *se;
-+#endif
-+ php_url *url = ecalloc(1, sizeof(php_url));
-+
-+#define __URLSET(u,n) \
-+ ((u)&&(u)->n)
-+#define __URLCPY(n) \
-+ url->n = __URLSET(new_url,n) ? estrdup(new_url->n) : (__URLSET(old_url,n) ? estrdup(old_url->n) : NULL)
-+
-+ if (!(flags & HTTP_URL_STRIP_PORT)) {
-+ url->port = __URLSET(new_url, port) ? new_url->port : ((old_url) ? old_url->port : 0);
-+ }
-+ if (!(flags & HTTP_URL_STRIP_USER)) {
-+ __URLCPY(user);
-+ }
-+ if (!(flags & HTTP_URL_STRIP_PASS)) {
-+ __URLCPY(pass);
-+ }
-+
-+ __URLCPY(scheme);
-+ __URLCPY(host);
-+
-+ if (!(flags & HTTP_URL_STRIP_PATH)) {
-+ if ((flags & HTTP_URL_JOIN_PATH) && __URLSET(old_url, path) && __URLSET(new_url, path) && *new_url->path != '/') {
-+ size_t old_path_len = strlen(old_url->path), new_path_len = strlen(new_url->path);
-+
-+ url->path = ecalloc(1, old_path_len + new_path_len + 1 + 1);
-+
-+ strcat(url->path, old_url->path);
-+ if (url->path[old_path_len - 1] != '/') {
-+ php_dirname(url->path, old_path_len);
-+ strcat(url->path, "/");
-+ }
-+ strcat(url->path, new_url->path);
-+ } else {
-+ __URLCPY(path);
-+ }
-+ }
-+ if (!(flags & HTTP_URL_STRIP_QUERY)) {
-+ if ((flags & HTTP_URL_JOIN_QUERY) && __URLSET(new_url, query) && __URLSET(old_url, query)) {
-+ zval qarr, qstr;
-+
-+ INIT_PZVAL(&qstr);
-+ INIT_PZVAL(&qarr);
-+ array_init(&qarr);
-+
-+ ZVAL_STRING(&qstr, old_url->query, 0);
-+ http_querystring_modify(&qarr, &qstr);
-+ ZVAL_STRING(&qstr, new_url->query, 0);
-+ http_querystring_modify(&qarr, &qstr);
-+
-+ ZVAL_NULL(&qstr);
-+ http_querystring_update(&qarr, &qstr);
-+ url->query = Z_STRVAL(qstr);
-+ zval_dtor(&qarr);
-+ } else {
-+ __URLCPY(query);
-+ }
-+ }
-+ if (!(flags & HTTP_URL_STRIP_FRAGMENT)) {
-+ __URLCPY(fragment);
-+ }
-+
-+ if (!url->scheme) {
-+ if (flags & HTTP_URL_FROM_ENV) {
-+ zval *https = http_get_server_var("HTTPS", 1);
-+ if (https && !strcasecmp(Z_STRVAL_P(https), "ON")) {
-+ url->scheme = estrndup("https", lenof("https"));
-+ } else switch (url->port) {
-+ case 443:
-+ url->scheme = estrndup("https", lenof("https"));
-+ break;
-+
-+#ifndef HAVE_GETSERVBYPORT
-+ default:
-+#endif
-+ case 80:
-+ case 0:
-+ url->scheme = estrndup("http", lenof("http"));
-+ break;
-+
-+#ifdef HAVE_GETSERVBYPORT
-+ default:
-+ if ((se = getservbyport(htons(url->port), "tcp")) && se->s_name) {
-+ url->scheme = estrdup(se->s_name);
-+ } else {
-+ url->scheme = estrndup("http", lenof("http"));
-+ }
-+ break;
-+#endif
-+ }
-+ } else {
-+ url->scheme = estrndup("http", lenof("http"));
-+ }
-+ }
-+
-+ if (!url->host) {
-+ if (flags & HTTP_URL_FROM_ENV) {
-+ zval *zhost;
-+
-+ if ((((zhost = http_get_server_var("HTTP_HOST", 1)) ||
-+ (zhost = http_get_server_var("SERVER_NAME", 1)))) && Z_STRLEN_P(zhost)) {
-+ url->host = estrndup(Z_STRVAL_P(zhost), Z_STRLEN_P(zhost));
-+ } else {
-+ url->host = localhostname();
-+ }
-+ } else {
-+ url->host = estrndup("localhost", lenof("localhost"));
-+ }
-+ }
-+
-+ if (!url->path) {
-+ if ((flags & HTTP_URL_FROM_ENV) && SG(request_info).request_uri && SG(request_info).request_uri[0]) {
-+ const char *q = strchr(SG(request_info).request_uri, '?');
-+
-+ if (q) {
-+ url->path = estrndup(SG(request_info).request_uri, q - SG(request_info).request_uri);
-+ } else {
-+ url->path = estrdup(SG(request_info).request_uri);
-+ }
-+ } else {
-+ url->path = estrndup("/", 1);
-+ }
-+ } else if (url->path[0] != '/') {
-+ if ((flags & HTTP_URL_FROM_ENV) && SG(request_info).request_uri && SG(request_info).request_uri[0]) {
-+ size_t ulen = strlen(SG(request_info).request_uri);
-+ size_t plen = strlen(url->path);
-+ char *path;
-+
-+ if (SG(request_info).request_uri[ulen-1] != '/') {
-+ for (--ulen; ulen && SG(request_info).request_uri[ulen - 1] != '/'; --ulen);
-+ }
-+
-+ path = emalloc(ulen + plen + 1);
-+ memcpy(path, SG(request_info).request_uri, ulen);
-+ memcpy(path + ulen, url->path, plen);
-+ path[ulen + plen] = '\0';
-+ STR_SET(url->path, path);
-+ } else {
-+ size_t plen = strlen(url->path);
-+ char *path = emalloc(plen + 1 + 1);
-+
-+ path[0] = '/';
-+ memcpy(&path[1], url->path, plen + 1);
-+ STR_SET(url->path, path);
-+ }
-+ }
-+ /* replace directory references if path is not a single slash */
-+ if (url->path[0] && (url->path[0] != '/' || url->path[1])) {
-+ char *ptr, *end = url->path + strlen(url->path) + 1;
-+
-+ for (ptr = strstr(url->path, "/."); ptr; ptr = strstr(ptr, "/.")) {
-+ switch (ptr[2]) {
-+ case '\0':
-+ ptr[1] = '\0';
-+ break;
-+
-+ case '/':
-+ memmove(&ptr[1], &ptr[3], end - &ptr[3]);
-+ break;
-+
-+ case '.':
-+ if (ptr[3] == '/') {
-+ char *pos = &ptr[4];
-+ while (ptr != url->path) {
-+ if (*--ptr == '/') {
-+ break;
-+ }
-+ }
-+ memmove(&ptr[1], pos, end - pos);
-+ break;
-+ } else if (!ptr[3]) {
-+ /* .. at the end */
-+ ptr[1] = '\0';
-+ }
-+ /* fallthrough */
-+
-+ default:
-+ /* something else */
-+ ++ptr;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (url->port) {
-+ if ( ((url->port == 80) && !strcmp(url->scheme, "http"))
-+ || ((url->port ==443) && !strcmp(url->scheme, "https"))
-+#ifdef HAVE_GETSERVBYNAME
-+ || ((se = getservbyname(url->scheme, "tcp")) && se->s_port &&
-+ (url->port == ntohs(se->s_port)))
-+#endif
-+ ) {
-+ url->port = 0;
-+ }
-+ }
-+
-+ if (url_str) {
-+ size_t len;
-+
-+ *url_str = emalloc(HTTP_URL_MAXLEN + 1);
-+
-+ **url_str = '\0';
-+ strlcat(*url_str, url->scheme, HTTP_URL_MAXLEN);
-+ strlcat(*url_str, "://", HTTP_URL_MAXLEN);
-+
-+ if (url->user && *url->user) {
-+ strlcat(*url_str, url->user, HTTP_URL_MAXLEN);
-+ if (url->pass && *url->pass) {
-+ strlcat(*url_str, ":", HTTP_URL_MAXLEN);
-+ strlcat(*url_str, url->pass, HTTP_URL_MAXLEN);
-+ }
-+ strlcat(*url_str, "@", HTTP_URL_MAXLEN);
-+ }
-+
-+ strlcat(*url_str, url->host, HTTP_URL_MAXLEN);
-+
-+ if (url->port) {
-+ char port_str[8];
-+
-+ snprintf(port_str, sizeof(port_str), "%d", (int) url->port);
-+ strlcat(*url_str, ":", HTTP_URL_MAXLEN);
-+ strlcat(*url_str, port_str, HTTP_URL_MAXLEN);
-+ }
-+
-+ strlcat(*url_str, url->path, HTTP_URL_MAXLEN);
-+
-+ if (url->query && *url->query) {
-+ strlcat(*url_str, "?", HTTP_URL_MAXLEN);
-+ strlcat(*url_str, url->query, HTTP_URL_MAXLEN);
-+ }
-+
-+ if (url->fragment && *url->fragment) {
-+ strlcat(*url_str, "#", HTTP_URL_MAXLEN);
-+ strlcat(*url_str, url->fragment, HTTP_URL_MAXLEN);
-+ }
-+
-+ if (HTTP_URL_MAXLEN == (len = strlen(*url_str))) {
-+ http_error(HE_NOTICE, HTTP_E_URL, "Length of URL exceeds HTTP_URL_MAXLEN");
-+ }
-+ if (url_len) {
-+ *url_len = len;
-+ }
-+ }
-+
-+ if (url_ptr) {
-+ *url_ptr = url;
-+ } else {
-+ php_url_free(url);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ STATUS http_urlencode_hash_ex(HashTable *, zend_bool, char *, size_t, char **, size_t *) */
-+PHP_HTTP_API STATUS _http_urlencode_hash_ex(HashTable *hash, zend_bool override_argsep,
-+ char *pre_encoded_data, size_t pre_encoded_len,
-+ char **encoded_data, size_t *encoded_len TSRMLS_DC)
-+{
-+ char *arg_sep;
-+ size_t arg_sep_len;
-+ phpstr *qstr = phpstr_new();
-+
-+ if (override_argsep || !(arg_sep_len = strlen(arg_sep = INI_STR("arg_separator.output")))) {
-+ arg_sep = HTTP_URL_ARGSEP;
-+ arg_sep_len = lenof(HTTP_URL_ARGSEP);
-+ }
-+
-+ if (pre_encoded_len && pre_encoded_data) {
-+ phpstr_append(qstr, pre_encoded_data, pre_encoded_len);
-+ }
-+
-+ if (SUCCESS != http_urlencode_hash_recursive(hash, qstr, arg_sep, arg_sep_len, NULL, 0)) {
-+ phpstr_free(&qstr);
-+ return FAILURE;
-+ }
-+
-+ phpstr_data(qstr, encoded_data, encoded_len);
-+ phpstr_free(&qstr);
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/* {{{ http_urlencode_hash_recursive */
-+PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, const char *arg_sep, size_t arg_sep_len, const char *prefix, size_t prefix_len TSRMLS_DC)
-+{
-+ HashKey key = initHashKey(0);
-+ zval **data = NULL;
-+ HashPosition pos;
-+
-+ if (!ht || !str) {
-+ http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid parameters");
-+ return FAILURE;
-+ }
-+ if (ht->nApplyCount > 0) {
-+ return SUCCESS;
-+ }
-+
-+ FOREACH_HASH_KEYVAL(pos, ht, key, data) {
-+ char *encoded_key;
-+ int encoded_len;
-+ phpstr new_prefix;
-+
-+ if (!data || !*data) {
-+ phpstr_dtor(str);
-+ return FAILURE;
-+ }
-+
-+ if (key.type == HASH_KEY_IS_STRING) {
-+ if (!*key.str) {
-+ /* only public properties */
-+ continue;
-+ }
-+ if (key.len && key.str[key.len - 1] == '\0') {
-+ --key.len;
-+ }
-+ encoded_key = php_url_encode(key.str, key.len, &encoded_len);
-+ } else {
-+ encoded_len = spprintf(&encoded_key, 0, "%ld", key.num);
-+ }
-+
-+ {
-+ phpstr_init(&new_prefix);
-+ if (prefix && prefix_len) {
-+ phpstr_append(&new_prefix, prefix, prefix_len);
-+ phpstr_appends(&new_prefix, "%5B");
-+ }
-+
-+ phpstr_append(&new_prefix, encoded_key, encoded_len);
-+ efree(encoded_key);
-+
-+ if (prefix && prefix_len) {
-+ phpstr_appends(&new_prefix, "%5D");
-+ }
-+ phpstr_fix(&new_prefix);
-+ }
-+
-+ if (Z_TYPE_PP(data) == IS_ARRAY || Z_TYPE_PP(data) == IS_OBJECT) {
-+ STATUS status;
-+ ++ht->nApplyCount;
-+ status = http_urlencode_hash_recursive(HASH_OF(*data), str, arg_sep, arg_sep_len, PHPSTR_VAL(&new_prefix), PHPSTR_LEN(&new_prefix));
-+ --ht->nApplyCount;
-+ if (SUCCESS != status) {
-+ phpstr_dtor(&new_prefix);
-+ phpstr_dtor(str);
-+ return FAILURE;
-+ }
-+ } else {
-+ zval *val = http_zsep(IS_STRING, *data);
-+
-+ if (PHPSTR_LEN(str)) {
-+ phpstr_append(str, arg_sep, arg_sep_len);
-+ }
-+ phpstr_append(str, PHPSTR_VAL(&new_prefix), PHPSTR_LEN(&new_prefix));
-+ phpstr_appends(str, "=");
-+
-+ if (Z_STRLEN_P(val) && Z_STRVAL_P(val)) {
-+ char *encoded_val;
-+ int encoded_len;
-+
-+ encoded_val = php_url_encode(Z_STRVAL_P(val), Z_STRLEN_P(val), &encoded_len);
-+ phpstr_append(str, encoded_val, encoded_len);
-+ efree(encoded_val);
-+ }
-+
-+ zval_ptr_dtor(&val);
-+ }
-+ phpstr_dtor(&new_prefix);
-+ }
-+ return SUCCESS;
-+}
-+/* }}} */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/http_util_object.c
-@@ -0,0 +1,158 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: http_util_object.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#include "php_http.h"
-+
-+#ifdef ZEND_ENGINE_2
-+
-+#include "ext/standard/php_http.h"
-+
-+#include "php_http_util_object.h"
-+
-+#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpUtil, method, 0, req_args)
-+#define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpUtil, method, 0)
-+
-+#define HTTP_UTIL_ALIAS(method, func) HTTP_STATIC_ME_ALIAS(method, func, HTTP_ARGS(HttpUtil, method))
-+
-+HTTP_BEGIN_ARGS(date, 0)
-+ HTTP_ARG_VAL(timestamp, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(buildStr, 1)
-+ HTTP_ARG_VAL(query, 0)
-+ HTTP_ARG_VAL(prefix, 0)
-+ HTTP_ARG_VAL(arg_sep, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(buildUrl, 1)
-+ HTTP_ARG_VAL(url, 0)
-+ HTTP_ARG_VAL(parts, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+ HTTP_ARG_VAL(composed, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(negotiateLanguage, 1)
-+ HTTP_ARG_VAL(supported, 0)
-+ HTTP_ARG_VAL(result, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(negotiateCharset, 1)
-+ HTTP_ARG_VAL(supported, 0)
-+ HTTP_ARG_VAL(result, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(negotiateContentType, 1)
-+ HTTP_ARG_VAL(supported, 0)
-+ HTTP_ARG_VAL(result, 1)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(matchModified, 1)
-+ HTTP_ARG_VAL(last_modified, 0)
-+ HTTP_ARG_VAL(for_range, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(matchEtag, 1)
-+ HTTP_ARG_VAL(plain_etag, 0)
-+ HTTP_ARG_VAL(for_range, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(matchRequestHeader, 2)
-+ HTTP_ARG_VAL(header_name, 0)
-+ HTTP_ARG_VAL(header_value, 0)
-+ HTTP_ARG_VAL(case_sensitive, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(parseMessage, 1)
-+ HTTP_ARG_VAL(message_string, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(parseHeaders, 1)
-+ HTTP_ARG_VAL(headers_string, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(parseCookie, 1)
-+ HTTP_ARG_VAL(cookie_string, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(buildCookie, 1)
-+ HTTP_ARG_VAL(cookie_array, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(parseParams, 1)
-+ HTTP_ARG_VAL(param_string, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(chunkedDecode, 1)
-+ HTTP_ARG_VAL(encoded_string, 0)
-+HTTP_END_ARGS;
-+
-+#ifdef HTTP_HAVE_ZLIB
-+HTTP_BEGIN_ARGS(deflate, 1)
-+ HTTP_ARG_VAL(plain, 0)
-+ HTTP_ARG_VAL(flags, 0)
-+HTTP_END_ARGS;
-+
-+HTTP_BEGIN_ARGS(inflate, 1)
-+ HTTP_ARG_VAL(encoded, 0)
-+HTTP_END_ARGS;
-+#endif
-+
-+HTTP_BEGIN_ARGS(support, 0)
-+ HTTP_ARG_VAL(feature, 0)
-+HTTP_END_ARGS;
-+
-+zend_class_entry *http_util_object_ce;
-+zend_function_entry http_util_object_fe[] = {
-+ HTTP_UTIL_ALIAS(date, http_date)
-+ HTTP_UTIL_ALIAS(buildUrl, http_build_url)
-+ HTTP_UTIL_ALIAS(buildStr, http_build_str)
-+ HTTP_UTIL_ALIAS(negotiateLanguage, http_negotiate_language)
-+ HTTP_UTIL_ALIAS(negotiateCharset, http_negotiate_charset)
-+ HTTP_UTIL_ALIAS(negotiateContentType, http_negotiate_content_type)
-+ HTTP_UTIL_ALIAS(matchModified, http_match_modified)
-+ HTTP_UTIL_ALIAS(matchEtag, http_match_etag)
-+ HTTP_UTIL_ALIAS(matchRequestHeader, http_match_request_header)
-+ HTTP_UTIL_ALIAS(parseMessage, http_parse_message)
-+ HTTP_UTIL_ALIAS(parseHeaders, http_parse_headers)
-+ HTTP_UTIL_ALIAS(parseCookie, http_parse_cookie)
-+ HTTP_UTIL_ALIAS(buildCookie, http_build_cookie)
-+ HTTP_UTIL_ALIAS(parseParams, http_parse_params)
-+ HTTP_UTIL_ALIAS(chunkedDecode, http_chunked_decode)
-+#ifdef HTTP_HAVE_ZLIB
-+ HTTP_UTIL_ALIAS(deflate, http_deflate)
-+ HTTP_UTIL_ALIAS(inflate, http_inflate)
-+#endif /* HTTP_HAVE_ZLIB */
-+ HTTP_UTIL_ALIAS(support, http_support)
-+
-+ EMPTY_FUNCTION_ENTRY
-+};
-+
-+PHP_MINIT_FUNCTION(http_util_object)
-+{
-+ HTTP_REGISTER_CLASS(HttpUtil, http_util_object, NULL, 0);
-+ return SUCCESS;
-+}
-+
-+#endif /* ZEND_ENGINE_2 */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/lib/BigGet.php
-@@ -0,0 +1,213 @@
-+<?php
-+
-+/**
-+ * BigGet - download big files efficiently
-+ * $Id: BigGet.php 220502 2006-09-25 08:27:32Z mike $
-+ *
-+ * @copyright Michael Wallner, <mike@iworks.at>
-+ * @license BSD, revised
-+ * @version $Revision: 220502 $
-+ */
-+class BigGet extends HttpRequestPool
-+{
-+ /**
-+ * File split size
-+ */
-+ const SIZE = 1048576;
-+
-+ /**
-+ * Parallel Request count
-+ */
-+ const RMAX = 5;
-+
-+ /**
-+ * Whether to output debug messages
-+ *
-+ * @var bool
-+ */
-+ public $dbg = false;
-+
-+ /**
-+ * URL
-+ *
-+ * @var string
-+ */
-+ private $url;
-+
-+ /**
-+ * Temp file prefix
-+ *
-+ * @var string
-+ */
-+ private $tmp;
-+
-+ /**
-+ * Size of requested resource
-+ *
-+ * @var int
-+ */
-+ private $size;
-+
-+ /**
-+ * Whether the requests have been sent
-+ *
-+ * @var bool
-+ */
-+ private $sent = false;
-+
-+ /**
-+ * Request counter
-+ *
-+ * @var int
-+ */
-+ private $count = 0;
-+
-+ /**
-+ * Static constructor
-+ *
-+ * @param string $url
-+ * @param string $tmp
-+ * @return BigGet
-+ * @throws Exception
-+ */
-+ public static function url($url, $tmp = '/tmp')
-+ {
-+ $head = new HttpRequest($url, HttpRequest::METH_HEAD);
-+ $headers = $head->send()->getHeaders();
-+
-+ if (200 != $head->getResponseCode()) {
-+ throw new HttpException("Did not receive '200 Ok' from HEAD $url");
-+ }
-+ if (!isset($headers['Accept-Ranges'])) {
-+ throw new HttpException("Did not receive an Accept-Ranges header from HEAD $url");
-+ }
-+ if (!isset($headers['Content-Length'])) {
-+ throw new HttpException("Did not receive a Content-Length header from HEAD $url");
-+ }
-+
-+ $bigget = new BigGet;
-+ $bigget->url = $url;
-+ $bigget->tmp = tempnam($tmp, 'BigGet.');
-+ $bigget->size = $headers['Content-Length'];
-+ return $bigget;
-+ }
-+
-+ /**
-+ * Save the resource to a file
-+ *
-+ * @param string $file
-+ * @return bool
-+ * @throws Exception
-+ */
-+ public function saveTo($file)
-+ {
-+ $this->sent or $this->send();
-+
-+ if ($w = fopen($this->tmp, 'wb')) {
-+
-+ $this->dbg && print "\nCopying temp files to $file ...\n";
-+
-+ foreach (glob($this->tmp .".????") as $tmp) {
-+
-+ $this->dbg && print "\t$tmp\n";
-+
-+ if ($r = fopen($tmp, 'rb')) {
-+ stream_copy_to_stream($r, $w);
-+ fclose($r);
-+ }
-+ unlink($tmp);
-+ }
-+ fclose($w);
-+ rename($this->tmp, $file);
-+
-+ $this->dbg && print "\nDone.\n";
-+
-+ return true;
-+ }
-+ return false;
-+ }
-+
-+ /**
-+ * Overrides HttpRequestPool::send()
-+ *
-+ * @return void
-+ * @throws Exception
-+ */
-+ public function send()
-+ {
-+ $this->sent = true;
-+
-+ // use max RMAX simultanous requests with a req size of SIZE
-+ while ($this->count < self::RMAX && -1 != $offset = $this->getRangeOffset()) {
-+ $this->attachNew($offset);
-+ }
-+
-+ while ($this->socketPerform()) {
-+ if (!$this->socketSelect()) {
-+ throw new HttpSocketException;
-+ }
-+ }
-+ }
-+
-+ /**
-+ * Overrides HttpRequestPool::socketPerform()
-+ *
-+ * @return bool
-+ */
-+ protected function socketPerform()
-+ {
-+ $rs = parent::socketPerform();
-+
-+ foreach ($this->getFinishedRequests() as $r) {
-+ $this->detach($r);
-+
-+ if (206 != $rc = $r->getResponseCode()) {
-+ throw new HttpException("Unexpected response code: $rc");
-+ }
-+
-+ file_put_contents(sprintf("%s.%04d", $this->tmp, $r->id), $r->getResponseBody());
-+
-+ if (-1 != $offset = $this->getRangeOffset()) {
-+ $this->attachNew($offset);
-+ }
-+ }
-+
-+ return $rs;
-+ }
-+
-+ private function attachNew($offset)
-+ {
-+ $stop = min($this->count * self::SIZE + self::SIZE, $this->size) - 1;
-+
-+ $this->dbg && print "Attaching new request to get range: $offset-$stop\n";
-+
-+ $req = new BigGetRequest(
-+ $this->url,
-+ HttpRequest::METH_GET,
-+ array(
-+ 'headers' => array(
-+ 'Range' => "bytes=$offset-$stop"
-+ )
-+ )
-+ );
-+ $this->attach($req);
-+ $req->id = $this->count++;
-+ }
-+
-+ private function getRangeOffset()
-+ {
-+ return ($this->size >= $start = $this->count * self::SIZE) ? $start : -1;
-+ }
-+}
-+
-+
-+/**
-+ * BigGet request
-+ * @ignore
-+ */
-+class BigGetRequest extends HttpRequest
-+{
-+ public $id;
-+}
-+
-+?>
---- /dev/null
-+++ b/ext/http/lib/FeedAggregator.php
-@@ -0,0 +1,187 @@
-+<?php
-+
-+/**
-+ * Simple Feed Aggregator
-+ * $Id: FeedAggregator.php 208774 2006-03-06 16:07:19Z mike $
-+ *
-+ * @copyright Michael Wallner, <mike@iworks.at>
-+ * @license BSD, revised
-+ * @package pecl/http
-+ * @version $Revision: 208774 $
-+ */
-+class FeedAggregator
-+{
-+ /**
-+ * Cache directory
-+ *
-+ * @var string
-+ */
-+ public $directory;
-+
-+ /**
-+ * Feeds
-+ *
-+ * @var array
-+ */
-+ protected $feeds = array();
-+
-+ /**
-+ * Constructor
-+ *
-+ * @param string $directory
-+ */
-+ public function __construct($directory = 'feeds')
-+ {
-+ $this->setDirectory($directory);
-+ }
-+
-+ /**
-+ * Set cache directory
-+ *
-+ * @param string $directory
-+ */
-+ public function setDirectory($directory)
-+ {
-+ $this->directory = $directory;
-+ foreach (glob($this->directory .'/*.xml') as $feed) {
-+ $this->feeds[basename($feed, '.xml')] = filemtime($feed);
-+ }
-+ }
-+
-+ /**
-+ * Strips all special chars
-+ *
-+ * @param string $url
-+ * @return string
-+ */
-+ public function url2name($url)
-+ {
-+ return preg_replace('/[^\w\.-]+/', '_', $url);
-+ }
-+
-+ /**
-+ * Checks if $url is a known feed
-+ *
-+ * @param string $url
-+ * @return bool
-+ */
-+ public function hasFeed($url)
-+ {
-+ return isset($this->feeds[$this->url2name($url)]);
-+ }
-+
-+ /**
-+ * Add an URL as feed
-+ *
-+ * @param string $url
-+ * @return void
-+ * @throws Exception
-+ */
-+ public function addFeed($url)
-+ {
-+ $r = $this->setupRequest($url);
-+ $r->send();
-+ $this->handleResponse($r);
-+ }
-+
-+ /**
-+ * Add several URLs as feeds
-+ *
-+ * @param array $urls
-+ * @return void
-+ * @throws Exception
-+ */
-+ public function addFeeds(array $urls)
-+ {
-+ $pool = new HttpRequestPool;
-+ foreach ($urls as $url) {
-+ $pool->attach($r = $this->setupRequest($url));
-+ }
-+ $pool->send();
-+
-+ foreach ($pool as $request) {
-+ $this->handleResponse($request);
-+ }
-+ }
-+
-+ /**
-+ * Load a feed (from cache)
-+ *
-+ * @param string $url
-+ * @return string
-+ * @throws Exception
-+ */
-+ public function getFeed($url)
-+ {
-+ $this->addFeed($url);
-+ return $this->loadFeed($this->url2name($url));
-+ }
-+
-+ /**
-+ * Load several feeds (from cache)
-+ *
-+ * @param array $urls
-+ * @return array
-+ * @throws Exception
-+ */
-+ public function getFeeds(array $urls)
-+ {
-+ $feeds = array();
-+ $this->addFeeds($urls);
-+ foreach ($urls as $url) {
-+ $feeds[] = $this->loadFeed($this->url2name($url));
-+ }
-+ return $feeds;
-+ }
-+
-+ protected function saveFeed($file, $contents)
-+ {
-+ if (file_put_contents($this->directory .'/'. $file .'.xml', $contents)) {
-+ $this->feeds[$file] = time();
-+ } else {
-+ throw new Exception("Could not save feed contents to $file.xml");
-+ }
-+ }
-+
-+ protected function loadFeed($file)
-+ {
-+ if (isset($this->feeds[$file])) {
-+ if ($data = file_get_contents($this->directory .'/'. $file .'.xml')) {
-+ return $data;
-+ } else {
-+ throw new Exception("Could not load feed contents from $file.xml");
-+ }
-+ } else {
-+ throw new Exception("Unknown feed/file $file.xml");
-+ }
-+ }
-+
-+ protected function setupRequest($url, $escape = true)
-+ {
-+ $r = new HttpRequest($url);
-+ $r->setOptions(array('redirect' => true));
-+
-+ $file = $escape ? $this->url2name($url) : $url;
-+
-+ if (isset($this->feeds[$file])) {
-+ $r->setOptions(array('lastmodified' => $this->feeds[$file]));
-+ }
-+
-+ return $r;
-+ }
-+
-+ protected function handleResponse(HttpRequest $r)
-+ {
-+ if ($r->getResponseCode() != 304) {
-+ if ($r->getResponseCode() != 200) {
-+ throw new Exception("Unexpected response code ". $r->getResponseCode());
-+ }
-+ if (!strlen($body = $r->getResponseBody())) {
-+ throw new Exception("Received empty feed from ". $r->getUrl());
-+ }
-+ $this->saveFeed($this->url2name($r->getUrl()), $body);
-+ }
-+ }
-+}
-+
-+?>
---- /dev/null
-+++ b/ext/http/lib/PgLobStream.php
-@@ -0,0 +1,100 @@
-+<?php
-+
-+/**
-+ * PostgreSQL LOB stream
-+ * $Id: PgLobStream.php 210232 2006-03-27 17:41:25Z mike $
-+ *
-+ * Usage:
-+ * <code>
-+ * // GET /image.php?image=1234
-+ * if (PgLobStream::$loId = (int) $_GET['image']) {
-+ * if ($lob = fopen('pglob://dbname=database user=mike', 'r')) {
-+ * HttpResponse::setContentType('image/jpeg');
-+ * HttpResponse::setStream($lob);
-+ * HttpResponse::send();
-+ * }
-+ * }
-+ * </code>
-+ *
-+ * @copyright Michael Wallner, <mike@iworks.at>
-+ * @license BSD, revised
-+ * @package pecl/http
-+ * @version $Revision: 210232 $
-+ */
-+class PgLobStream
-+{
-+ private $dbh;
-+ private $loh;
-+ private $lon;
-+ private $size = 0;
-+
-+ public static $loId;
-+
-+ function stream_open($path, $mode)
-+ {
-+ $path = trim(parse_url($path, PHP_URL_HOST));
-+
-+ if ($path) {
-+ if ($this->dbh = pg_connect($path)) {
-+ if (pg_query($this->dbh, 'BEGIN')) {
-+ if (is_resource($this->loh = pg_lo_open($this->dbh, $this->lon = self::$loId, $mode))) {
-+ pg_lo_seek($this->loh, 0, PGSQL_SEEK_END);
-+ $this->size = (int) pg_lo_tell($this->loh);
-+ pg_lo_seek($this->loh, 0, PGSQL_SEEK_SET);
-+ return true;
-+ }
-+ }
-+ }
-+ }
-+ return false;
-+ }
-+
-+ function stream_read($length)
-+ {
-+ return pg_lo_read($this->loh, $length);
-+ }
-+
-+ function stream_seek($offset, $whence = PGSQL_SEEK_SET)
-+ {
-+ return pg_lo_seek($this->loh, $offset, $whence);
-+ }
-+
-+ function stream_tell()
-+ {
-+ return pg_lo_tell($this->loh);
-+ }
-+
-+ function stream_eof()
-+ {
-+ return pg_lo_tell($this->loh) >= $this->size;
-+ }
-+
-+ function stream_flush()
-+ {
-+ return true;
-+ }
-+
-+ function stream_stat()
-+ {
-+ return array('size' => $this->size, 'ino' => $this->lon);
-+ }
-+
-+ function stream_write($data)
-+ {
-+ return pg_lo_write($this->loh, $data);
-+ }
-+
-+ function stream_close()
-+ {
-+ if (pg_lo_close($this->loh)) {
-+ return pg_query($this->dbh, 'COMMIT');
-+ } else {
-+ pg_query($this->dbh, 'ROLLBACK');
-+ return false;
-+ }
-+ }
-+}
-+
-+stream_register_wrapper('pglob', 'PgLobStream');
-+
-+?>
---- /dev/null
-+++ b/ext/http/lib/XmlRpcClient.php
-@@ -0,0 +1,119 @@
-+<?php
-+
-+/**
-+ * XMLRPC Client, very KISS
-+ * $Id: XmlRpcClient.php 227268 2007-01-15 08:01:35Z mike $
-+ *
-+ * NOTE: requires ext/xmlrpc
-+ *
-+ * Usage:
-+ * <code>
-+ * <?php
-+ * $rpc = new XmlRpcClient('http://mike:secret@example.com/cgi-bin/vpop-xmlrpc');
-+ * $rpc->__request->setOptions(array('compress' => true));
-+ * try {
-+ * print_r($rpc->vpop->listdomain(array('domain' => 'example.com')));
-+ * } catch (Exception $ex) {
-+ * echo $ex;
-+ * }
-+ * ?>
-+ * </code>
-+ *
-+ * @copyright Michael Wallner, <mike@iworks.at>
-+ * @license BSD, revised
-+ * @package pecl/http
-+ * @version $Revision: 227268 $
-+ */
-+class XmlRpcClient
-+{
-+ /**
-+ * RPC namespace
-+ *
-+ * @var string
-+ */
-+ public $__namespace;
-+
-+ /**
-+ * HttpRequest instance
-+ *
-+ * @var HttpRequest
-+ */
-+ public $__request;
-+
-+ /**
-+ * Client charset
-+ *
-+ * @var string
-+ */
-+ public $__encoding = "iso-8859-1";
-+
-+ /**
-+ * RPC options
-+ *
-+ * @var array
-+ */
-+ public $__options;
-+
-+ /**
-+ * Constructor
-+ *
-+ * @param string $url RPC endpoint
-+ * @param string $namespace RPC namespace
-+ * @param array $options HttpRequest options
-+ */
-+ public function __construct($url, $namespace = '', array $options = null)
-+ {
-+ $this->__request = new HttpRequest($url, HttpRequest::METH_POST, (array) $options);
-+ $this->__namespace = $namespace;
-+ }
-+
-+ /**
-+ * RPC method proxy
-+ *
-+ * @param string $method RPC method name
-+ * @param array $params RPC method arguments
-+ * @return mixed decoded RPC response
-+ * @throws Exception
-+ */
-+ public function __call($method, array $params)
-+ {
-+ if (strlen($this->__namespace)) {
-+ $method = $this->__namespace .'.'. $method;
-+ }
-+ $this->__request->setContentType("text/xml");
-+ $this->__request->setRawPostData(
-+ xmlrpc_encode_request($method, $params,
-+ array("encoding" => $this->__encoding) + (array) $this->__options));
-+ $response = $this->__request->send();
-+ if ($response->getResponseCode() != 200) {
-+ throw new Exception(
-+ $response->getResponseStatus(),
-+ $response->getResponseCode()
-+ );
-+ }
-+
-+ $data = xmlrpc_decode($response->getBody(), $this->__encoding);
-+ if (xmlrpc_is_fault($data)) {
-+ throw new Exception(
-+ (string) $data['faultString'],
-+ (int) $data['faultCode']
-+ );
-+ }
-+
-+ return $data;
-+ }
-+
-+ /**
-+ * Returns self, where namespace is set to variable name
-+ *
-+ * @param string $ns
-+ * @return XmlRpcRequest
-+ */
-+ public function __get($ns)
-+ {
-+ $this->__namespace = $ns;
-+ return $this;
-+ }
-+}
-+
-+?>
---- /dev/null
-+++ b/ext/http/lib/XmlRpcServer.php
-@@ -0,0 +1,254 @@
-+<?php
-+
-+XmlRpcServer::setContentType("text/xml");
-+XmlRpcServer::capture();
-+
-+/**
-+ * XMLRPC Server, very KISS
-+ * $Id: XmlRpcServer.php 227268 2007-01-15 08:01:35Z mike $
-+ *
-+ * NOTE: requires ext/xmlrpc
-+ *
-+ * Usage:
-+ * <code>
-+ * <?php
-+ * class Handler extends XmlRpcRequestHandlerStub {
-+ * public function xmlrpcPing(array $values) {
-+ * return true;
-+ * }
-+ * }
-+ * try {
-+ * XmlRpcServer::factory("namespace")->registerHandler(new Handler);
-+ * XmlRpcServer::run();
-+ * } catch (Exception $ex) {
-+ * XmlRpcServer::error($ex->getCode(), $ex->getMessage());
-+ * }
-+ * </code>
-+ *
-+ * @copyright Michael Wallner, <mike@iworks.at>
-+ * @license BSD, revised
-+ * @package pecl/http
-+ * @version $Revision: 227268 $
-+ */
-+
-+class XmlRpcServer extends HttpResponse
-+{
-+ /**
-+ * Server charset
-+ *
-+ * @var string
-+ */
-+ public static $encoding = "iso-8859-1";
-+
-+ /**
-+ * RPC namespace
-+ *
-+ * @var string
-+ */
-+ public $namespace;
-+
-+ /**
-+ * RPC handler attached to this server instance
-+ *
-+ * @var XmlRpcRequestHandler
-+ */
-+ protected $handler;
-+
-+ private static $xmlreq;
-+ private static $xmlrpc;
-+ private static $refcnt = 0;
-+ private static $handle = array();
-+
-+ /**
-+ * Create a new XmlRpcServer instance
-+ *
-+ * @param string $namespace
-+ * @param string $encoding
-+ */
-+ public function __construct($namespace)
-+ {
-+ $this->namespace = $namespace;
-+ self::initialize();
-+ }
-+
-+ /**
-+ * Destructor
-+ */
-+ public function __destruct()
-+ {
-+ if (self::$refcnt && !--self::$refcnt) {
-+ xmlrpc_server_destroy(self::$xmlrpc);
-+ }
-+ }
-+
-+ /**
-+ * Static factory
-+ *
-+ * @param string $namespace
-+ * @return XmlRpcServer
-+ */
-+ public static function factory($namespace)
-+ {
-+ return new XmlRpcServer($namespace);
-+ }
-+
-+ /**
-+ * Run all servers and send response
-+ *
-+ * @param array $options
-+ */
-+ public static function run(array $options = null)
-+ {
-+ self::initialize(false, true);
-+ self::setContentType("text/xml; charset=". self::$encoding);
-+ echo xmlrpc_server_call_method(self::$xmlrpc, self::$xmlreq, null,
-+ array("encoding" => self::$encoding) + (array) $options);
-+ }
-+
-+ /**
-+ * Test hook; call instead of XmlRpcServer::run()
-+ *
-+ * @param string $method
-+ * @param array $params
-+ * @param array $request_options
-+ * @param array $response_options
-+ */
-+ public static function test($method, array $params, array $request_options = null, array $response_options = null)
-+ {
-+ self::$xmlreq = xmlrpc_encode_request($method, $params, $request_options);
-+ self::run($response_options);
-+ }
-+
-+ /**
-+ * Optional XMLRPC error handler
-+ *
-+ * @param int $code
-+ * @param string $msg
-+ */
-+ public static function error($code, $msg, array $options = null)
-+ {
-+ echo xmlrpc_encode(array("faultCode" => $code, "faultString" => $msg),
-+ array("encoding" => self::$encoding) + (array) $options);
-+ }
-+
-+ /**
-+ * Register a single method
-+ *
-+ * @param string $name
-+ * @param mixed $callback
-+ * @param mixed $dispatch
-+ * @param array $spec
-+ */
-+ public function registerMethod($name, $callback, $dispatch = null, array $spec = null)
-+ {
-+ if (!is_callable($callback, false, $cb_name)) {
-+ throw new Exception("$cb_name is not a valid callback");
-+ }
-+ if (isset($dispatch)) {
-+ if (!is_callable($dispatch, false, $cb_name)) {
-+ throw new Exception("$cb_name is not a valid callback");
-+ }
-+ xmlrpc_server_register_method(self::$xmlrpc, $name, $dispatch);
-+ self::$handle[$name] = $callback;
-+ } else {
-+ xmlrpc_server_register_method(self::$xmlrpc, $name, $callback);
-+ }
-+
-+ if (isset($spec)) {
-+ xmlrpc_server_add_introspection_data(self::$xmlrpc, $spec);
-+ }
-+ }
-+
-+ /**
-+ * Register an XmlRpcRequestHandler for this server instance
-+ *
-+ * @param XmlRpcRequestHandler $handler
-+ */
-+ public function registerHandler(XmlRpcRequestHandler $handler)
-+ {
-+ $this->handler = $handler;
-+
-+ foreach (get_class_methods($handler) as $method) {
-+ if (!strncmp($method, "xmlrpc", 6)) {
-+ $this->registerMethod(
-+ $this->method($method, $handler->getNamespace()),
-+ array($handler, $method), array($this, "dispatch"));
-+ }
-+ }
-+
-+ $handler->getIntrospectionData($spec);
-+ if (is_array($spec)) {
-+ xmlrpc_server_add_introspection_data(self::$xmlrpc, $spec);
-+ }
-+ }
-+
-+ private function method($method, $namespace = null)
-+ {
-+ if (!strlen($namespace)) {
-+ $namespace = strlen($this->namespace) ? $this->namespace : "xmlrpc";
-+ }
-+ return $namespace .".". strtolower($method[6]) . substr($method, 7);
-+ }
-+
-+ private function dispatch($method, array $params = null)
-+ {
-+ if (array_key_exists($method, self::$handle)) {
-+ return call_user_func(self::$handle[$method], $params);
-+ }
-+ throw new Exception("Unknown XMLRPC method: $method");
-+ }
-+
-+ private static function initialize($server = true, $data = false)
-+ {
-+ if ($data) {
-+ if (!self::$xmlreq && !(self::$xmlreq = http_get_request_body())) {
-+ throw new Exception("Failed to fetch XMLRPC request body");
-+ }
-+ }
-+ if ($server) {
-+ if (!self::$xmlrpc && !(self::$xmlrpc = xmlrpc_server_create())) {
-+ throw new Exception("Failed to initialize XMLRPC server");
-+ }
-+ ++self::$refcnt;
-+ }
-+ }
-+}
-+
-+/**
-+ * XmlRpcRequestHandler
-+ *
-+ * Define XMLRPC methods with an "xmlrpc" prefix, eg:
-+ * <code>
-+ * class IntOp implements XmlRpcRequestHandler {
-+ * public function getNamespace() {
-+ * return "int";
-+ * }
-+ * public function getInstrospectionData(array &$spec = null) {
-+ * }
-+ * // XMLRPC method name: int.sumValues
-+ * public function xmlrpcSumValues(array $values) {
-+ * return array_sum($values);
-+ * }
-+ * }
-+ * </code>
-+ */
-+interface XmlRpcRequestHandler
-+{
-+ public function getNamespace();
-+ public function getIntrospectionData(array &$spec = null);
-+}
-+
-+/**
-+ * XmlRpcRequestHandlerStub
-+ */
-+abstract class XmlRpcRequestHandlerStub implements XmlRpcRequestHandler
-+{
-+ public function getNamespace()
-+ {
-+ }
-+ public function getIntrospectionData(array &$spec = null)
-+ {
-+ }
-+}
-+
-+?>
---- /dev/null
-+++ b/ext/http/missing.c
-@@ -0,0 +1,74 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: missing.c 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include "config.h"
-+#endif
-+
-+#include "php.h"
-+#include "missing.h"
-+
-+#ifdef WONKY
-+int zend_declare_property_double(zend_class_entry *ce, char *name, int name_length, double value, int access_type TSRMLS_DC)
-+{
-+ zval *property = pemalloc(sizeof(zval), ce->type & ZEND_INTERNAL_CLASS);
-+ INIT_PZVAL(property);
-+ ZVAL_DOUBLE(property, value);
-+ return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
-+}
-+
-+void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC)
-+{
-+ zval *tmp = ecalloc(1, sizeof(zval));
-+ ZVAL_DOUBLE(tmp, value);
-+ zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
-+}
-+
-+int zend_declare_property_bool(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC)
-+{
-+ zval *property = pemalloc(sizeof(zval), ce->type & ZEND_INTERNAL_CLASS);
-+ INIT_PZVAL(property);
-+ ZVAL_BOOL(property, value);
-+ return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
-+}
-+
-+void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC)
-+{
-+ zval *tmp = ecalloc(1, sizeof(zval));
-+ ZVAL_BOOL(tmp, value);
-+ zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
-+}
-+
-+void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, char *value, int value_len TSRMLS_DC)
-+{
-+ zval *tmp;
-+
-+ ALLOC_ZVAL(tmp);
-+ tmp->is_ref = 0;
-+ tmp->refcount = 0;
-+ ZVAL_STRINGL(tmp, value, value_len, 1);
-+ zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/missing.h
-@@ -0,0 +1,184 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: missing.h 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#ifndef PHP_HTTP_MISSING
-+#define PHP_HTTP_MISSING
-+
-+#include "php_version.h"
-+
-+#if ZEND_MODULE_API_NO >= 20100409
-+#define ZEND_ENGINE_2_4
-+#endif
-+
-+#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID >= 50399)
-+# define ZEND_LITERAL_KEY_DC , const zend_literal *_zend_literal_key
-+# define ZEND_LITERAL_KEY_CC , _zend_literal_key
-+# define ZEND_LITERAL_NIL_CC , NULL
-+# define HTTP_CHECK_OPEN_BASEDIR(file, act) \
-+ if ((PG(open_basedir) && *PG(open_basedir))) \
-+ { \
-+ const char *tmp = file; \
-+ \
-+ if (!strncasecmp(tmp, "file:", lenof("file:"))) { \
-+ tmp += lenof("file:"); \
-+ while ((tmp - (const char *)file < 7) && (*tmp == '/' || *tmp == '\\')) ++tmp; \
-+ } \
-+ \
-+ if ( (tmp != file || !strstr(file, "://")) && \
-+ (!*tmp || php_check_open_basedir(tmp TSRMLS_CC))) { \
-+ act; \
-+ } \
-+ }
-+
-+#else
-+# define ZEND_LITERAL_KEY_DC
-+# define ZEND_LITERAL_KEY_CC
-+# define ZEND_LITERAL_NIL_CC
-+# define HTTP_CHECK_OPEN_BASEDIR(file, act) \
-+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) \
-+ { \
-+ const char *tmp = file; \
-+ \
-+ if (!strncasecmp(tmp, "file:", lenof("file:"))) { \
-+ tmp += lenof("file:"); \
-+ while ((tmp - (const char *)file < 7) && (*tmp == '/' || *tmp == '\\')) ++tmp; \
-+ } \
-+ \
-+ if ( (tmp != file || !strstr(file, "://")) && \
-+ (!*tmp || php_check_open_basedir(tmp TSRMLS_CC) || \
-+ (PG(safe_mode) && !php_checkuid(tmp, "rb+", CHECKUID_CHECK_MODE_PARAM)))) { \
-+ act; \
-+ } \
-+ }
-+
-+#endif
-+
-+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3)
-+# define HTTP_ZAPI_HASH_TSRMLS_CC TSRMLS_CC
-+# define HTTP_ZAPI_HASH_TSRMLS_DC TSRMLS_DC
-+# define HTTP_ZAPI_CONST_CAST(t) (const t)
-+# define GLOBAL_ERROR_HANDLING EG(error_handling)
-+# define GLOBAL_EXCEPTION_CLASS EG(exception_class)
-+# define HTTP_IS_CALLABLE(cb_zv, flags, cb_sp) zend_is_callable((cb_zv), (flags), (cb_sp) TSRMLS_CC)
-+# define HTTP_STATIC_ARG_INFO
-+#else
-+# define HTTP_ZAPI_HASH_TSRMLS_CC
-+# define HTTP_ZAPI_HASH_TSRMLS_DC
-+# define HTTP_ZAPI_CONST_CAST(t) (t)
-+# define GLOBAL_ERROR_HANDLING PG(error_handling)
-+# define GLOBAL_EXCEPTION_CLASS PG(exception_class)
-+# define HTTP_IS_CALLABLE(cb_zv, flags, cb_sp) zend_is_callable((cb_zv), (flags), (cb_sp))
-+# define HTTP_STATIC_ARG_INFO static
-+#endif
-+
-+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION == 0)
-+# define WONKY
-+#endif
-+
-+#ifndef pemalloc_rel
-+# define pemalloc_rel(size, persistent) ((persistent)?malloc(size):emalloc_rel(size))
-+#endif
-+
-+#ifndef ZEND_ACC_DEPRECATED
-+# define ZEND_ACC_DEPRECATED 0
-+#endif
-+
-+#if PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION < 10
-+# define php_url_parse_ex(u, l) php_url_parse(u)
-+#endif
-+
-+#ifndef TSRMLS_FETCH_FROM_CTX
-+# ifdef ZTS
-+# define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
-+# else
-+# define TSRMLS_FETCH_FROM_CTX(ctx)
-+# endif
-+#endif
-+
-+#ifndef TSRMLS_SET_CTX
-+# ifdef ZTS
-+# define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
-+# else
-+# define TSRMLS_SET_CTX(ctx)
-+# endif
-+#endif
-+
-+#ifndef ZVAL_ADDREF
-+# define ZVAL_ADDREF Z_ADDREF_P
-+#endif
-+
-+#ifndef SEPARATE_ARG_IF_REF
-+#define SEPARATE_ARG_IF_REF(zv) \
-+ if (PZVAL_IS_REF(zv)) { \
-+ zval *ov = zv; \
-+ ALLOC_INIT_ZVAL(zv); \
-+ Z_TYPE_P(zv) = Z_TYPE_P(ov); \
-+ zv->value = ov->value; \
-+ zval_copy_ctor(zv); \
-+ } else { \
-+ ZVAL_ADDREF(zv); \
-+ }
-+#endif
-+
-+#ifndef ZVAL_ZVAL
-+#define ZVAL_ZVAL(z, zv, copy, dtor) { \
-+ int is_ref, refcount; \
-+ is_ref = (z)->is_ref; \
-+ refcount = (z)->refcount; \
-+ *(z) = *(zv); \
-+ if (copy) { \
-+ zval_copy_ctor(z); \
-+ } \
-+ if (dtor) { \
-+ if (!copy) { \
-+ ZVAL_NULL(zv); \
-+ } \
-+ zval_ptr_dtor(&zv); \
-+ } \
-+ (z)->is_ref = is_ref; \
-+ (z)->refcount = refcount; \
-+ }
-+#endif
-+#ifndef RETVAL_ZVAL
-+# define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor)
-+#endif
-+#ifndef RETURN_ZVAL
-+# define RETURN_ZVAL(zv, copy, dtor) { RETVAL_ZVAL(zv, copy, dtor); return; }
-+#endif
-+
-+#ifndef ZEND_MN
-+# define ZEND_MN(name) ZEND_FN(name)
-+#endif
-+
-+#ifdef WONKY
-+extern int zend_declare_property_double(zend_class_entry *ce, char *name, int name_length, double value, int access_type TSRMLS_DC);
-+extern void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC);
-+
-+extern int zend_declare_property_bool(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC);
-+extern void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
-+
-+extern void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, char *value, int value_len TSRMLS_DC);
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http.h
-@@ -0,0 +1,262 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http.h 324012 2012-03-08 08:44:32Z mike $ */
-+
-+#ifndef PHP_EXT_HTTP_H
-+#define PHP_EXT_HTTP_H
-+
-+#define PHP_HTTP_VERSION "1.7.4"
-+
-+#ifdef HAVE_CONFIG_H
-+# include "config.h"
-+#else
-+# ifndef PHP_WIN32
-+# include "php_config.h"
-+# endif
-+#endif
-+
-+#include "php.h"
-+#include "missing.h"
-+#include "php_http_std_defs.h"
-+#include "phpstr/phpstr.h"
-+
-+#ifdef HTTP_WANT_SAPI
-+# if PHP_API_VERSION > 20041225
-+# define HTTP_HAVE_SAPI_RTIME
-+# endif
-+# include "SAPI.h"
-+#endif
-+
-+#ifdef HTTP_WANT_NETDB
-+# ifdef PHP_WIN32
-+# define HTTP_HAVE_NETDB
-+# include <winsock2.h>
-+# elif defined(HAVE_NETDB_H)
-+# define HTTP_HAVE_NETDB
-+# include <netdb.h>
-+# ifdef HAVE_UNISTD_H
-+# include <unistd.h>
-+# endif
-+# endif
-+#endif
-+
-+#if defined(HTTP_WANT_CURL) && defined(HTTP_HAVE_CURL)
-+# ifdef PHP_WIN32
-+# include <winsock2.h>
-+# define CURL_STATICLIB
-+# endif
-+# include <curl/curl.h>
-+# define HTTP_CURL_VERSION(x, y, z) (LIBCURL_VERSION_NUM >= (((x)<<16) + ((y)<<8) + (z)))
-+#
-+# if defined(HTTP_WANT_EVENT) && defined(HTTP_HAVE_EVENT)
-+# include <event.h>
-+# endif
-+#endif
-+
-+#if defined(HTTP_WANT_MAGIC) && defined(HTTP_HAVE_MAGIC)
-+# if defined(PHP_WIN32) && !defined(USE_MAGIC_DLL) && !defined(USE_MAGIC_STATIC)
-+# define USE_MAGIC_STATIC
-+# endif
-+# include <magic.h>
-+#endif
-+
-+#if defined(HTTP_WANT_ZLIB) && defined(HTTP_HAVE_ZLIB)
-+# include <zlib.h>
-+#endif
-+
-+#include <ctype.h>
-+#define HTTP_IS_CTYPE(type, c) is##type((int) (unsigned char) (c))
-+#define HTTP_TO_CTYPE(type, c) to##type((int) (unsigned char) (c))
-+
-+extern zend_module_entry http_module_entry;
-+#define phpext_http_ptr &http_module_entry
-+
-+extern int http_module_number;
-+
-+ZEND_BEGIN_MODULE_GLOBALS(http)
-+
-+ struct _http_globals_etag {
-+ char *mode;
-+ void *ctx;
-+ zend_bool started;
-+ } etag;
-+
-+ struct _http_globals_log {
-+ char *cache;
-+ char *redirect;
-+ char *not_found;
-+ char *allowed_methods;
-+ char *composite;
-+ } log;
-+
-+ struct _http_globals_send {
-+ double throttle_delay;
-+ size_t buffer_size;
-+ char *content_type;
-+ char *unquoted_etag;
-+ time_t last_modified;
-+ struct _http_globals_send_deflate {
-+ zend_bool response;
-+ zend_bool start_auto;
-+ long start_flags;
-+ int encoding;
-+ void *stream;
-+ } deflate;
-+ struct _http_globals_send_inflate {
-+ zend_bool start_auto;
-+ long start_flags;
-+ void *stream;
-+ } inflate;
-+ zend_bool not_found_404;
-+ } send;
-+
-+ struct _http_globals_request {
-+ time_t time;
-+ HashTable *headers;
-+ struct _http_globals_request_methods {
-+ HashTable registered;
-+ char *allowed;
-+ char *custom;
-+ } methods;
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
-+ struct _http_globals_request_datashare {
-+ zend_llist handles;
-+ zend_bool cookie;
-+ zend_bool dns;
-+ zend_bool ssl;
-+ zend_bool connect;
-+ } datashare;
-+#endif
-+#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_EVENT)
-+ struct _http_globals_request_pool {
-+ struct _http_globals_request_pool_event {
-+ void *base;
-+ } event;
-+ } pool;
-+#endif
-+ } request;
-+
-+ struct _http_globals_persistent {
-+ struct _http_globals_persistent_handles {
-+ ulong limit;
-+ struct _http_globals_persistent_handles_ident {
-+ ulong h;
-+ char *s;
-+ size_t l;
-+ } ident;
-+ } handles;
-+ } persistent;
-+
-+#ifdef ZEND_ENGINE_2
-+ zend_bool only_exceptions;
-+#endif
-+
-+ zend_bool force_exit;
-+ zend_bool read_post_data;
-+ zval *server_var;
-+
-+ZEND_END_MODULE_GLOBALS(http)
-+
-+ZEND_EXTERN_MODULE_GLOBALS(http);
-+
-+#ifdef ZTS
-+# include "TSRM.h"
-+# define HTTP_G ((zend_http_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(http_globals_id)])
-+#else
-+# define HTTP_G (&http_globals)
-+#endif
-+
-+#if defined(HAVE_ICONV) && (HTTP_SHARED_DEPS || !defined(COMPILE_DL_ICONV))
-+# define HTTP_HAVE_ICONV
-+#endif
-+
-+#if defined(HAVE_PHP_SESSION) && (HTTP_SHARED_DEPS || !defined(COMPILE_DL_SESSION))
-+# define HTTP_HAVE_SESSION
-+#endif
-+
-+#if defined(HAVE_HASH_EXT) && (HTTP_SHARED_DEPS || !defined(COMPILE_DL_HASH)) && defined(HTTP_HAVE_PHP_HASH_H)
-+# define HTTP_HAVE_HASH
-+#endif
-+
-+#if defined(HAVE_SPL)
-+# define HTTP_HAVE_SPL
-+#endif
-+
-+PHP_FUNCTION(http_date);
-+PHP_FUNCTION(http_build_url);
-+PHP_FUNCTION(http_build_str);
-+PHP_FUNCTION(http_negotiate_language);
-+PHP_FUNCTION(http_negotiate_charset);
-+PHP_FUNCTION(http_negotiate_content_type);
-+PHP_FUNCTION(http_negotiate);
-+PHP_FUNCTION(http_redirect);
-+PHP_FUNCTION(http_throttle);
-+PHP_FUNCTION(http_send_status);
-+PHP_FUNCTION(http_send_last_modified);
-+PHP_FUNCTION(http_send_content_type);
-+PHP_FUNCTION(http_send_content_disposition);
-+PHP_FUNCTION(http_match_modified);
-+PHP_FUNCTION(http_match_etag);
-+PHP_FUNCTION(http_cache_last_modified);
-+PHP_FUNCTION(http_cache_etag);
-+PHP_FUNCTION(http_send_data);
-+PHP_FUNCTION(http_send_file);
-+PHP_FUNCTION(http_send_stream);
-+PHP_FUNCTION(http_chunked_decode);
-+PHP_FUNCTION(http_parse_message);
-+PHP_FUNCTION(http_parse_headers);
-+PHP_FUNCTION(http_parse_cookie);
-+PHP_FUNCTION(http_build_cookie);
-+PHP_FUNCTION(http_parse_params);
-+PHP_FUNCTION(http_get_request_headers);
-+PHP_FUNCTION(http_get_request_body);
-+PHP_FUNCTION(http_get_request_body_stream);
-+PHP_FUNCTION(http_match_request_header);
-+PHP_FUNCTION(http_persistent_handles_count);
-+PHP_FUNCTION(http_persistent_handles_clean);
-+PHP_FUNCTION(http_persistent_handles_ident);
-+#ifdef HTTP_HAVE_CURL
-+PHP_FUNCTION(http_get);
-+PHP_FUNCTION(http_head);
-+PHP_FUNCTION(http_post_data);
-+PHP_FUNCTION(http_post_fields);
-+PHP_FUNCTION(http_put_data);
-+PHP_FUNCTION(http_put_file);
-+PHP_FUNCTION(http_put_stream);
-+PHP_FUNCTION(http_request);
-+PHP_FUNCTION(http_request_body_encode);
-+#endif /* HTTP_HAVE_CURL */
-+PHP_FUNCTION(http_request_method_register);
-+PHP_FUNCTION(http_request_method_unregister);
-+PHP_FUNCTION(http_request_method_exists);
-+PHP_FUNCTION(http_request_method_name);
-+PHP_FUNCTION(ob_etaghandler);
-+#ifdef HTTP_HAVE_ZLIB
-+PHP_FUNCTION(http_deflate);
-+PHP_FUNCTION(http_inflate);
-+PHP_FUNCTION(ob_deflatehandler);
-+PHP_FUNCTION(ob_inflatehandler);
-+#endif
-+PHP_FUNCTION(http_support);
-+
-+#endif /* PHP_HTTP_H */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_api.h
-@@ -0,0 +1,326 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_api.h 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#ifndef PHP_HTTP_API_H
-+#define PHP_HTTP_API_H
-+
-+#define HTTP_SUPPORT 0x01L
-+#define HTTP_SUPPORT_REQUESTS 0x02L
-+#define HTTP_SUPPORT_MAGICMIME 0x04L
-+#define HTTP_SUPPORT_ENCODINGS 0x08L
-+#define HTTP_SUPPORT_SSLREQUESTS 0x20L
-+#define HTTP_SUPPORT_PERSISTENCE 0x40L
-+#define HTTP_SUPPORT_EVENTS 0x80L
-+
-+#define HTTP_PARAMS_ALLOW_COMMA 0x01
-+#define HTTP_PARAMS_ALLOW_FAILURE 0x02
-+#define HTTP_PARAMS_RAISE_ERROR 0x04
-+#define HTTP_PARAMS_DEFAULT (HTTP_PARAMS_ALLOW_COMMA|HTTP_PARAMS_ALLOW_FAILURE|HTTP_PARAMS_RAISE_ERROR)
-+#define HTTP_PARAMS_COLON_SEPARATOR 0x10
-+
-+extern PHP_MINIT_FUNCTION(http_support);
-+
-+#define http_support(f) _http_support(f)
-+PHP_HTTP_API long _http_support(long feature);
-+
-+#define pretty_key(key, key_len, uctitle, xhyphen) _http_pretty_key(key, key_len, uctitle, xhyphen)
-+extern char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen);
-+
-+#define http_boundary(b, l) _http_boundary((b), (l) TSRMLS_CC)
-+extern size_t _http_boundary(char *buf, size_t len TSRMLS_DC);
-+
-+#define http_error(type, code, string) _http_error_ex(type, code, "%s", string)
-+#define http_error_ex _http_error_ex
-+extern void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...);
-+
-+
-+#ifdef ZEND_ENGINE_2
-+#define http_exception_wrap(o, n, ce) _http_exception_wrap((o), (n), (ce) TSRMLS_CC)
-+extern zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC);
-+
-+#define http_try \
-+{ \
-+ zval *old_exception = EG(exception); \
-+ EG(exception) = NULL;
-+#define http_catch(ex_ce) \
-+ if (EG(exception) && old_exception) { \
-+ EG(exception) = http_exception_wrap(old_exception, EG(exception), ex_ce); \
-+ } \
-+}
-+#define http_final(ex_ce) \
-+ if (EG(exception)) { \
-+ EG(exception) = http_exception_wrap(EG(exception), NULL, ex_ce); \
-+ }
-+
-+typedef zend_object_value (*http_object_new_t)(zend_class_entry *ce, void *, void ** TSRMLS_DC);
-+
-+#define http_object_new(ov, cn, cl, co, ce, i, pp) _http_object_new((ov), (cn), (cl), (http_object_new_t) (co), (ce), (i), (void *) (pp) TSRMLS_CC)
-+extern STATUS _http_object_new(zend_object_value *ov, const char *cname_str, uint cname_len, http_object_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC);
-+#endif /* ZEND_ENGINE_2 */
-+
-+
-+#define HTTP_CHECK_CURL_INIT(ch, init, action) \
-+ if ((!(ch)) && (!((ch) = init))) { \
-+ http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initialize curl"); \
-+ action; \
-+ }
-+#define HTTP_CHECK_CONTENT_TYPE(ct, action) \
-+ if (!strchr((ct), '/')) { \
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, \
-+ "Content type \"%s\" does not seem to contain a primary and a secondary part", (ct)); \
-+ action; \
-+ }
-+#define HTTP_CHECK_MESSAGE_TYPE_RESPONSE(msg, action) \
-+ if (!HTTP_MSG_TYPE(RESPONSE, (msg))) { \
-+ http_error(HE_NOTICE, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_RESPONSE"); \
-+ action; \
-+ }
-+#define HTTP_CHECK_MESSAGE_TYPE_REQUEST(msg, action) \
-+ if (!HTTP_MSG_TYPE(REQUEST, (msg))) { \
-+ http_error(HE_NOTICE, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); \
-+ action; \
-+ }
-+#define HTTP_CHECK_GZIP_LEVEL(level, action) \
-+ if (level < -1 || level > 9) { \
-+ http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid compression level (-1 to 9): %d", level); \
-+ action; \
-+ }
-+#ifndef PHP_OUTPUT_NEWAPI
-+# define HTTP_GET_OUTPUT_START() \
-+ char *output_start_filename = php_get_output_start_filename(TSRMLS_C); \
-+ int output_start_lineno = php_get_output_start_lineno(TSRMLS_C)
-+#else
-+# define HTTP_GET_OUTPUT_START() \
-+ char *output_start_filename = php_output_get_start_filename(TSRMLS_C); \
-+ int output_start_lineno = php_output_get_start_lineno(TSRMLS_C)
-+#endif
-+#define HTTP_CHECK_HEADERS_SENT(action) \
-+ if (SG(headers_sent) && !SG(request_info).no_headers) { \
-+ HTTP_GET_OUTPUT_START(); \
-+ if (output_start_filename) { \
-+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Cannot modify header information - headers already sent by (output started at %s:%d)", \
-+ output_start_filename, output_start_lineno); \
-+ } else { \
-+ http_error(HE_WARNING, HTTP_E_HEADER, "Cannot modify header information - headers already sent"); \
-+ } \
-+ action; \
-+ }
-+
-+#define http_log(f, i, m) _http_log_ex((f), (i), (m) TSRMLS_CC)
-+extern void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC);
-+
-+#define http_exit(s, h) http_exit_ex((s), (h), NULL, 1)
-+#define http_exit_ex(s, h, b, e) _http_exit_ex((s), (h), (b), (e) TSRMLS_CC)
-+extern STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header TSRMLS_DC);
-+
-+#define http_check_method(m) http_check_method_ex((m), HTTP_KNOWN_METHODS)
-+#define http_check_method_ex(m, a) _http_check_method_ex((m), (a))
-+extern STATUS _http_check_method_ex(const char *method, const char *methods);
-+
-+#define http_got_server_var(v) (NULL != http_get_server_var_ex((v), strlen(v), 1))
-+#define http_get_server_var(v, c) http_get_server_var_ex((v), strlen(v), (c))
-+#define http_get_server_var_ex(v, l, c) _http_get_server_var_ex((v), (l), (c) TSRMLS_CC)
-+PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_len, zend_bool check TSRMLS_DC);
-+
-+#define http_get_request_body(b, l) _http_get_request_body_ex((b), (l), 1 TSRMLS_CC)
-+#define http_get_request_body_ex(b, l, d) _http_get_request_body_ex((b), (l), (d) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_bool dup TSRMLS_DC);
-+
-+#define http_get_request_body_stream() _http_get_request_body_stream(TSRMLS_C)
-+PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D);
-+
-+
-+typedef void (*http_parse_params_callback)(void *cb_arg, const char *key, int keylen, const char *val, int vallen TSRMLS_DC);
-+
-+#define http_parse_params_default_callback _http_parse_params_default_callback
-+PHP_HTTP_API void _http_parse_params_default_callback(void *ht, const char *key, int keylen, const char *val, int vallen TSRMLS_DC);
-+
-+#define http_parse_params(s, f, ht) _http_parse_params_ex((s), (f), _http_parse_params_default_callback, (ht) TSRMLS_CC)
-+#define http_parse_params_ex(s, f, cb, a) _http_parse_params_ex((s), (f), (cb), (a) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_parse_params_ex(const char *params, int flags, http_parse_params_callback cb, void *cb_arg TSRMLS_DC);
-+
-+
-+#define http_sleep(s) _http_sleep(s)
-+static inline void _http_sleep(double s)
-+{
-+#define HTTP_DIFFSEC (0.001)
-+#define HTTP_MLLISEC (1000)
-+#define HTTP_MCROSEC (1000 * 1000)
-+#define HTTP_NANOSEC (1000 * 1000 * 1000)
-+#define HTTP_MSEC(s) ((long)(s * HTTP_MLLISEC))
-+#define HTTP_USEC(s) ((long)(s * HTTP_MCROSEC))
-+#define HTTP_NSEC(s) ((long)(s * HTTP_NANOSEC))
-+
-+#if defined(PHP_WIN32)
-+ Sleep((DWORD) HTTP_MSEC(s));
-+#elif defined(HAVE_USLEEP)
-+ usleep(HTTP_USEC(s));
-+#elif defined(HAVE_NANOSLEEP)
-+ struct timespec req, rem;
-+
-+ req.tv_sec = (time_t) s;
-+ req.tv_nsec = HTTP_NSEC(s) % HTTP_NANOSEC;
-+
-+ while (nanosleep(&req, &rem) && (errno == EINTR) && (HTTP_NSEC(rem.tv_sec) + rem.tv_nsec) > HTTP_NSEC(HTTP_DIFFSEC))) {
-+ req.tv_sec = rem.tv_sec;
-+ req.tv_nsec = rem.tv_nsec;
-+ }
-+#else
-+ struct timeval timeout;
-+
-+ timeout.tv.sec = (time_t) s;
-+ timeout.tv_usec = HTTP_USEC(s) % HTTP_MCROSEC;
-+
-+ select(0, NULL, NULL, NULL, &timeout);
-+#endif
-+}
-+
-+#define http_locate_str _http_locate_str
-+static inline const char *_http_locate_str(const char *h, size_t h_len, const char *n, size_t n_len)
-+{
-+ const char *p, *e;
-+
-+ if (n_len && h_len) {
-+ e = h + h_len;
-+ do {
-+ if (*h == *n) {
-+ for (p = n; *p == h[p-n]; ++p) {
-+ if (p == n+n_len-1) {
-+ return h;
-+ }
-+ }
-+ }
-+ } while (h++ != e);
-+ }
-+
-+ return NULL;
-+}
-+
-+#define http_locate_body _http_locate_body
-+static inline const char *_http_locate_body(const char *message)
-+{
-+ const char *body = NULL, *msg = message;
-+
-+ while (*msg) {
-+ if (*msg == '\n') {
-+ if (*(msg+1) == '\n') {
-+ body = msg + 2;
-+ break;
-+ } else if (*(msg+1) == '\r' && *(msg+2) == '\n') {
-+ body = msg + 3;
-+ break;
-+ }
-+ }
-+ ++msg;
-+ }
-+ return body;
-+}
-+
-+#define http_locate_eol _http_locate_eol
-+static inline const char *_http_locate_eol(const char *line, int *eol_len)
-+{
-+ const char *eol = strpbrk(line, "\r\n");
-+
-+ if (eol_len) {
-+ *eol_len = eol ? ((eol[0] == '\r' && eol[1] == '\n') ? 2 : 1) : 0;
-+ }
-+ return eol;
-+}
-+
-+#define http_zset(t, z) _http_zset((t), (z))
-+static inline zval *_http_zset(int type, zval *z)
-+{
-+ if (Z_TYPE_P(z) != type) {
-+ switch (type) {
-+ case IS_NULL: convert_to_null(z); break;
-+ case IS_BOOL: convert_to_boolean(z); break;
-+ case IS_LONG: convert_to_long(z); break;
-+ case IS_DOUBLE: convert_to_double(z); break;
-+ case IS_STRING: convert_to_string(z); break;
-+ case IS_ARRAY: convert_to_array(z); break;
-+ case IS_OBJECT: convert_to_object(z); break;
-+ }
-+ }
-+ return z;
-+}
-+#define http_zsep(t, z) _http_zsep_ex((t), (z), NULL)
-+#define http_zsep_ex(t, z, p) _http_zsep_ex((t), (z), (p))
-+static inline zval *_http_zsep_ex(int type, zval *z, zval **p) {
-+ ZVAL_ADDREF(z);
-+ if (Z_TYPE_P(z) != type) {
-+ switch (type) {
-+ case IS_NULL: convert_to_null_ex(&z); break;
-+ case IS_BOOL: convert_to_boolean_ex(&z); break;
-+ case IS_LONG: convert_to_long_ex(&z); break;
-+ case IS_DOUBLE: convert_to_double_ex(&z); break;
-+ case IS_STRING: convert_to_string_ex(&z); break;
-+ case IS_ARRAY: convert_to_array_ex(&z); break;
-+ case IS_OBJECT: convert_to_object_ex(&z); break;
-+ }
-+ } else {
-+ SEPARATE_ZVAL_IF_NOT_REF(&z);
-+ }
-+ if (p) {
-+ *p = z;
-+ }
-+ return z;
-+}
-+
-+typedef struct _HashKey {
-+ char *str;
-+ uint len;
-+ ulong num;
-+ uint dup:1;
-+ uint type:31;
-+} HashKey;
-+#define initHashKey(dup) {NULL, 0, 0, (dup), 0}
-+
-+#define FOREACH_VAL(pos, array, val) FOREACH_HASH_VAL(pos, Z_ARRVAL_P(array), val)
-+#define FOREACH_HASH_VAL(pos, hash, val) \
-+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
-+ zend_hash_get_current_data_ex(hash, (void *) &val, &pos) == SUCCESS; \
-+ zend_hash_move_forward_ex(hash, &pos))
-+
-+#define FOREACH_KEY(pos, array, key) FOREACH_HASH_KEY(pos, Z_ARRVAL_P(array), key)
-+#define FOREACH_HASH_KEY(pos, hash, _key) \
-+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
-+ ((_key).type = zend_hash_get_current_key_ex(hash, &(_key).str, &(_key).len, &(_key).num, (zend_bool) (_key).dup, &pos)) != HASH_KEY_NON_EXISTANT; \
-+ zend_hash_move_forward_ex(hash, &pos)) \
-+
-+#define FOREACH_KEYVAL(pos, array, key, val) FOREACH_HASH_KEYVAL(pos, Z_ARRVAL_P(array), key, val)
-+#define FOREACH_HASH_KEYVAL(pos, hash, _key, val) \
-+ for ( zend_hash_internal_pointer_reset_ex(hash, &pos); \
-+ ((_key).type = zend_hash_get_current_key_ex(hash, &(_key).str, &(_key).len, &(_key).num, (zend_bool) (_key).dup, &pos)) != HASH_KEY_NON_EXISTANT && \
-+ zend_hash_get_current_data_ex(hash, (void *) &val, &pos) == SUCCESS; \
-+ zend_hash_move_forward_ex(hash, &pos))
-+
-+#define array_copy(src, dst) zend_hash_copy(dst, src, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *))
-+#define ARRAY_JOIN_STRONLY 1
-+#define ARRAY_JOIN_PRETTIFY 2
-+#define array_join(src, dst, append, flags) zend_hash_apply_with_arguments(src HTTP_ZAPI_HASH_TSRMLS_CC, (append)?apply_array_append_func:apply_array_merge_func, 2, dst, (int)flags)
-+
-+extern int apply_array_append_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
-+extern int apply_array_merge_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_cache_api.h
-@@ -0,0 +1,162 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_cache_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_CACHE_API_H
-+#define PHP_HTTP_CACHE_API_H
-+
-+#include "php_http_send_api.h"
-+
-+#include "ext/standard/crc32.h"
-+#include "ext/standard/sha1.h"
-+#include "ext/standard/md5.h"
-+
-+#ifdef HTTP_HAVE_HASH
-+# include "php_hash.h"
-+#endif
-+
-+#define http_etag_digest(d, l) _http_etag_digest((d), (l))
-+static inline char *_http_etag_digest(const unsigned char *digest, int len)
-+{
-+ static const char hexdigits[17] = "0123456789abcdef";
-+ int i;
-+ char *hex = emalloc(len * 2 + 1);
-+ char *ptr = hex;
-+
-+ for (i = 0; i < len; ++i) {
-+ *ptr++ = hexdigits[digest[i] >> 4];
-+ *ptr++ = hexdigits[digest[i] & 0xF];
-+ }
-+ *ptr = '\0';
-+
-+ return hex;
-+}
-+
-+#define http_etag_init() _http_etag_init(TSRMLS_C)
-+static inline void *_http_etag_init(TSRMLS_D)
-+{
-+ void *ctx = NULL;
-+ char *mode = HTTP_G->etag.mode;
-+
-+#ifdef HTTP_HAVE_HASH
-+ const php_hash_ops *eho = NULL;
-+
-+ if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
-+ ctx = emalloc(eho->context_size);
-+ eho->hash_init(ctx);
-+ } else
-+#endif
-+ if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) {
-+ ctx = emalloc(sizeof(uint));
-+ *((uint *) ctx) = ~0;
-+ } else if (mode && !strcasecmp(mode, "sha1")) {
-+ PHP_SHA1Init(ctx = emalloc(sizeof(PHP_SHA1_CTX)));
-+ } else {
-+ PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX)));
-+ }
-+
-+ return ctx;
-+}
-+
-+#define http_etag_finish(c) _http_etag_finish((c) TSRMLS_CC)
-+static inline char *_http_etag_finish(void *ctx TSRMLS_DC)
-+{
-+ unsigned char digest[128] = {0};
-+ char *etag = NULL, *mode = HTTP_G->etag.mode;
-+
-+#ifdef HTTP_HAVE_HASH
-+ const php_hash_ops *eho = NULL;
-+
-+ if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
-+ eho->hash_final(digest, ctx);
-+ etag = http_etag_digest(digest, eho->digest_size);
-+ } else
-+#endif
-+ if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) {
-+ *((uint *) ctx) = ~*((uint *) ctx);
-+ etag = http_etag_digest((const unsigned char *) ctx, sizeof(uint));
-+ } else if (mode && (!strcasecmp(mode, "sha1"))) {
-+ PHP_SHA1Final(digest, ctx);
-+ etag = http_etag_digest(digest, 20);
-+ } else {
-+ PHP_MD5Final(digest, ctx);
-+ etag = http_etag_digest(digest, 16);
-+ }
-+ efree(ctx);
-+
-+ return etag;
-+}
-+
-+#define http_etag_update(c, d, l) _http_etag_update((c), (d), (l) TSRMLS_CC)
-+static inline void _http_etag_update(void *ctx, const char *data_ptr, size_t data_len TSRMLS_DC)
-+{
-+ char *mode = HTTP_G->etag.mode;
-+#ifdef HTTP_HAVE_HASH
-+ const php_hash_ops *eho = NULL;
-+
-+ if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
-+ eho->hash_update(ctx, (const unsigned char *) data_ptr, data_len);
-+ } else
-+#endif
-+ if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) {
-+ uint i, c = *((uint *) ctx);
-+ for (i = 0; i < data_len; ++i) {
-+ CRC32(c, data_ptr[i]);
-+ }
-+ *((uint *)ctx) = c;
-+ } else if (mode && (!strcasecmp(mode, "sha1"))) {
-+ PHP_SHA1Update(ctx, (const unsigned char *) data_ptr, data_len);
-+ } else {
-+ PHP_MD5Update(ctx, (const unsigned char *) data_ptr, data_len);
-+ }
-+}
-+
-+#define http_ob_etaghandler(o, l, ho, hl, m) _http_ob_etaghandler((o), (l), (ho), (hl), (m) TSRMLS_CC)
-+extern void _http_ob_etaghandler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC);
-+
-+#define http_etag(p, l, m) _http_etag((p), (l), (m) TSRMLS_CC)
-+PHP_HTTP_API char *_http_etag(const void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC);
-+
-+#define http_last_modified(p, m) _http_last_modified((p), (m) TSRMLS_CC)
-+PHP_HTTP_API time_t _http_last_modified(const void *data_ptr, http_send_mode data_mode TSRMLS_DC);
-+
-+#define http_match_last_modified(entry, modified) _http_match_last_modified_ex((entry), (modified), 1 TSRMLS_CC)
-+#define http_match_last_modified_ex(entry, modified, ep) _http_match_last_modified_ex((entry), (modified), (ep) TSRMLS_CC)
-+PHP_HTTP_API zend_bool _http_match_last_modified_ex(const char *entry, time_t t, zend_bool enforce_presence TSRMLS_DC);
-+
-+#define http_match_etag(entry, etag) _http_match_etag_ex((entry), (etag), 1 TSRMLS_CC)
-+#define http_match_etag_ex(entry, etag, ep) _http_match_etag_ex((entry), (etag), (ep) TSRMLS_CC)
-+PHP_HTTP_API zend_bool _http_match_etag_ex(const char *entry, const char *etag, zend_bool enforce_presence TSRMLS_DC);
-+
-+#define http_cache_last_modified(l, s, cc, ccl) _http_cache_last_modified((l), (s), (cc), (ccl) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_cache_last_modified(time_t last_modified, time_t send_modified, const char *cache_control, size_t cc_len TSRMLS_DC);
-+
-+#define http_cache_etag(e, el, cc, ccl) _http_cache_etag((e), (el), (cc), (ccl) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_cache_etag(const char *etag, size_t etag_len, const char *cache_control, size_t cc_len TSRMLS_DC);
-+
-+#define http_start_ob_etaghandler() _http_start_ob_etaghandler(TSRMLS_C)
-+PHP_HTTP_API STATUS _http_start_ob_etaghandler(TSRMLS_D);
-+#define http_interrupt_ob_etaghandler() _http_interrupt_ob_etaghandler(TSRMLS_C)
-+PHP_HTTP_API zend_bool _http_interrupt_ob_etaghandler(TSRMLS_D);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_cookie_api.h
-@@ -0,0 +1,86 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_cookie_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_COOKIE_API_H
-+#define PHP_HTTP_COOKIE_API_H
-+
-+#define HTTP_COOKIE_SECURE 0x10L
-+#define HTTP_COOKIE_HTTPONLY 0x20L
-+
-+#define HTTP_COOKIE_PARSE_RAW 0x01L
-+
-+extern PHP_MINIT_FUNCTION(http_cookie);
-+
-+/*
-+ generally a netscape cookie compliant struct, recognizing httpOnly attribute, too;
-+ cookie params like those from rfc2109 and rfc2965 are just put into extras, if
-+ one specifies them in allowed extras, else they're treated like cookies themself
-+*/
-+typedef struct _http_cookie_list_t {
-+ HashTable cookies;
-+ HashTable extras;
-+ long flags;
-+ char *path;
-+ char *domain;
-+ time_t expires;
-+} http_cookie_list;
-+
-+#define http_cookie_list_new() _http_cookie_list_init(NULL ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+#define http_cookie_list_init(l) _http_cookie_list_init((l) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API http_cookie_list *_http_cookie_list_init(http_cookie_list *list ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_cookie_list_dtor(l) _http_cookie_list_dtor((l) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_dtor(http_cookie_list *list TSRMLS_DC);
-+
-+#define http_cookie_list_free(l) _http_cookie_list_free((l) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_free(http_cookie_list **list TSRMLS_DC);
-+
-+#define http_cookie_list_has_cookie(list, name, name_len) zend_hash_exists(&(list)->cookies, (name), (name_len)+1)
-+#define http_cookie_list_has_extra(list, name, name_len) zend_hash_exists(&(list)->extras, (name), (name_len)+1)
-+
-+#define http_cookie_list_add_cookie(l, n, nl, v, vl) _http_cookie_list_add_cookie((l), (n), (nl), (v), (vl) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_add_cookie(http_cookie_list *list, const char *name, size_t name_len, const char *value, size_t value_len TSRMLS_DC);
-+
-+#define http_cookie_list_add_extra(l, n , nl, v, vl) _http_cookie_list_add_extra((l), (n), (nl), (v), (vl) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_add_extra(http_cookie_list *list, const char *name, size_t name_len, const char *value, size_t value_len TSRMLS_DC);
-+
-+#define http_cookie_list_get_cookie(l, n, nl) _http_cookie_list_get_cookie((l), (n), (nl) TSRMLS_CC)
-+PHP_HTTP_API const char *_http_cookie_list_get_cookie(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC);
-+
-+#define http_cookie_list_get_extra(l, n, nl) _http_cookie_list_get_extra((l), (n), (nl) TSRMLS_CC)
-+PHP_HTTP_API const char *_http_cookie_list_get_extra(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC);
-+
-+#define http_parse_cookie(s) _http_parse_cookie_ex(NULL, (s), 0, NULL TSRMLS_CC)
-+#define http_parse_cookie_ex(l, s, f, a) _http_parse_cookie_ex((l), (s), (f), (a) TSRMLS_CC)
-+PHP_HTTP_API http_cookie_list *_http_parse_cookie_ex(http_cookie_list * list, const char *string, long flags, char **allowed_extras TSRMLS_DC);
-+
-+#define http_cookie_list_tostruct(l, s) _http_cookie_list_tostruct((l), (s) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_tostruct(http_cookie_list *list, zval *strct TSRMLS_DC);
-+
-+#define http_cookie_list_fromstruct(l, s) _http_cookie_list_fromstruct((l), (s) TSRMLS_CC)
-+PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *list, zval *strct TSRMLS_DC);
-+
-+#define http_cookie_list_tostring(l, str, len) _http_cookie_list_tostring((l), (str), (len) TSRMLS_CC)
-+PHP_HTTP_API void _http_cookie_list_tostring(http_cookie_list *list, char **str, size_t *len TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/php_http_date_api.h
-@@ -0,0 +1,35 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_date_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_DATE_API_H
-+#define PHP_HTTP_DATE_API_H
-+
-+#define http_date(t) _http_date((t) TSRMLS_CC)
-+PHP_HTTP_API char *_http_date(time_t t TSRMLS_DC);
-+
-+#define http_parse_date(d) _http_parse_date_ex((d), 0 TSRMLS_CC)
-+#define http_parse_date_ex(d, s) _http_parse_date_ex((d), (s) TSRMLS_CC)
-+PHP_HTTP_API time_t _http_parse_date_ex(const char *date, zend_bool silent TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_deflatestream_object.h
-@@ -0,0 +1,57 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_deflatestream_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_DEFLATESTREAM_OBJECT_H
-+#define PHP_HTTP_DEFLATESTREAM_OBJECT_H
-+#ifdef HTTP_HAVE_ZLIB
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_deflatestream_object_t {
-+ zend_object zo;
-+ http_encoding_stream *stream;
-+} http_deflatestream_object;
-+
-+extern zend_class_entry *http_deflatestream_object_ce;
-+extern zend_function_entry http_deflatestream_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_deflatestream_object);
-+
-+#define http_deflatestream_object_new(ce) _http_deflatestream_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_deflatestream_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_deflatestream_object_new_ex(ce, s, ptr) _http_deflatestream_object_new_ex((ce), (s), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_deflatestream_object_new_ex(zend_class_entry *ce, http_encoding_stream *s, http_deflatestream_object **ptr TSRMLS_DC);
-+#define http_deflatestream_object_clone(zobj) _http_deflatestream_object_clone_obj(zobj TSRMLS_CC)
-+extern zend_object_value _http_deflatestream_object_clone_obj(zval *object TSRMLS_DC);
-+#define http_deflatestream_object_free(o) _http_deflatestream_object_free((o) TSRMLS_CC)
-+extern void _http_deflatestream_object_free(zend_object *object TSRMLS_DC);
-+
-+PHP_METHOD(HttpDeflateStream, __construct);
-+PHP_METHOD(HttpDeflateStream, factory);
-+PHP_METHOD(HttpDeflateStream, update);
-+PHP_METHOD(HttpDeflateStream, flush);
-+PHP_METHOD(HttpDeflateStream, finish);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_encoding_api.h
-@@ -0,0 +1,192 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_encoding_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_ENCODING_API_H
-+#define PHP_HTTP_ENCODING_API_H
-+
-+#define http_encoding_dechunk(e, el, d, dl) _http_encoding_dechunk((e), (el), (d), (dl) TSRMLS_CC)
-+PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC);
-+
-+#define http_encoding_response_start(cl, i) _http_encoding_response_start((cl), (i) TSRMLS_CC)
-+PHP_HTTP_API int _http_encoding_response_start(size_t content_length, zend_bool ignore_http_ohandler TSRMLS_DC);
-+
-+#ifdef HTTP_HAVE_ZLIB
-+
-+extern PHP_MINIT_FUNCTION(http_encoding);
-+extern PHP_RINIT_FUNCTION(http_encoding);
-+extern PHP_RSHUTDOWN_FUNCTION(http_encoding);
-+
-+typedef enum _http_encoding_type_t {
-+ HTTP_ENCODING_NONE,
-+ HTTP_ENCODING_GZIP,
-+ HTTP_ENCODING_DEFLATE,
-+} http_encoding_type;
-+
-+#define HTTP_INFLATE_ROUNDS 100
-+
-+#define HTTP_DEFLATE_BUFFER_SIZE_GUESS(S) \
-+ (((size_t) ((double) S * (double) 1.015)) + 10 + 8 + 4 + 1)
-+#define HTTP_INFLATE_BUFFER_SIZE_GUESS(S) \
-+ (((S) + 1) << 3)
-+#define HTTP_INFLATE_BUFFER_SIZE_ALIGN(S) \
-+ ((S) += (S) >> (3))
-+
-+#define HTTP_DEFLATE_BUFFER_SIZE 0x8000
-+#define HTTP_INFLATE_BUFFER_SIZE 0x1000
-+
-+#define HTTP_DEFLATE_LEVEL_DEF 0x00000000
-+#define HTTP_DEFLATE_LEVEL_MIN 0x00000001
-+#define HTTP_DEFLATE_LEVEL_MAX 0x00000009
-+#define HTTP_DEFLATE_TYPE_ZLIB 0x00000000
-+#define HTTP_DEFLATE_TYPE_GZIP 0x00000010
-+#define HTTP_DEFLATE_TYPE_RAW 0x00000020
-+#define HTTP_DEFLATE_STRATEGY_DEF 0x00000000
-+#define HTTP_DEFLATE_STRATEGY_FILT 0x00000100
-+#define HTTP_DEFLATE_STRATEGY_HUFF 0x00000200
-+#define HTTP_DEFLATE_STRATEGY_RLE 0x00000300
-+#define HTTP_DEFLATE_STRATEGY_FIXED 0x00000400
-+
-+#define HTTP_DEFLATE_LEVEL_SET(flags, level) \
-+ switch (flags & 0xf) \
-+ { \
-+ default: \
-+ if ((flags & 0xf) < 10) { \
-+ level = flags & 0xf; \
-+ break; \
-+ } \
-+ case HTTP_DEFLATE_LEVEL_DEF: \
-+ level = Z_DEFAULT_COMPRESSION; \
-+ break; \
-+ }
-+
-+#define HTTP_DEFLATE_WBITS_SET(flags, wbits) \
-+ switch (flags & 0xf0) \
-+ { \
-+ case HTTP_DEFLATE_TYPE_GZIP: \
-+ wbits = HTTP_WINDOW_BITS_GZIP; \
-+ break; \
-+ case HTTP_DEFLATE_TYPE_RAW: \
-+ wbits = HTTP_WINDOW_BITS_RAW; \
-+ break; \
-+ default: \
-+ wbits = HTTP_WINDOW_BITS_ZLIB; \
-+ break; \
-+ }
-+
-+#define HTTP_INFLATE_WBITS_SET(flags, wbits) \
-+ if (flags & HTTP_INFLATE_TYPE_RAW) { \
-+ wbits = HTTP_WINDOW_BITS_RAW; \
-+} else { \
-+ wbits = HTTP_WINDOW_BITS_ANY; \
-+}
-+
-+#define HTTP_DEFLATE_STRATEGY_SET(flags, strategy) \
-+ switch (flags & 0xf00) \
-+ { \
-+ case HTTP_DEFLATE_STRATEGY_FILT: \
-+ strategy = Z_FILTERED; \
-+ break; \
-+ case HTTP_DEFLATE_STRATEGY_HUFF: \
-+ strategy = Z_HUFFMAN_ONLY; \
-+ break; \
-+ case HTTP_DEFLATE_STRATEGY_RLE: \
-+ strategy = Z_RLE; \
-+ break; \
-+ case HTTP_DEFLATE_STRATEGY_FIXED: \
-+ strategy = Z_FIXED; \
-+ break; \
-+ default: \
-+ strategy = Z_DEFAULT_STRATEGY; \
-+ break; \
-+ }
-+
-+#define HTTP_WINDOW_BITS_ZLIB 0x0000000f
-+#define HTTP_WINDOW_BITS_GZIP 0x0000001f
-+#define HTTP_WINDOW_BITS_ANY 0x0000002f
-+#define HTTP_WINDOW_BITS_RAW -0x000000f
-+
-+#ifndef Z_FIXED
-+/* Z_FIXED does not exist prior 1.2.2.2 */
-+# define Z_FIXED 0
-+#endif
-+
-+#define HTTP_INFLATE_TYPE_ZLIB 0x00000000
-+#define HTTP_INFLATE_TYPE_GZIP 0x00000000
-+#define HTTP_INFLATE_TYPE_RAW 0x00000001
-+
-+#define HTTP_ENCODING_STREAM_FLUSH_NONE 0x00000000
-+#define HTTP_ENCODING_STREAM_FLUSH_SYNC 0x00100000
-+#define HTTP_ENCODING_STREAM_FLUSH_FULL 0x00200000
-+
-+#define HTTP_ENCODING_STREAM_FLUSH_FLAG(f) \
-+ (((f) & HTTP_ENCODING_STREAM_FLUSH_FULL) ? Z_FULL_FLUSH : \
-+ (((f) & HTTP_ENCODING_STREAM_FLUSH_SYNC) ? Z_SYNC_FLUSH : Z_NO_FLUSH))
-+
-+#define HTTP_ENCODING_STREAM_PERSISTENT 0x01000000
-+
-+typedef struct _http_encoding_stream_t {
-+ z_stream stream;
-+ int flags;
-+ void *storage;
-+} http_encoding_stream;
-+
-+#define http_encoding_deflate(f, d, dl, r, rl) _http_encoding_deflate((f), (d), (dl), (r), (rl) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_inflate(d, dl, r, rl) _http_encoding_inflate((d), (dl), (r), (rl) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_encoding_deflate_stream_init(s, f) _http_encoding_deflate_stream_init((s), (f) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API http_encoding_stream *_http_encoding_deflate_stream_init(http_encoding_stream *s, int flags ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_deflate_stream_update(s, d, dl, e, el) _http_encoding_deflate_stream_update((s), (d), (dl), (e), (el) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_deflate_stream_flush(s, e, el) _http_encoding_deflate_stream_flush((s), (e), (el) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_deflate_stream_finish(s, e, el) _http_encoding_deflate_stream_finish((s), (e), (el) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_deflate_stream_dtor(s) _http_encoding_deflate_stream_dtor((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_encoding_deflate_stream_dtor(http_encoding_stream *s TSRMLS_DC);
-+#define http_encoding_deflate_stream_free(s) _http_encoding_deflate_stream_free((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_encoding_deflate_stream_free(http_encoding_stream **s TSRMLS_DC);
-+
-+#define http_encoding_inflate_stream_init(s, f) _http_encoding_inflate_stream_init((s), (f) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API http_encoding_stream *_http_encoding_inflate_stream_init(http_encoding_stream *s, int flags ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_inflate_stream_update(s, d, dl, e, el) _http_encoding_inflate_stream_update((s), (d), (dl), (e), (el) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_update(http_encoding_stream *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_inflate_stream_flush(s, d, dl) _http_encoding_inflate_stream_flush((s), (d), (dl) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_flush(http_encoding_stream *s, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_inflate_stream_finish(s, e, el) _http_encoding_inflate_stream_finish((s), (e), (el) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_encoding_inflate_stream_finish(http_encoding_stream *s, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+#define http_encoding_inflate_stream_dtor(s) _http_encoding_inflate_stream_dtor((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_encoding_inflate_stream_dtor(http_encoding_stream *s TSRMLS_DC);
-+#define http_encoding_inflate_stream_free(s) _http_encoding_inflate_stream_free((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_encoding_inflate_stream_free(http_encoding_stream **s TSRMLS_DC);
-+
-+#define http_ob_deflatehandler(o, ol, h, hl, m) _http_ob_deflatehandler((o), (ol), (h), (hl), (m) TSRMLS_CC)
-+extern void _http_ob_deflatehandler(char *, uint, char **, uint *, int TSRMLS_DC);
-+
-+#define http_ob_inflatehandler(o, ol, h, hl, m) _http_ob_inflatehandler((o), (ol), (h), (hl), (m) TSRMLS_CC)
-+extern void _http_ob_inflatehandler(char *, uint, char **, uint *, int TSRMLS_DC);
-+
-+#endif /* HTTP_HAVE_ZLIB */
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/php_http_exception_object.h
-@@ -0,0 +1,60 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_exception_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_EXCEPTION_OBJECT_H
-+#define PHP_HTTP_EXCEPTION_OBJECT_H
-+#ifdef ZEND_ENGINE_2
-+
-+#include "zend_exceptions.h"
-+
-+PHP_MINIT_FUNCTION(http_exception_object);
-+
-+#define HTTP_EX_DEF_CE http_exception_object_ce
-+#define HTTP_EX_CE(name) http_ ##name## _exception_object_ce
-+
-+extern zend_class_entry *http_exception_object_ce;
-+extern zend_class_entry *HTTP_EX_CE(runtime);
-+extern zend_class_entry *HTTP_EX_CE(header);
-+extern zend_class_entry *HTTP_EX_CE(malformed_headers);
-+extern zend_class_entry *HTTP_EX_CE(request_method);
-+extern zend_class_entry *HTTP_EX_CE(message_type);
-+extern zend_class_entry *HTTP_EX_CE(invalid_param);
-+extern zend_class_entry *HTTP_EX_CE(encoding);
-+extern zend_class_entry *HTTP_EX_CE(request);
-+extern zend_class_entry *HTTP_EX_CE(request_pool);
-+extern zend_class_entry *HTTP_EX_CE(socket);
-+extern zend_class_entry *HTTP_EX_CE(response);
-+extern zend_class_entry *HTTP_EX_CE(url);
-+extern zend_function_entry http_exception_object_fe[];
-+
-+#define http_exception_get_default _http_exception_get_default
-+extern zend_class_entry *_http_exception_get_default();
-+
-+#define http_exception_get_for_code(c) _http_exception_get_for_code(c)
-+extern zend_class_entry *_http_exception_get_for_code(long code);
-+
-+PHP_METHOD(HttpException, __toString);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_filter_api.h
-@@ -0,0 +1,33 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_filter_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_FILTER_API_H
-+#define PHP_HTTP_FILTER_API_H
-+#ifdef ZEND_ENGINE_2
-+
-+extern php_stream_filter_factory http_filter_factory;
-+PHP_MINIT_FUNCTION(http_filter);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_headers_api.h
-@@ -0,0 +1,77 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_headers_api.h 300300 2010-06-09 07:29:35Z mike $ */
-+
-+#ifndef PHP_HTTP_HEADERS_API_H
-+#define PHP_HTTP_HEADERS_API_H
-+
-+#include "php_http_info_api.h"
-+
-+typedef enum http_range_status_t {
-+ RANGE_OK,
-+ RANGE_NO,
-+ RANGE_ERR
-+} http_range_status;
-+
-+#define http_parse_headers(h, a) _http_parse_headers_ex((h), Z_ARRVAL_P(a), 1, http_info_default_callback, NULL TSRMLS_CC)
-+#define http_parse_headers_ex(h, ht, p) _http_parse_headers_ex((h), (ht), (p), http_info_default_callback, NULL TSRMLS_CC)
-+#define http_parse_headers_cb(h, ht, p, f, d) _http_parse_headers_ex((h), (ht), (p), (f), (d) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *headers, zend_bool prettify, http_info_callback callback_func, void **callback_data TSRMLS_DC);
-+
-+typedef char *(*negotiate_func_t)(const char *test, double *quality, HashTable *supported TSRMLS_DC);
-+
-+#define http_negotiate_language_func _http_negotiate_language_func
-+extern char *_http_negotiate_language_func(const char *test, double *quality, HashTable *supported TSRMLS_DC);
-+#define http_negotiate_content_type_func _http_negotiate_default_func
-+#define http_negotiate_encoding_func _http_negotiate_default_func
-+#define http_negotiate_charset_func _http_negotiate_default_func
-+#define http_negotiate_default_func _http_negotiate_default_func
-+extern char *_http_negotiate_default_func(const char *test, double *quality, HashTable *supported TSRMLS_DC);
-+
-+#define http_negotiate_language(zsupported) http_negotiate_language_ex(Z_ARRVAL_P(zsupported))
-+#define http_negotiate_language_ex(supported) http_negotiate_q("HTTP_ACCEPT_LANGUAGE", (supported), http_negotiate_language_func)
-+#define http_negotiate_charset(zsupported) http_negotiate_charset_ex(Z_ARRVAL_P(zsupported))
-+#define http_negotiate_charset_ex(supported) http_negotiate_q("HTTP_ACCEPT_CHARSET", (supported), http_negotiate_charset_func)
-+#define http_negotiate_encoding(zsupported) http_negotiate_encoding_ex(Z_ARRVAL_P(zsupported))
-+#define http_negotiate_encoding_ex(supported) http_negotiate_q("HTTP_ACCEPT_ENCODING", (supported), http_negotiate_encoding_func)
-+#define http_negotiate_content_type(zsupported) http_negotiate_content_type_ex(Z_ARRVAL_P(zsupported))
-+#define http_negotiate_content_type_ex(supported) http_negotiate_q("HTTP_ACCEPT", (supported), http_negotiate_content_type_func)
-+#define http_negotiate_q(e, s, n) _http_negotiate_q((e), (s), (n) TSRMLS_CC)
-+PHP_HTTP_API HashTable *_http_negotiate_q(const char *header, HashTable *supported, negotiate_func_t neg TSRMLS_DC);
-+#define http_negotiate_z(z, s, n) _http_negotiate_z((z), (s), (n) TSRMLS_CC)
-+PHP_HTTP_API HashTable *_http_negotiate_z(zval *value, HashTable *supported, negotiate_func_t neg TSRMLS_DC);
-+
-+#define http_get_request_ranges(r, l) _http_get_request_ranges((r), (l) TSRMLS_CC)
-+PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_t length TSRMLS_DC);
-+
-+#define http_get_request_headers(h) _http_get_request_headers((h) TSRMLS_CC)
-+PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC);
-+
-+#define http_get_response_headers(h) _http_get_response_headers((h) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_get_response_headers(HashTable *headers_ht TSRMLS_DC);
-+
-+#define http_match_request_header(h, v) http_match_request_header_ex((h), (v), 0)
-+#define http_match_request_header_ex(h, v, c) _http_match_request_header_ex((h), (v), (c) TSRMLS_CC)
-+PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const char *value, zend_bool match_case TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_inflatestream_object.h
-@@ -0,0 +1,57 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_inflatestream_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_INFLATESTREAM_OBJECT_H
-+#define PHP_HTTP_INFLATESTREAM_OBJECT_H
-+#ifdef HTTP_HAVE_ZLIB
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_inflatestream_object_t {
-+ zend_object zo;
-+ http_encoding_stream *stream;
-+} http_inflatestream_object;
-+
-+extern zend_class_entry *http_inflatestream_object_ce;
-+extern zend_function_entry http_inflatestream_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_inflatestream_object);
-+
-+#define http_inflatestream_object_new(ce) _http_inflatestream_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_inflatestream_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_inflatestream_object_new_ex(ce, s, ptr) _http_inflatestream_object_new_ex((ce), (s), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_inflatestream_object_new_ex(zend_class_entry *ce, http_encoding_stream *s, http_inflatestream_object **ptr TSRMLS_DC);
-+#define http_inflatestream_object_clone(zobj) _http_inflatestream_object_clone_obj(zobj TSRMLS_CC)
-+extern zend_object_value _http_inflatestream_object_clone_obj(zval *object TSRMLS_DC);
-+#define http_inflatestream_object_free(o) _http_inflatestream_object_free((o) TSRMLS_CC)
-+extern void _http_inflatestream_object_free(zend_object *object TSRMLS_DC);
-+
-+PHP_METHOD(HttpInflateStream, __construct);
-+PHP_METHOD(HttpInflateStream, factory);
-+PHP_METHOD(HttpInflateStream, update);
-+PHP_METHOD(HttpInflateStream, flush);
-+PHP_METHOD(HttpInflateStream, finish);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_info_api.h
-@@ -0,0 +1,79 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_info_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_INFO_API_H
-+#define PHP_HTTP_INFO_API_H
-+
-+#define IS_HTTP_REQUEST 1
-+#define IS_HTTP_RESPONSE 2
-+
-+#define HTTP_INFO(ptr) (ptr)->http.info
-+
-+#define HTTP_INFO_REQUEST_FMT_ARGS(_http_ptr, _EOL) "%s %s HTTP/%1.1f" _EOL, \
-+ (_http_ptr)->info.request.method?(_http_ptr)->info.request.method:"UNKNOWN", \
-+ (_http_ptr)->info.request.url?(_http_ptr)->info.request.url:"/", \
-+ (_http_ptr)->version>0.0?(_http_ptr)->version:1.1
-+
-+#define HTTP_INFO_RESPONSE_FMT_ARGS(_http_ptr, _EOL) "HTTP/%1.1f %d%s%s" _EOL, \
-+ (_http_ptr)->version>0.0?(_http_ptr)->version:1.1, \
-+ (_http_ptr)->info.response.code?(_http_ptr)->info.response.code:200, \
-+ (_http_ptr)->info.response.status&&*(_http_ptr)->info.response.status ? " ":"", \
-+ STR_PTR((_http_ptr)->info.response.status)
-+
-+typedef struct _http_request_info_t {
-+ char *method;
-+ char *url;
-+} http_request_info;
-+
-+typedef struct _http_response_info_t {
-+ int code;
-+ char *status;
-+} http_response_info;
-+
-+typedef union _http_info_union_t {
-+ http_request_info request;
-+ http_response_info response;
-+} http_info_union;
-+
-+struct http_info {
-+ http_info_union info;
-+ double version;
-+};
-+
-+typedef struct _http_info_t {
-+ struct http_info http;
-+ int type;
-+} http_info;
-+
-+typedef void (*http_info_callback)(void **callback_data, HashTable **headers, http_info *info TSRMLS_DC);
-+
-+#define http_info_default_callback _http_info_default_callback
-+PHP_HTTP_API void _http_info_default_callback(void **nothing, HashTable **headers, http_info *info TSRMLS_DC);
-+#define http_info_dtor _http_info_dtor
-+PHP_HTTP_API void _http_info_dtor(http_info *info);
-+#define http_info_parse(p, i) _http_info_parse_ex((p), (i), 1 TSRMLS_CC)
-+#define http_info_parse_ex(p, i, s) _http_info_parse_ex((p), (i), (s) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_info_parse_ex(const char *pre_header, http_info *info , zend_bool silent TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_message_api.h
-@@ -0,0 +1,131 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_message_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_MESSAGE_API_H
-+#define PHP_HTTP_MESSAGE_API_H
-+
-+#include "php_http_info_api.h"
-+
-+typedef enum _http_message_type_t {
-+ HTTP_MSG_NONE = 0,
-+ HTTP_MSG_REQUEST = IS_HTTP_REQUEST,
-+ HTTP_MSG_RESPONSE = IS_HTTP_RESPONSE,
-+} http_message_type;
-+
-+typedef struct _http_message_t http_message;
-+
-+struct _http_message_t {
-+ phpstr body;
-+ HashTable hdrs;
-+ http_message_type type;
-+ struct http_info http;
-+ http_message *parent;
-+};
-+
-+/* required minimum length of an HTTP message "HTTP/1.1" */
-+#define HTTP_MSG_MIN_SIZE 8
-+
-+/* shorthand for type checks */
-+#define HTTP_MSG_TYPE(TYPE, msg) ((msg) && ((msg)->type == HTTP_MSG_ ##TYPE))
-+
-+#define http_message_new() http_message_init_ex(NULL, 0)
-+#define http_message_init(m) http_message_init_ex((m), 0)
-+#define http_message_init_ex(m, t) _http_message_init_ex((m), (t) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-+#define http_message_init_rel(m, t) _http_message_init_ex((m), (t) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)
-+PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_type t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-+#define http_message_init_env(m, t) _http_message_init_env((m), (t) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-+PHP_HTTP_API http_message *_http_message_init_env(http_message *m, http_message_type t TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-+
-+#define http_message_set_type(m, t) _http_message_set_type((m), (t))
-+PHP_HTTP_API void _http_message_set_type(http_message *m, http_message_type t);
-+
-+#define http_message_set_info(m, i) _http_message_set_info((m), (i))
-+PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info);
-+
-+#define http_message_header(m, h) _http_message_header_ex((m), (h), sizeof(h), 1)
-+#define http_message_header_ex _http_message_header_ex
-+static inline zval *_http_message_header_ex(http_message *msg, char *key_str, size_t key_len, int join)
-+{
-+ zval **header;
-+ if (SUCCESS == zend_hash_find(&msg->hdrs, key_str, key_len, (void *) &header)) {
-+ if (join && Z_TYPE_PP(header) == IS_ARRAY) {
-+ zval *header_str, **val;
-+ HashPosition pos;
-+ phpstr str;
-+
-+ phpstr_init(&str);
-+ MAKE_STD_ZVAL(header_str);
-+ FOREACH_VAL(pos, *header, val) {
-+ phpstr_appendf(&str, PHPSTR_LEN(&str) ? ", %s":"%s", Z_STRVAL_PP(val));
-+ }
-+ phpstr_fix(&str);
-+ ZVAL_STRINGL(header_str, PHPSTR_VAL(&str), PHPSTR_LEN(&str), 0);
-+ return header_str;
-+ } else {
-+ ZVAL_ADDREF(*header);
-+ return *header;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+#define http_message_count(c, m) \
-+{ \
-+ http_message *__tmp_msg = (m); \
-+ for (c = 0; __tmp_msg; __tmp_msg = __tmp_msg->parent, ++(c)); \
-+}
-+
-+#define http_message_parse(m, l) http_message_parse_ex(NULL, (m), (l))
-+#define http_message_parse_ex(h, m, l) _http_message_parse_ex((h), (m), (l) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+#define http_message_parse_rel(h, m, l) _http_message_parse_ex((h), (m), (l) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC TSRMLS_CC)
-+PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_message_tostring(m, s, l) _http_message_tostring((m), (s), (l))
-+PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_t *length);
-+
-+#define http_message_serialize(m, s, l) _http_message_serialize((m), (s), (l))
-+PHP_HTTP_API void _http_message_serialize(http_message *message, char **string, size_t *length);
-+
-+#define http_message_reverse(m) _http_message_reverse(m)
-+PHP_HTTP_API http_message *_http_message_reverse(http_message *msg);
-+
-+#define http_message_interconnect(m1, m2) _http_message_interconnect((m1), (m2))
-+PHP_HTTP_API http_message *_http_message_interconnect(http_message *m1, http_message *m2);
-+
-+#define http_message_tostruct_recursive(m, s) _http_message_tostruct_recursive((m), (s) TSRMLS_CC)
-+PHP_HTTP_API void _http_message_tostruct_recursive(http_message *msg, zval *strct TSRMLS_DC);
-+
-+#define http_message_send(m) _http_message_send((m) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC);
-+
-+#define http_message_dup(m) _http_message_dup((m) TSRMLS_CC)
-+PHP_HTTP_API http_message *_http_message_dup(http_message *msg TSRMLS_DC);
-+
-+#define http_message_dtor(m) _http_message_dtor((m))
-+PHP_HTTP_API void _http_message_dtor(http_message *message);
-+
-+#define http_message_free(m) _http_message_free((m))
-+PHP_HTTP_API void _http_message_free(http_message **message);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_message_object.h
-@@ -0,0 +1,115 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_message_object.h 298590 2010-04-26 11:46:35Z mike $ */
-+
-+#ifndef PHP_HTTP_MESSAGE_OBJECT_H
-+#define PHP_HTTP_MESSAGE_OBJECT_H
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_message_object_t {
-+ zend_object zo;
-+ http_message *message;
-+ zend_object_value parent;
-+ zval *iterator;
-+} http_message_object;
-+
-+extern zend_class_entry *http_message_object_ce;
-+extern zend_function_entry http_message_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_message_object);
-+extern PHP_MSHUTDOWN_FUNCTION(http_message_object);
-+
-+#define http_message_object_prepend(o, p) http_message_object_prepend_ex((o), (p), 1)
-+#define http_message_object_prepend_ex(o, p, t) _http_message_object_prepend_ex((o), (p), (t) TSRMLS_CC)
-+extern void _http_message_object_prepend_ex(zval *this_ptr, zval *prepend, zend_bool top TSRMLS_DC);
-+
-+#define http_message_object_reverse(t, r) _http_message_object_reverse((t), (r) TSRMLS_CC)
-+extern void _http_message_object_reverse(zval *this_ptr, zval *return_value TSRMLS_DC);
-+
-+#define http_message_object_new(ce) _http_message_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_message_object_new_ex(ce, msg, ptr) _http_message_object_new_ex((ce), (msg), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg, http_message_object **ptr TSRMLS_DC);
-+#define http_message_object_clone(zobj) _http_message_object_clone_obj(zobj TSRMLS_CC)
-+extern zend_object_value _http_message_object_clone_obj(zval *object TSRMLS_DC);
-+#define http_message_object_free(o) _http_message_object_free((o) TSRMLS_CC)
-+extern void _http_message_object_free(zend_object *object TSRMLS_DC);
-+
-+#define HTTP_MSG_CHECK_OBJ(obj, dofail) \
-+ if (!(obj)->message) { \
-+ http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is empty"); \
-+ dofail; \
-+ }
-+#define HTTP_MSG_CHECK_STD() HTTP_MSG_CHECK_OBJ(obj, RETURN_FALSE)
-+
-+#define HTTP_MSG_INIT_OBJ(obj) \
-+ if (!(obj)->message) { \
-+ (obj)->message = http_message_new(); \
-+ }
-+#define HTTP_MSG_INIT_STD() HTTP_MSG_INIT_OBJ(obj)
-+
-+PHP_METHOD(HttpMessage, __construct);
-+PHP_METHOD(HttpMessage, getBody);
-+PHP_METHOD(HttpMessage, setBody);
-+PHP_METHOD(HttpMessage, getHeader);
-+PHP_METHOD(HttpMessage, getHeaders);
-+PHP_METHOD(HttpMessage, setHeaders);
-+PHP_METHOD(HttpMessage, addHeaders);
-+PHP_METHOD(HttpMessage, getType);
-+PHP_METHOD(HttpMessage, setType);
-+PHP_METHOD(HttpMessage, getInfo);
-+PHP_METHOD(HttpMessage, setInfo);
-+PHP_METHOD(HttpMessage, getResponseCode);
-+PHP_METHOD(HttpMessage, setResponseCode);
-+PHP_METHOD(HttpMessage, getResponseStatus);
-+PHP_METHOD(HttpMessage, setResponseStatus);
-+PHP_METHOD(HttpMessage, getRequestMethod);
-+PHP_METHOD(HttpMessage, setRequestMethod);
-+PHP_METHOD(HttpMessage, getRequestUrl);
-+PHP_METHOD(HttpMessage, setRequestUrl);
-+PHP_METHOD(HttpMessage, getHttpVersion);
-+PHP_METHOD(HttpMessage, setHttpVersion);
-+PHP_METHOD(HttpMessage, guessContentType);
-+PHP_METHOD(HttpMessage, getParentMessage);
-+PHP_METHOD(HttpMessage, send);
-+PHP_METHOD(HttpMessage, toString);
-+PHP_METHOD(HttpMessage, toMessageTypeObject);
-+
-+PHP_METHOD(HttpMessage, count);
-+PHP_METHOD(HttpMessage, serialize);
-+PHP_METHOD(HttpMessage, unserialize);
-+PHP_METHOD(HttpMessage, rewind);
-+PHP_METHOD(HttpMessage, valid);
-+PHP_METHOD(HttpMessage, current);
-+PHP_METHOD(HttpMessage, key);
-+PHP_METHOD(HttpMessage, next);
-+
-+PHP_METHOD(HttpMessage, factory);
-+PHP_METHOD(HttpMessage, fromEnv);
-+
-+PHP_METHOD(HttpMessage, detach);
-+PHP_METHOD(HttpMessage, prepend);
-+PHP_METHOD(HttpMessage, reverse);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_persistent_handle_api.h
-@@ -0,0 +1,58 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_persistent_handle_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef HTTP_PERSISTENT_HANDLE_H
-+#define HTTP_PERSISTENT_HANDLE_H
-+
-+typedef void *(*http_persistent_handle_ctor)(void);
-+typedef void (*http_persistent_handle_dtor)(void *handle);
-+typedef void *(*http_persistent_handle_copy)(void *handle);
-+
-+PHP_MINIT_FUNCTION(http_persistent_handle);
-+PHP_MSHUTDOWN_FUNCTION(http_persistent_handle);
-+
-+#define http_persistent_handle_provide(n, c, d, cc) _http_persistent_handle_provide_ex((n), strlen(n), (c), (d), (cc))
-+#define http_persistent_handle_provide_ex(n, l, c, d, cc) _http_persistent_handle_provide_ex((n), (l), (c), (d), (cc))
-+PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor, http_persistent_handle_copy copy);
-+
-+#define http_persistent_handle_cleanup(n, c) _http_persistent_handle_cleanup_ex((n), strlen(n), (c) TSRMLS_CC)
-+#define http_persistent_handle_cleanup_ex(n, l,c ) _http_persistent_handle_cleanup_ex((n), (l), (c) TSRMLS_CC)
-+PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC);
-+
-+#define http_persistent_handle_statall() _http_persistent_handle_statall_ex(NULL TSRMLS_CC)
-+#define http_persistent_handle_statall_ex(ht) _http_persistent_handle_statall_ex((ht) TSRMLS_CC)
-+PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht TSRMLS_DC);
-+
-+#define http_persistent_handle_acquire(n, h) _http_persistent_handle_acquire_ex((n), strlen(n), (h) TSRMLS_CC)
-+#define http_persistent_handle_acquire_ex(n, l, h) _http_persistent_handle_acquire_ex((n), (l), (h) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, size_t name_len, void **handle TSRMLS_DC);
-+
-+#define http_persistent_handle_release(n, h) _http_persistent_handle_release_ex((n), strlen(n), (h) TSRMLS_CC)
-+#define http_persistent_handle_release_ex(n, l, h) _http_persistent_handle_release_ex((n), (l), (h) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, size_t name_len, void **handle TSRMLS_DC);
-+
-+#define http_persistent_handle_accrete(n, oh, nh) _http_persistent_handle_accrete_ex((n), strlen(n), (oh), (nh) TSRMLS_CC)
-+#define http_persistent_handle_accrete_ex(n, l, oh, nh) _http_persistent_handle_accrete_ex((n), (l), (oh), (nh) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_persistent_handle_accrete_ex(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC);
-+
-+#endif /* HTTP_PERSISTENT_HANDLE_H */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/php_http_querystring_api.h
-@@ -0,0 +1,38 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_querystring_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_QUERYSTRING_API_H
-+#define PHP_HTTP_QUERYSTRING_API_H
-+
-+#ifdef HTTP_HAVE_ICONV
-+#define http_querystring_xlate(a, p, ie, oe) _http_querystring_xlate((a), (p), (ie), (oe) TSRMLS_CC)
-+PHP_HTTP_API int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC);
-+#endif
-+
-+#define http_querystring_update(qa, qs) _http_querystring_update((qa), (qs) TSRMLS_CC)
-+PHP_HTTP_API void _http_querystring_update(zval *qarray, zval *qstring TSRMLS_DC);
-+
-+#define http_querystring_modify(q, p) _http_querystring_modify((q), (p) TSRMLS_CC)
-+PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/php_http_querystring_object.h
-@@ -0,0 +1,78 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_querystring_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_QUERYSTRING_OBJECT_H
-+#define PHP_HTTP_QUERYSTRING_OBJECT_H
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_querystring_object_t {
-+ zend_object zo;
-+} http_querystring_object;
-+
-+#define HTTP_QUERYSTRING_TYPE_BOOL IS_BOOL
-+#define HTTP_QUERYSTRING_TYPE_INT IS_LONG
-+#define HTTP_QUERYSTRING_TYPE_FLOAT IS_DOUBLE
-+#define HTTP_QUERYSTRING_TYPE_STRING IS_STRING
-+#define HTTP_QUERYSTRING_TYPE_ARRAY IS_ARRAY
-+#define HTTP_QUERYSTRING_TYPE_OBJECT IS_OBJECT
-+
-+extern zend_class_entry *http_querystring_object_ce;
-+extern zend_function_entry http_querystring_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_querystring_object);
-+
-+#define http_querystring_object_new(ce) _http_querystring_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_querystring_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_querystring_object_new_ex(ce, n, ptr) _http_querystring_object_new_ex((ce), (n), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_querystring_object_new_ex(zend_class_entry *ce, void *nothing, http_querystring_object **ptr TSRMLS_DC);
-+#define http_querystring_object_free(o) _http_querystring_object_free((o) TSRMLS_CC)
-+extern void _http_querystring_object_free(zend_object *object TSRMLS_DC);
-+
-+PHP_METHOD(HttpQueryString, __construct);
-+PHP_METHOD(HttpQueryString, toString);
-+PHP_METHOD(HttpQueryString, toArray);
-+PHP_METHOD(HttpQueryString, get);
-+PHP_METHOD(HttpQueryString, set);
-+PHP_METHOD(HttpQueryString, mod);
-+PHP_METHOD(HttpQueryString, getBool);
-+PHP_METHOD(HttpQueryString, getInt);
-+PHP_METHOD(HttpQueryString, getFloat);
-+PHP_METHOD(HttpQueryString, getString);
-+PHP_METHOD(HttpQueryString, getArray);
-+PHP_METHOD(HttpQueryString, getObject);
-+#ifdef HTTP_HAVE_ICONV
-+PHP_METHOD(HttpQueryString, xlate);
-+#endif
-+PHP_METHOD(HttpQueryString, factory);
-+#ifndef WONKY
-+PHP_METHOD(HttpQueryString, singleton);
-+#endif
-+PHP_METHOD(HttpQueryString, serialize);
-+PHP_METHOD(HttpQueryString, unserialize);
-+PHP_METHOD(HttpQueryString, offsetGet);
-+PHP_METHOD(HttpQueryString, offsetSet);
-+PHP_METHOD(HttpQueryString, offsetExists);
-+PHP_METHOD(HttpQueryString, offsetUnset);
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_api.h
-@@ -0,0 +1,144 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_API_H
-+#define PHP_HTTP_REQUEST_API_H
-+
-+#ifdef HTTP_HAVE_CURL
-+
-+#include "php_http_request_body_api.h"
-+#include "php_http_request_method_api.h"
-+
-+extern PHP_MINIT_FUNCTION(http_request);
-+extern PHP_MSHUTDOWN_FUNCTION(http_request);
-+
-+typedef struct _http_request_t {
-+ CURL *ch;
-+ char *url;
-+ http_request_method meth;
-+ http_request_body *body;
-+
-+ struct {
-+ curl_infotype last_type;
-+ phpstr request;
-+ phpstr response;
-+ } conv;
-+
-+ struct {
-+ phpstr cookies;
-+ HashTable options;
-+ struct curl_slist *headers;
-+ } _cache;
-+
-+ struct {
-+ uint count;
-+ double delay;
-+ } _retry;
-+
-+ char _error[CURL_ERROR_SIZE+1];
-+ zval *_progress_callback;
-+
-+#ifdef ZTS
-+ void ***tsrm_ls;
-+#endif
-+
-+ uint _in_progress_cb:1;
-+
-+} http_request;
-+
-+#ifndef pestrndup
-+# define pestrndup(s,l,p) _pestrndup((s),(l),(p))
-+static inline void *_pestrndup(const void *s, size_t l, int p)
-+{
-+ void *d = pemalloc(l+1, p);
-+ memcpy(d, s, l);
-+ ((char *) d)[l] = '\0';
-+ return d;
-+}
-+#endif
-+
-+/* CURLOPT_PRIVATE storage living as long as a CURL handle */
-+typedef struct _http_request_storage_t {
-+ char *url;
-+ char *cookiestore;
-+ char errorbuffer[CURL_ERROR_SIZE];
-+} http_request_storage;
-+
-+static inline http_request_storage *http_request_storage_get(CURL *ch)
-+{
-+ http_request_storage *st = NULL;
-+ curl_easy_getinfo(ch, CURLINFO_PRIVATE, &st);
-+ return st;
-+}
-+
-+#define http_curl_init(r) http_curl_init_ex(NULL, (r))
-+#define http_curl_init_ex(c, r) _http_curl_init_ex((c), (r) TSRMLS_CC)
-+PHP_HTTP_API CURL *_http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC);
-+
-+#define http_curl_free(c) _http_curl_free((c) TSRMLS_CC)
-+PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC);
-+
-+#define http_curl_copy(c) _http_curl_copy((c) TSRMLS_CC)
-+PHP_HTTP_API CURL *_http_curl_copy(CURL *ch TSRMLS_DC);
-+
-+#define http_request_new() _http_request_init_ex(NULL, NULL, 0, NULL ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+#define http_request_init(r) _http_request_init_ex((r), NULL, 0, NULL ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+#define http_request_init_ex(r, c, m, u) _http_request_init_ex((r), (c), (m), (u) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API http_request *_http_request_init_ex(http_request *request, CURL *ch, http_request_method meth, const char *url ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_request_dtor(r) _http_request_dtor((r))
-+PHP_HTTP_API void _http_request_dtor(http_request *request);
-+
-+#define http_request_free(r) _http_request_free((r))
-+PHP_HTTP_API void _http_request_free(http_request **request);
-+
-+#define http_request_reset(r) _http_request_reset(r)
-+PHP_HTTP_API void _http_request_reset(http_request *r);
-+
-+#define http_request_enable_cookies(r) _http_request_enable_cookies(r)
-+PHP_HTTP_API STATUS _http_request_enable_cookies(http_request *request);
-+
-+#define http_request_reset_cookies(r, s) _http_request_reset_cookies((r), (s))
-+PHP_HTTP_API STATUS _http_request_reset_cookies(http_request *request, int session_only);
-+
-+#define http_request_flush_cookies(r) _http_request_flush_cookies(r)
-+PHP_HTTP_API STATUS _http_request_flush_cookies(http_request *request);
-+
-+#define http_request_defaults(r) _http_request_defaults(r)
-+PHP_HTTP_API void _http_request_defaults(http_request *request);
-+
-+#define http_request_prepare(r, o) _http_request_prepare((r), (o))
-+PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *options);
-+
-+#define http_request_exec(r) _http_request_exec((r))
-+PHP_HTTP_API void _http_request_exec(http_request *request);
-+
-+#define http_request_info(r, i) _http_request_info((r), (i))
-+PHP_HTTP_API void _http_request_info(http_request *request, HashTable *info);
-+
-+#define http_request_set_progress_callback(r, cb) _http_request_set_progress_callback((r), (cb))
-+PHP_HTTP_API void _http_request_set_progress_callback(http_request *request, zval *cb);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_body_api.h
-@@ -0,0 +1,62 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_body_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_BODY_API_H
-+#define PHP_HTTP_REQUEST_BODY_API_H
-+
-+#ifdef HTTP_HAVE_CURL
-+
-+#define HTTP_REQUEST_BODY_EMPTY 0
-+#define HTTP_REQUEST_BODY_CSTRING 1
-+#define HTTP_REQUEST_BODY_CURLPOST 2
-+#define HTTP_REQUEST_BODY_UPLOADFILE 3
-+typedef struct _http_request_body_t {
-+ void *data;
-+ size_t size;
-+ uint type:3;
-+ uint free:1;
-+ uint priv:28;
-+} http_request_body;
-+
-+
-+#define http_request_body_new() http_request_body_init(NULL)
-+#define http_request_body_init(b) http_request_body_init_ex((b), 0, NULL, 0, 0)
-+#define http_request_body_init_ex(b, t, d, l, f) _http_request_body_init_ex((b), (t), (d), (l), (f) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+#define http_request_body_init_rel(b, t, d, l, f) _http_request_body_init_ex((b), (t), (d), (l), (f) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC TSRMLS_CC)
-+PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *body, int type, void *data, size_t len, zend_bool free ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_request_body_fill(b, fields, files) _http_request_body_fill((b), (fields), (files) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC)
-+PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC);
-+
-+#define http_request_body_encode(b, s, l) _http_request_body_encode((b), (s), (l) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_request_body_encode(http_request_body *body, char **buf, size_t *len TSRMLS_DC);
-+
-+#define http_request_body_dtor(b) _http_request_body_dtor((b) TSRMLS_CC)
-+PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC);
-+
-+#define http_request_body_free(b) _http_request_body_free((b) TSRMLS_CC)
-+PHP_HTTP_API void _http_request_body_free(http_request_body **body TSRMLS_DC);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_datashare_api.h
-@@ -0,0 +1,88 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_datashare_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_DATASHARE_API_H
-+#define PHP_HTTP_REQUEST_DATASHARE_API_H
-+#ifdef HTTP_HAVE_CURL
-+#ifdef ZEND_ENGINE_2
-+
-+#ifdef ZTS
-+typedef struct _http_request_datashare_lock_t {
-+ CURL *ch;
-+ MUTEX_T mx;
-+} http_request_datashare_lock;
-+
-+typedef union _http_request_datashare_handle_t {
-+ zend_llist *list;
-+ http_request_datashare_lock *locks;
-+} http_request_datashare_handle;
-+#else
-+typedef struct _http_request_datashare_handle_t {
-+ zend_llist *list;
-+} http_request_datashare_handle;
-+#endif
-+
-+typedef struct _http_request_datashare_t {
-+ CURLSH *ch;
-+ zend_bool persistent;
-+ http_request_datashare_handle handle;
-+} http_request_datashare;
-+
-+#define HTTP_RSHARE_HANDLES(s) ((s)->persistent ? &HTTP_G->request.datashare.handles : (s)->handle.list)
-+
-+#define http_request_datashare_global_get _http_request_datashare_global_get
-+extern http_request_datashare *_http_request_datashare_global_get(void);
-+
-+extern PHP_MINIT_FUNCTION(http_request_datashare);
-+extern PHP_MSHUTDOWN_FUNCTION(http_request_datashare);
-+extern PHP_RINIT_FUNCTION(http_request_datashare);
-+extern PHP_RSHUTDOWN_FUNCTION(http_request_datashare);
-+
-+#define http_request_datashare_new() _http_request_datashare_init_ex(NULL, 0 TSRMLS_CC)
-+#define http_request_datashare_init(s) _http_request_datashare_init_ex((s), 0 TSRMLS_CC)
-+#define http_request_datashare_init_ex(s, p) _http_request_datashare_init_ex((s), (p) TSRMLS_CC)
-+PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_request_datashare *share, zend_bool persistent TSRMLS_DC);
-+
-+#define http_request_datashare_attach(s, r) _http_request_datashare_attach((s), (r) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_request_datashare_attach(http_request_datashare *share, zval *request TSRMLS_DC);
-+
-+#define http_request_datashare_detach(s, r) _http_request_datashare_detach((s), (r) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_request_datashare_detach(http_request_datashare *share, zval *request TSRMLS_DC);
-+
-+#define http_request_datashare_detach_all(s) _http_request_datashare_detach_all((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_request_datashare_detach_all(http_request_datashare *share TSRMLS_DC);
-+
-+#define http_request_datashare_dtor(s) _http_request_datashare_dtor((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_request_datashare_dtor(http_request_datashare *share TSRMLS_DC);
-+
-+#define http_request_datashare_free(s) _http_request_datashare_free((s) TSRMLS_CC)
-+PHP_HTTP_API void _http_request_datashare_free(http_request_datashare **share TSRMLS_DC);
-+
-+#define http_request_datashare_set(s, o, l, e) _http_request_datashare_set((s), (o), (l), (e) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_request_datashare_set(http_request_datashare *share, const char *option, size_t option_len, zend_bool enable TSRMLS_DC);
-+
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_int.h
-@@ -0,0 +1,72 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_int.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#if defined(ZTS) && defined(HTTP_HAVE_SSL)
-+# ifdef PHP_WIN32
-+# define HTTP_NEED_OPENSSL_TSL
-+# include <openssl/crypto.h>
-+# else /* !PHP_WIN32 */
-+# if defined(HTTP_HAVE_OPENSSL)
-+# define HTTP_NEED_OPENSSL_TSL
-+# include <openssl/crypto.h>
-+# elif defined(HTTP_HAVE_GNUTLS)
-+# define HTTP_NEED_GNUTLS_TSL
-+# include <gcrypt.h>
-+# else
-+# warning \
-+ "libcurl was compiled with SSL support, but configure could not determine which" \
-+ "library was used; thus no SSL crypto locking callbacks will be set, which may " \
-+ "cause random crashes on SSL requests"
-+# endif /* HTTP_HAVE_OPENSSL || HTTP_HAVE_GNUTLS */
-+# endif /* PHP_WIN32 */
-+#endif /* ZTS && HTTP_HAVE_SSL */
-+
-+#define HTTP_CURL_OPT(OPTION, p) curl_easy_setopt((request->ch), OPTION, (p))
-+
-+#define HTTP_CURL_OPT_STRING(OPTION, ldiff, obdc) \
-+ { \
-+ char *K = #OPTION; \
-+ HTTP_CURL_OPT_STRING_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION, obdc); \
-+ }
-+#define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \
-+ if (!strcasecmp(key.str, keyname)) { \
-+ zval *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, http_zsep(IS_STRING, *param)); \
-+ if (obdc) { \
-+ HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(copy), return FAILURE); \
-+ } \
-+ HTTP_CURL_OPT(optname, Z_STRVAL_P(copy)); \
-+ zval_ptr_dtor(©); \
-+ continue; \
-+ }
-+#define HTTP_CURL_OPT_LONG(OPTION, ldiff) \
-+ { \
-+ char *K = #OPTION; \
-+ HTTP_CURL_OPT_LONG_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION); \
-+ }
-+#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \
-+ if (!strcasecmp(key.str, keyname)) { \
-+ zval *copy = http_zsep(IS_LONG, *param); \
-+ HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \
-+ zval_ptr_dtor(©); \
-+ continue; \
-+ }
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/php_http_request_method_api.h
-@@ -0,0 +1,85 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_method_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_METHOD_API_H
-+#define PHP_HTTP_REQUEST_METHOD_API_H
-+
-+typedef enum _http_request_method_t {
-+ /* force the enum to be signed */
-+ HTTP_NEG_REQUEST_METHOD =-1,
-+ HTTP_NO_REQUEST_METHOD = 0,
-+ /* HTTP/1.1 */
-+ HTTP_GET = 1,
-+ HTTP_HEAD = 2,
-+ HTTP_POST = 3,
-+ HTTP_PUT = 4,
-+ HTTP_DELETE = 5,
-+ HTTP_OPTIONS = 6,
-+ HTTP_TRACE = 7,
-+ HTTP_CONNECT = 8,
-+ /* WebDAV - RFC 2518 */
-+ HTTP_PROPFIND = 9,
-+ HTTP_PROPPATCH = 10,
-+ HTTP_MKCOL = 11,
-+ HTTP_COPY = 12,
-+ HTTP_MOVE = 13,
-+ HTTP_LOCK = 14,
-+ HTTP_UNLOCK = 15,
-+ /* WebDAV Versioning - RFC 3253 */
-+ HTTP_VERSION_CONTROL = 16,
-+ HTTP_REPORT = 17,
-+ HTTP_CHECKOUT = 18,
-+ HTTP_CHECKIN = 19,
-+ HTTP_UNCHECKOUT = 20,
-+ HTTP_MKWORKSPACE = 21,
-+ HTTP_UPDATE = 22,
-+ HTTP_LABEL = 23,
-+ HTTP_MERGE = 24,
-+ HTTP_BASELINE_CONTROL = 25,
-+ HTTP_MKACTIVITY = 26,
-+ /* WebDAV Access Control - RFC 3744 */
-+ HTTP_ACL = 27,
-+ HTTP_MAX_REQUEST_METHOD = 28
-+} http_request_method;
-+
-+#define HTTP_MIN_REQUEST_METHOD (HTTP_NO_REQUEST_METHOD + 1)
-+#define HTTP_STD_REQUEST_METHOD(m) ((m > HTTP_NO_REQUEST_METHOD) && (m < HTTP_MAX_REQUEST_METHOD))
-+
-+extern PHP_MINIT_FUNCTION(http_request_method);
-+extern PHP_RINIT_FUNCTION(http_request_method);
-+extern PHP_RSHUTDOWN_FUNCTION(http_request_method);
-+
-+#define http_request_method_name(m) _http_request_method_name((m) TSRMLS_CC)
-+PHP_HTTP_API const char *_http_request_method_name(http_request_method m TSRMLS_DC);
-+
-+#define http_request_method_exists(u, l, c) _http_request_method_exists((u), (l), (c) TSRMLS_CC)
-+PHP_HTTP_API int _http_request_method_exists(int by_name, http_request_method id, const char *name TSRMLS_DC);
-+
-+#define http_request_method_register(m, l) _http_request_method_register((m), (l) TSRMLS_CC)
-+PHP_HTTP_API int _http_request_method_register(const char *method, int method_name_len TSRMLS_DC);
-+
-+#define http_request_method_unregister(mn) _http_request_method_unregister((mn) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_request_method_unregister(int method TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_object.h
-@@ -0,0 +1,118 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_OBJECT_H
-+#define PHP_HTTP_REQUEST_OBJECT_H
-+#ifdef HTTP_HAVE_CURL
-+#ifdef ZEND_ENGINE_2
-+
-+#include "php_http_request_api.h"
-+#include "php_http_request_pool_api.h"
-+#include "php_http_request_datashare_api.h"
-+
-+typedef struct _http_request_object_t {
-+ zend_object zo;
-+ http_request *request;
-+ http_request_pool *pool;
-+ http_request_datashare *share;
-+} http_request_object;
-+
-+extern zend_class_entry *http_request_object_ce;
-+extern zend_function_entry http_request_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_request_object);
-+
-+#define http_request_object_new(ce) _http_request_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_request_object_new_ex(ce, ch, ptr) _http_request_object_new_ex((ce), (ch), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_request_object_new_ex(zend_class_entry *ce, CURL *ch, http_request_object **ptr TSRMLS_DC);
-+#define http_request_object_clone(zv) _http_request_object_clone_obj((zv) TSRMLS_CC)
-+extern zend_object_value _http_request_object_clone_obj(zval *zobject TSRMLS_DC);
-+#define http_request_object_free(o) _http_request_object_free((o) TSRMLS_CC)
-+extern void _http_request_object_free(zend_object *object TSRMLS_DC);
-+
-+#define http_request_object_requesthandler(req, this) _http_request_object_requesthandler((req), (this) TSRMLS_CC)
-+extern STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr TSRMLS_DC);
-+#define http_request_object_responsehandler(req, this) _http_request_object_responsehandler((req), (this) TSRMLS_CC)
-+extern STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this_ptr TSRMLS_DC);
-+
-+PHP_METHOD(HttpRequest, __construct);
-+PHP_METHOD(HttpRequest, setOptions);
-+PHP_METHOD(HttpRequest, getOptions);
-+PHP_METHOD(HttpRequest, addSslOptions);
-+PHP_METHOD(HttpRequest, setSslOptions);
-+PHP_METHOD(HttpRequest, getSslOptions);
-+PHP_METHOD(HttpRequest, addHeaders);
-+PHP_METHOD(HttpRequest, getHeaders);
-+PHP_METHOD(HttpRequest, setHeaders);
-+PHP_METHOD(HttpRequest, addCookies);
-+PHP_METHOD(HttpRequest, getCookies);
-+PHP_METHOD(HttpRequest, setCookies);
-+PHP_METHOD(HttpRequest, enableCookies);
-+PHP_METHOD(HttpRequest, resetCookies);
-+PHP_METHOD(HttpRequest, flushCookies);
-+PHP_METHOD(HttpRequest, setMethod);
-+PHP_METHOD(HttpRequest, getMethod);
-+PHP_METHOD(HttpRequest, setUrl);
-+PHP_METHOD(HttpRequest, getUrl);
-+PHP_METHOD(HttpRequest, setContentType);
-+PHP_METHOD(HttpRequest, getContentType);
-+PHP_METHOD(HttpRequest, setQueryData);
-+PHP_METHOD(HttpRequest, getQueryData);
-+PHP_METHOD(HttpRequest, addQueryData);
-+PHP_METHOD(HttpRequest, setPostFields);
-+PHP_METHOD(HttpRequest, getPostFields);
-+PHP_METHOD(HttpRequest, addPostFields);
-+PHP_METHOD(HttpRequest, getBody);
-+PHP_METHOD(HttpRequest, setBody);
-+PHP_METHOD(HttpRequest, addBody);
-+PHP_METHOD(HttpRequest, addPostFile);
-+PHP_METHOD(HttpRequest, setPostFiles);
-+PHP_METHOD(HttpRequest, getPostFiles);
-+PHP_METHOD(HttpRequest, setPutFile);
-+PHP_METHOD(HttpRequest, getPutFile);
-+PHP_METHOD(HttpRequest, getPutData);
-+PHP_METHOD(HttpRequest, setPutData);
-+PHP_METHOD(HttpRequest, addPutData);
-+PHP_METHOD(HttpRequest, send);
-+PHP_METHOD(HttpRequest, getResponseData);
-+PHP_METHOD(HttpRequest, getResponseHeader);
-+PHP_METHOD(HttpRequest, getResponseCookies);
-+PHP_METHOD(HttpRequest, getResponseCode);
-+PHP_METHOD(HttpRequest, getResponseStatus);
-+PHP_METHOD(HttpRequest, getResponseBody);
-+PHP_METHOD(HttpRequest, getResponseInfo);
-+PHP_METHOD(HttpRequest, getResponseMessage);
-+PHP_METHOD(HttpRequest, getRawResponseMessage);
-+PHP_METHOD(HttpRequest, getRequestMessage);
-+PHP_METHOD(HttpRequest, getRawRequestMessage);
-+PHP_METHOD(HttpRequest, getHistory);
-+PHP_METHOD(HttpRequest, clearHistory);
-+PHP_METHOD(HttpRequest, getMessageClass);
-+PHP_METHOD(HttpRequest, setMessageClass);
-+PHP_METHOD(HttpRequest, factory);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_request_pool_api.h
-@@ -0,0 +1,97 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_request_pool_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_POOL_API_H
-+#define PHP_HTTP_REQUEST_POOL_API_H
-+#ifdef HTTP_HAVE_CURL
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_request_pool_t {
-+ CURLM *ch;
-+ zend_llist finished;
-+ zend_llist handles;
-+ int unfinished;
-+#ifdef ZTS
-+ void ***tsrm_ls;
-+#endif
-+#ifdef HTTP_HAVE_EVENT
-+ struct event *timeout;
-+ unsigned useevents:1;
-+ unsigned runsocket:1;
-+#endif
-+} http_request_pool;
-+
-+typedef int (*http_request_pool_apply_func)(http_request_pool *pool, zval *request);
-+typedef int (*http_request_pool_apply_with_arg_func)(http_request_pool *pool, zval *request, void *arg);
-+
-+PHP_MINIT_FUNCTION(http_request_pool);
-+#ifdef HTTP_HAVE_EVENT
-+PHP_RINIT_FUNCTION(http_request_pool);
-+#endif
-+
-+#define http_request_pool_timeout _http_request_pool_timeout
-+extern struct timeval *_http_request_pool_timeout(http_request_pool *pool, struct timeval *timeout);
-+
-+#define http_request_pool_responsehandler _http_request_pool_responsehandler
-+extern void _http_request_pool_responsehandler(http_request_pool *pool);
-+
-+#define http_request_pool_apply_responsehandler _http_request_pool_responsehandler
-+extern int _http_request_pool_apply_responsehandler(http_request_pool *pool, zval *req, void *ch);
-+
-+#define http_request_pool_init(p) _http_request_pool_init((p) TSRMLS_CC)
-+PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool TSRMLS_DC);
-+
-+#define http_request_pool_attach(p, r) _http_request_pool_attach((p), (r))
-+PHP_HTTP_API STATUS _http_request_pool_attach(http_request_pool *pool, zval *request);
-+
-+#define http_request_pool_detach(p, r) _http_request_pool_detach((p), (r))
-+PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *request);
-+
-+#define http_request_pool_apply(p, f) _http_request_pool_apply((p), (f))
-+PHP_HTTP_API void _http_request_pool_apply(http_request_pool *pool, http_request_pool_apply_func cb);
-+
-+#define http_request_pool_apply_with_arg(p, f, a) _http_request_pool_apply_with_arg((p), (f), (a))
-+PHP_HTTP_API void _http_request_pool_apply_with_arg(http_request_pool *pool, http_request_pool_apply_with_arg_func cb, void *arg);
-+
-+#define http_request_pool_detach_all(p) _http_request_pool_detach_all((p))
-+PHP_HTTP_API void _http_request_pool_detach_all(http_request_pool *pool);
-+
-+#define http_request_pool_send(p) _http_request_pool_send((p))
-+PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool);
-+
-+#define http_request_pool_select _http_request_pool_select
-+PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool);
-+
-+#define http_request_pool_select_ex _http_request_pool_select_ex
-+PHP_HTTP_API STATUS _http_request_pool_select_ex(http_request_pool *pool, struct timeval *custom_timeout);
-+
-+#define http_request_pool_perform(p) _http_request_pool_perform((p))
-+PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool);
-+
-+#define http_request_pool_dtor(p) _http_request_pool_dtor((p))
-+PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_requestdatashare_object.h
-@@ -0,0 +1,59 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_requestdatashare_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUEST_DATASHARE_OBJECT_H
-+#define PHP_HTTP_REQUEST_DATASHARE_OBJECT_H
-+#ifdef HTTP_HAVE_CURL
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_requestdatashare_object_t {
-+ zend_object zo;
-+ http_request_datashare *share;
-+} http_requestdatashare_object;
-+
-+extern zend_class_entry *http_requestdatashare_object_ce;
-+extern zend_function_entry http_requestdatashare_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_requestdatashare_object);
-+
-+#define http_requestdatashare_object_new(ce) _http_requestdatashare_object_new((ce) TSRMLS_CC)
-+extern zend_object_value _http_requestdatashare_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_requestdatashare_object_new_ex(ce, s, ptr) _http_requestdatashare_object_new_ex((ce), (s), (ptr) TSRMLS_CC)
-+extern zend_object_value _http_requestdatashare_object_new_ex(zend_class_entry *ce, http_request_datashare *share, http_requestdatashare_object **ptr TSRMLS_DC);
-+#define http_requestdatashare_object_free(o) _http_requestdatashare_object_free((o) TSRMLS_CC)
-+extern void _http_requestdatashare_object_free(zend_object *object TSRMLS_DC);
-+
-+PHP_METHOD(HttpRequestDataShare, __destruct);
-+PHP_METHOD(HttpRequestDataShare, count);
-+PHP_METHOD(HttpRequestDataShare, attach);
-+PHP_METHOD(HttpRequestDataShare, detach);
-+PHP_METHOD(HttpRequestDataShare, reset);
-+PHP_METHOD(HttpRequestDataShare, factory);
-+#ifndef WONKY
-+PHP_METHOD(HttpRequestDataShare, singleton);
-+#endif
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_requestpool_object.h
-@@ -0,0 +1,69 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_requestpool_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_REQUESTPOOL_OBJECT_H
-+#define PHP_HTTP_REQUESTPOOL_OBJECT_H
-+#ifdef HTTP_HAVE_CURL
-+#ifdef ZEND_ENGINE_2
-+
-+typedef struct _http_requestpool_object_t {
-+ zend_object zo;
-+ http_request_pool pool;
-+ struct {
-+ long pos;
-+ } iterator;
-+} http_requestpool_object;
-+
-+extern zend_class_entry *http_requestpool_object_ce;
-+extern zend_function_entry http_requestpool_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_requestpool_object);
-+
-+#define http_requestpool_object_new(ce) _http_requestpool_object_new(ce TSRMLS_CC)
-+extern zend_object_value _http_requestpool_object_new(zend_class_entry *ce TSRMLS_DC);
-+#define http_requestpool_object_free(o) _http_requestpool_object_free(o TSRMLS_CC)
-+extern void _http_requestpool_object_free(zend_object *object TSRMLS_DC);
-+
-+PHP_METHOD(HttpRequestPool, __construct);
-+PHP_METHOD(HttpRequestPool, __destruct);
-+PHP_METHOD(HttpRequestPool, attach);
-+PHP_METHOD(HttpRequestPool, detach);
-+PHP_METHOD(HttpRequestPool, send);
-+PHP_METHOD(HttpRequestPool, reset);
-+PHP_METHOD(HttpRequestPool, socketPerform);
-+PHP_METHOD(HttpRequestPool, socketSelect);
-+PHP_METHOD(HttpRequestPool, valid);
-+PHP_METHOD(HttpRequestPool, current);
-+PHP_METHOD(HttpRequestPool, key);
-+PHP_METHOD(HttpRequestPool, next);
-+PHP_METHOD(HttpRequestPool, rewind);
-+PHP_METHOD(HttpRequestPool, count);
-+PHP_METHOD(HttpRequestPool, getAttachedRequests);
-+PHP_METHOD(HttpRequestPool, getFinishedRequests);
-+PHP_METHOD(HttpRequestPool, enablePipelining);
-+PHP_METHOD(HttpRequestPool, enableEvents);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_response_object.h
-@@ -0,0 +1,67 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_response_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_RESPONSE_OBJECT_H
-+#define PHP_HTTP_RESPONSE_OBJECT_H
-+#ifdef ZEND_ENGINE_2
-+#ifndef WONKY
-+
-+extern zend_class_entry *http_response_object_ce;
-+extern zend_function_entry http_response_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_response_object);
-+
-+PHP_METHOD(HttpResponse, setHeader);
-+PHP_METHOD(HttpResponse, getHeader);
-+PHP_METHOD(HttpResponse, setETag);
-+PHP_METHOD(HttpResponse, getETag);
-+PHP_METHOD(HttpResponse, setLastModified);
-+PHP_METHOD(HttpResponse, getLastModified);
-+PHP_METHOD(HttpResponse, setContentDisposition);
-+PHP_METHOD(HttpResponse, getContentDisposition);
-+PHP_METHOD(HttpResponse, setContentType);
-+PHP_METHOD(HttpResponse, getContentType);
-+PHP_METHOD(HttpResponse, guessContentType);
-+PHP_METHOD(HttpResponse, setCache);
-+PHP_METHOD(HttpResponse, getCache);
-+PHP_METHOD(HttpResponse, setCacheControl);
-+PHP_METHOD(HttpResponse, getCacheControl);
-+PHP_METHOD(HttpResponse, setGzip);
-+PHP_METHOD(HttpResponse, getGzip);
-+PHP_METHOD(HttpResponse, setThrottleDelay);
-+PHP_METHOD(HttpResponse, getThrottleDelay);
-+PHP_METHOD(HttpResponse, setBufferSize);
-+PHP_METHOD(HttpResponse, getBufferSize);
-+PHP_METHOD(HttpResponse, setData);
-+PHP_METHOD(HttpResponse, getData);
-+PHP_METHOD(HttpResponse, setFile);
-+PHP_METHOD(HttpResponse, getFile);
-+PHP_METHOD(HttpResponse, setStream);
-+PHP_METHOD(HttpResponse, getStream);
-+PHP_METHOD(HttpResponse, send);
-+PHP_METHOD(HttpResponse, capture);
-+
-+#endif
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_send_api.h
-@@ -0,0 +1,91 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_send_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_SEND_API_H
-+#define PHP_HTTP_SEND_API_H
-+
-+typedef enum _http_send_mode_t {
-+ SEND_DATA,
-+ SEND_RSRC
-+} http_send_mode;
-+
-+#define HTTP_REDIRECT 0L
-+#define HTTP_REDIRECT_PERM 301L
-+#define HTTP_REDIRECT_FOUND 302L
-+#define HTTP_REDIRECT_POST 303L
-+#define HTTP_REDIRECT_PROXY 305L
-+#define HTTP_REDIRECT_TEMP 307L
-+
-+extern PHP_MINIT_FUNCTION(http_send);
-+
-+#define http_send_status(s) sapi_header_op(SAPI_HEADER_SET_STATUS, (void *) (long) (s) TSRMLS_CC)
-+#define http_send_header(n, v, r) _http_send_header_ex((n), strlen(n), (v), strlen(v), (r), NULL TSRMLS_CC)
-+#define http_send_header_ex(n, nl, v, vl, r, s) _http_send_header_ex((n), (nl), (v), (vl), (r), (s) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_header_ex(const char *name, size_t name_len, const char *value, size_t value_len, zend_bool replace, char **sent_header TSRMLS_DC);
-+#define http_send_header_string(h) _http_send_status_header_ex(0, (h), strlen(h), 1 TSRMLS_CC)
-+#define http_send_header_string_ex(h, l, r) _http_send_status_header_ex(0, (h), (l), (r) TSRMLS_CC)
-+#define http_send_status_header(s, h) _http_send_status_header_ex((s), (h), (h)?strlen(h):0, 1 TSRMLS_CC)
-+#define http_send_status_header_ex(s, h, l, r) _http_send_status_header_ex((s), (h), (l), (r) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_status_header_ex(int status, const char *header, size_t header_len, zend_bool replace TSRMLS_DC);
-+
-+#define http_send_header_zval(n, z, r) http_send_header_zval_ex((n), strlen(n), (z), (r))
-+#define http_send_header_zval_ex(n, l, z, r) _http_send_header_zval_ex((n), (l), (z), (r) TSRMLS_CC)
-+PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, zval **val, zend_bool replace TSRMLS_DC);
-+
-+#define http_hide_header(h) http_hide_header_ex((h), strlen(h))
-+#define http_hide_header_ex(h, l) _http_hide_header_ex((h), (l) TSRMLS_CC)
-+PHP_HTTP_API void _http_hide_header_ex(const char *name, size_t name_len TSRMLS_DC);
-+
-+#define http_send_last_modified(t) _http_send_last_modified_ex((t), NULL TSRMLS_CC)
-+#define http_send_last_modified_ex(t, s) _http_send_last_modified_ex((t), (s) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_last_modified_ex(time_t t, char **sent_header TSRMLS_DC);
-+
-+#define http_send_etag(e, l) _http_send_etag_ex((e), (l), NULL TSRMLS_CC)
-+#define http_send_etag_ex(e, l, s) _http_send_etag_ex((e), (l), (s) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_etag_ex(const char *etag, size_t etag_len, char **sent_header TSRMLS_DC);
-+
-+#define http_send_cache_control(cc, cl) http_send_header_ex("Cache-Control", lenof("Cache-Control"), (cc), (cl), 1, NULL)
-+
-+#define http_send_content_type(c, l) _http_send_content_type((c), (l) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_content_type(const char *content_type, size_t ct_len TSRMLS_DC);
-+
-+#define http_send_content_disposition(f, l, i) _http_send_content_disposition((f), (l), (i) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_content_disposition(const char *filename, size_t f_len, zend_bool send_inline TSRMLS_DC);
-+
-+#define http_send_data(d, l) http_send((d), (l), SEND_DATA)
-+#define http_send_data_ex(d, l, nc) http_send_ex((d), (l), SEND_DATA, (nc))
-+#define http_send(d, s, m) _http_send_ex((d), (s), (m), 0 TSRMLS_CC)
-+#define http_send_ex(d, s, m, nc) _http_send_ex((d), (s), (m), (nc) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_ex(const void *data, size_t data_size, http_send_mode mode, zend_bool no_cache TSRMLS_DC);
-+
-+#define http_send_file(f) http_send_stream_ex(php_stream_open_wrapper_ex(f, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT), 1, 0)
-+#define http_send_file_ex(f, nc) http_send_stream_ex(php_stream_open_wrapper_ex(f, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT), 1, (nc))
-+#define http_send_stream(s) http_send_stream_ex((s), 0, 0)
-+#define http_send_stream_ex(s, c, nc) _http_send_stream_ex((s), (c), (nc) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_send_stream_ex(php_stream *s, zend_bool close_stream, zend_bool no_cache TSRMLS_DC);
-+
-+#define http_guess_content_type(mf, mm, d, l, m) _http_guess_content_type((mf), (mm), (d), (l), (m) TSRMLS_CC)
-+PHP_HTTP_API char *_http_guess_content_type(const char *magic_file, long magic_mode, void *data_ptr, size_t data_len, http_send_mode mode TSRMLS_DC);
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_std_defs.h
-@@ -0,0 +1,410 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_std_defs.h 323304 2012-02-17 21:13:24Z mike $ */
-+
-+#ifndef PHP_HTTP_STD_DEFS_H
-+#define PHP_HTTP_STD_DEFS_H
-+
-+#if defined(PHP_WIN32)
-+# if defined(HTTP_EXPORTS)
-+# define PHP_HTTP_API __declspec(dllexport)
-+# elif defined(COMPILE_DL_HTTP)
-+# define PHP_HTTP_API __declspec(dllimport)
-+# else
-+# define PHP_HTTP_API
-+# endif
-+#else
-+# define PHP_HTTP_API
-+#endif
-+
-+/* make functions that return SUCCESS|FAILURE more obvious */
-+typedef int STATUS;
-+
-+/* lenof() */
-+#define lenof(S) (sizeof(S) - 1)
-+
-+#ifndef MIN
-+# define MIN(a,b) (a<b?a:b)
-+#endif
-+#ifndef MAX
-+# define MAX(a,b) (a>b?a:b)
-+#endif
-+
-+/* STR_SET() */
-+#ifndef STR_SET
-+# define STR_SET(STR, SET) \
-+ { \
-+ STR_FREE(STR); \
-+ STR = SET; \
-+ }
-+#endif
-+
-+#define STR_PTR(s) (s?s:"")
-+
-+#define INIT_ZARR(zv, ht) \
-+ { \
-+ INIT_PZVAL(&(zv)); \
-+ Z_TYPE(zv) = IS_ARRAY; \
-+ Z_ARRVAL(zv) = (ht); \
-+ }
-+
-+/* return bool (v == SUCCESS) */
-+#define RETVAL_SUCCESS(v) RETVAL_BOOL(SUCCESS == (v))
-+#define RETURN_SUCCESS(v) RETURN_BOOL(SUCCESS == (v))
-+/* return object(values) */
-+#define RETVAL_OBJECT(o, addref) \
-+ RETVAL_OBJVAL((o)->value.obj, addref)
-+#define RETURN_OBJECT(o, addref) \
-+ RETVAL_OBJECT(o, addref); \
-+ return
-+#define RETVAL_OBJVAL(ov, addref) \
-+ ZVAL_OBJVAL(return_value, ov, addref)
-+#define RETURN_OBJVAL(ov, addref) \
-+ RETVAL_OBJVAL(ov, addref); \
-+ return
-+#define ZVAL_OBJVAL(zv, ov, addref) \
-+ (zv)->type = IS_OBJECT; \
-+ (zv)->value.obj = (ov);\
-+ if (addref && Z_OBJ_HT_P(zv)->add_ref) { \
-+ Z_OBJ_HT_P(zv)->add_ref((zv) TSRMLS_CC); \
-+ }
-+/* return property */
-+#define RETVAL_PROP(n) RETVAL_PROP_EX(getThis(), n)
-+#define RETURN_PROP(n) RETURN_PROP_EX(getThis(), n)
-+#define RETVAL_PROP_EX(this, n) \
-+ { \
-+ zval *__prop = zend_read_property(THIS_CE, this, ZEND_STRS(#n)-1, 0 TSRMLS_CC); \
-+ RETVAL_ZVAL(__prop, 1, 0); \
-+ }
-+#define RETURN_PROP_EX(this, n) \
-+ { \
-+ zval *__prop = zend_read_property(THIS_CE, this, ZEND_STRS(#n)-1, 0 TSRMLS_CC); \
-+ RETURN_ZVAL(__prop, 1, 0); \
-+ }
-+
-+/* function accepts no args */
-+#define NO_ARGS zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "");
-+
-+/* CR LF */
-+#define HTTP_CRLF "\r\n"
-+
-+/* default cache control */
-+#define HTTP_DEFAULT_CACHECONTROL "private, must-revalidate, max-age=0"
-+
-+/* max URL length */
-+#define HTTP_URL_MAXLEN 4096
-+
-+/* max request method length */
-+#define HTTP_REQUEST_METHOD_MAXLEN 31
-+
-+/* def URL arg separator */
-+#define HTTP_URL_ARGSEP "&"
-+
-+/* send buffer size */
-+#define HTTP_SENDBUF_SIZE 40960
-+
-+/* CURL buffer size */
-+#define HTTP_CURLBUF_SIZE 16384
-+
-+/* known methods */
-+#define HTTP_KNOWN_METHODS \
-+ /* HTTP 1.1 */ \
-+ "GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT, " \
-+ /* WebDAV - RFC 2518 */ \
-+ "PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, " \
-+ /* WebDAV Versioning - RFC 3253 */ \
-+ "VERSION-CONTROL, REPORT, CHECKOUT, CHECKIN, UNCHECKOUT, " \
-+ "MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, " \
-+ /* WebDAV Access Control - RFC 3744 */ \
-+ "ACL, " \
-+ /* END */
-+
-+#ifdef ZEND_ENGINE_2
-+# include "ext/standard/file.h"
-+# define HTTP_DEFAULT_STREAM_CONTEXT FG(default_context)
-+#else
-+# define HTTP_DEFAULT_STREAM_CONTEXT NULL
-+#endif
-+
-+#define HTTP_PHP_INI_ENTRY(entry, default, scope, updater, global) \
-+ STD_PHP_INI_ENTRY(entry, default, scope, updater, global, zend_http_globals, http_globals)
-+#define HTTP_PHP_INI_ENTRY_EX(entry, default, scope, updater, displayer, global) \
-+ STD_PHP_INI_ENTRY_EX(entry, default, scope, updater, global, zend_http_globals, http_globals, displayer)
-+
-+
-+#define HTTP_LONG_CONSTANT(name, const) REGISTER_LONG_CONSTANT(name, const, CONST_CS | CONST_PERSISTENT)
-+
-+/* {{{ objects & properties */
-+#ifdef ZEND_ENGINE_2
-+
-+# define HTTP_STATIC_ME_ALIAS(me, al, ai) ZEND_FENTRY(me, ZEND_FN(al), ai, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-+
-+# define HTTP_REGISTER_CLASS_EX(classname, name, parent, flags) \
-+ { \
-+ zend_class_entry ce; \
-+ memset(&ce, 0, sizeof(zend_class_entry)); \
-+ INIT_CLASS_ENTRY(ce, #classname, name## _fe); \
-+ ce.create_object = _ ##name## _new; \
-+ name## _ce = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
-+ name## _ce->ce_flags |= flags; \
-+ memcpy(& name## _handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
-+ }
-+
-+# define HTTP_REGISTER_CLASS(classname, name, parent, flags) \
-+ { \
-+ zend_class_entry ce; \
-+ memset(&ce, 0, sizeof(zend_class_entry)); \
-+ INIT_CLASS_ENTRY(ce, #classname, name## _fe); \
-+ ce.create_object = NULL; \
-+ name## _ce = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
-+ name## _ce->ce_flags |= flags; \
-+ }
-+
-+# define HTTP_REGISTER_EXCEPTION(classname, cename, parent) \
-+ { \
-+ zend_class_entry ce; \
-+ memset(&ce, 0, sizeof(zend_class_entry)); \
-+ INIT_CLASS_ENTRY(ce, #classname, NULL); \
-+ ce.create_object = NULL; \
-+ cename = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
-+ }
-+
-+# define getObject(t, o) getObjectEx(t, o, getThis())
-+# define getObjectEx(t, o, v) t * o = ((t *) zend_object_store_get_object(v TSRMLS_CC))
-+# define putObject(t, o) zend_objects_store_put(o, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) _ ##t## _free, NULL TSRMLS_CC);
-+# if defined(ZEND_ENGINE_2_4)
-+# define freeObject(o) \
-+ zend_object_std_dtor(o TSRMLS_CC); \
-+ efree(o);
-+# elif !defined(WONKY)
-+# define freeObject(o) \
-+ if (OBJ_GUARDS(o)) { \
-+ zend_hash_destroy(OBJ_GUARDS(o)); \
-+ FREE_HASHTABLE(OBJ_GUARDS(o)); \
-+ } \
-+ if (OBJ_PROP(o)) { \
-+ zend_hash_destroy(OBJ_PROP(o)); \
-+ FREE_HASHTABLE(OBJ_PROP(o)); \
-+ } \
-+ efree(o);
-+# else
-+# define freeObject(o) \
-+ if (OBJ_PROP(o)) { \
-+ zend_hash_destroy(OBJ_PROP(o)); \
-+ FREE_HASHTABLE(OBJ_PROP(o)); \
-+ } \
-+ efree(o);
-+# endif
-+# define OBJ_PROP(o) (o)->zo.properties
-+# define OBJ_GUARDS(o) (o)->zo.guards
-+
-+# define ACC_PROP_PRIVATE(ce, flags) ((flags & ZEND_ACC_PRIVATE) && (EG(scope) && ce == EG(scope))
-+# define ACC_PROP_PROTECTED(ce, flags) ((flags & ZEND_ACC_PROTECTED) && (zend_check_protected(ce, EG(scope))))
-+# define ACC_PROP_PUBLIC(flags) (flags & ZEND_ACC_PUBLIC)
-+# define ACC_PROP(ce, flags) (ACC_PROP_PUBLIC(flags) || ACC_PROP_PRIVATE(ce, flags) || ACC_PROP_PROTECTED(ce, flags))
-+
-+# define SET_EH_THROW_HTTP() SET_EH_THROW_EX(http_exception_get_default())
-+# define SET_EH_THROW_EX(ex) php_set_error_handling(EH_THROW, ex TSRMLS_CC)
-+# define SET_EH_NORMAL() php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC)
-+
-+#endif /* ZEND_ENGINE_2 */
-+/* }}} */
-+
-+#ifdef ZEND_ENGINE_2
-+# define with_error_handling(eh, ec) \
-+ { \
-+ error_handling_t __eh = GLOBAL_ERROR_HANDLING; \
-+ zend_class_entry *__ec= GLOBAL_EXCEPTION_CLASS; \
-+ php_set_error_handling(eh, ec TSRMLS_CC);
-+# define end_error_handling() \
-+ php_set_error_handling(__eh, __ec TSRMLS_CC); \
-+ }
-+#else
-+# define with_error_handling(eh, ec)
-+# define end_error_handling()
-+#endif
-+
-+#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION > 5
-+# define ZEND_EXCEPTION_GET_DEFAULT() zend_exception_get_default(TSRMLS_C)
-+#else
-+# define ZEND_EXCEPTION_GET_DEFAULT() zend_exception_get_default()
-+#endif
-+
-+#ifndef E_THROW
-+# define E_THROW 0
-+#endif
-+#ifdef ZEND_ENGINE_2
-+# define HE_THROW E_THROW TSRMLS_CC
-+# define HE_NOTICE (HTTP_G->only_exceptions ? E_THROW : E_NOTICE) TSRMLS_CC
-+# define HE_WARNING (HTTP_G->only_exceptions ? E_THROW : E_WARNING) TSRMLS_CC
-+# define HE_ERROR (HTTP_G->only_exceptions ? E_THROW : E_ERROR) TSRMLS_CC
-+#else
-+# define HE_THROW E_WARNING TSRMLS_CC
-+# define HE_NOTICE E_NOTICE TSRMLS_CC
-+# define HE_WARNING E_WARNING TSRMLS_CC
-+# define HE_ERROR E_ERROR TSRMLS_CC
-+#endif
-+
-+#define HTTP_E_RUNTIME 1L
-+#define HTTP_E_INVALID_PARAM 2L
-+#define HTTP_E_HEADER 3L
-+#define HTTP_E_MALFORMED_HEADERS 4L
-+#define HTTP_E_REQUEST_METHOD 5L
-+#define HTTP_E_MESSAGE_TYPE 6L
-+#define HTTP_E_ENCODING 7L
-+#define HTTP_E_REQUEST 8L
-+#define HTTP_E_REQUEST_POOL 9L
-+#define HTTP_E_SOCKET 10L
-+#define HTTP_E_RESPONSE 11L
-+#define HTTP_E_URL 12L
-+#define HTTP_E_QUERYSTRING 13L
-+
-+#ifdef ZEND_ENGINE_2
-+# define HTTP_BEGIN_ARGS_EX(class, method, ret_ref, req_args) HTTP_STATIC_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(args_for_ ##class## _ ##method , 0, ret_ref, req_args)
-+# define HTTP_BEGIN_ARGS_AR(class, method, ret_ref, req_args) HTTP_STATIC_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(args_for_ ##class## _ ##method , 1, ret_ref, req_args)
-+# define HTTP_END_ARGS }
-+# define HTTP_EMPTY_ARGS_EX(class, method, ret_ref) HTTP_BEGIN_ARGS_EX(class, method, ret_ref, 0) HTTP_END_ARGS
-+# define HTTP_ARGS(class, method) args_for_ ##class## _ ##method
-+# define HTTP_ARG_VAL(name, pass_ref) ZEND_ARG_INFO(pass_ref, name)
-+# define HTTP_ARG_OBJ(class, name, allow_null) ZEND_ARG_OBJ_INFO(0, name, class, allow_null)
-+#endif
-+
-+#ifdef ZEND_ENGINE_2
-+# define EMPTY_FUNCTION_ENTRY {NULL, NULL, NULL, 0, 0}
-+#else
-+# define EMPTY_FUNCTION_ENTRY {NULL, NULL, NULL}
-+#endif
-+
-+#ifdef HTTP_HAVE_CURL
-+# ifdef ZEND_ENGINE_2
-+# define HTTP_DECLARE_ARG_PASS_INFO() \
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_2, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO(); \
-+ \
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_3, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO(); \
-+ \
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_4, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO(); \
-+ \
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_5, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO();
-+
-+# else
-+# define HTTP_DECLARE_ARG_PASS_INFO() \
-+ static unsigned char http_arg_pass_ref_2[] = {2, BYREF_NONE, BYREF_FORCE}; \
-+ static unsigned char http_arg_pass_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \
-+ static unsigned char http_arg_pass_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \
-+ static unsigned char http_arg_pass_ref_5[] = {5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-+# endif /* ZEND_ENGINE_2 */
-+#else
-+# ifdef ZEND_ENGINE_2
-+# define HTTP_DECLARE_ARG_PASS_INFO() \
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_2, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO(); \
-+\
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_3, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO(); \
-+\
-+ HTTP_STATIC_ARG_INFO \
-+ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_4, 0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(0) \
-+ ZEND_ARG_PASS_INFO(1) \
-+ ZEND_END_ARG_INFO();
-+# else
-+# define HTTP_DECLARE_ARG_PASS_INFO() \
-+ static unsigned char http_arg_pass_ref_2[] = {2, BYREF_NONE, BYREF_FORCE}; \
-+ static unsigned char http_arg_pass_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \
-+ static unsigned char http_arg_pass_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-+# endif /* ZEND_ENGINE_2 */
-+#endif /* HTTP_HAVE_CURL */
-+
-+
-+#ifndef HAVE_CURL_SHARE_STRERROR
-+# define curl_share_strerror(dummy) "unknown error"
-+#endif
-+#ifndef HAVE_CURL_EASY_STRERROR
-+# define curl_easy_strerror(dummy) "unknown error"
-+#endif
-+#ifndef HAVE_CURL_MULTI_STRERROR
-+# define curl_multi_strerror(dummy) "unknown error"
-+#endif
-+
-+#define PHP_MINIT_CALL(func) PHP_MINIT(func)(INIT_FUNC_ARGS_PASSTHRU)
-+#define PHP_RINIT_CALL(func) PHP_RINIT(func)(INIT_FUNC_ARGS_PASSTHRU)
-+#define PHP_MSHUTDOWN_CALL(func) PHP_MSHUTDOWN(func)(SHUTDOWN_FUNC_ARGS_PASSTHRU)
-+#define PHP_RSHUTDOWN_CALL(func) PHP_RSHUTDOWN(func)(SHUTDOWN_FUNC_ARGS_PASSTHRU)
-+
-+#define Z_OBJ_DELREF(z) \
-+ if (Z_OBJ_HT(z)->del_ref) { \
-+ Z_OBJ_HT(z)->del_ref(&(z) TSRMLS_CC); \
-+ }
-+#define Z_OBJ_ADDREF(z) \
-+ if (Z_OBJ_HT(z)->add_ref) { \
-+ Z_OBJ_HT(z)->add_ref(&(z) TSRMLS_CC); \
-+ }
-+#define Z_OBJ_DELREF_P(z) \
-+ if (Z_OBJ_HT_P(z)->del_ref) { \
-+ Z_OBJ_HT_P(z)->del_ref((z) TSRMLS_CC); \
-+ }
-+#define Z_OBJ_ADDREF_P(z) \
-+ if (Z_OBJ_HT_P(z)->add_ref) { \
-+ Z_OBJ_HT_P(z)->add_ref((z) TSRMLS_CC); \
-+ }
-+#define Z_OBJ_DELREF_PP(z) \
-+ if (Z_OBJ_HT_PP(z)->del_ref) { \
-+ Z_OBJ_HT_PP(z)->del_ref(*(z) TSRMLS_CC); \
-+ }
-+#define Z_OBJ_ADDREF_PP(z) \
-+ if (Z_OBJ_HT_PP(z)->add_ref) { \
-+ Z_OBJ_HT_PP(z)->add_ref(*(z) TSRMLS_CC); \
-+ }
-+
-+#endif /* PHP_HTTP_STD_DEFS_H */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_url_api.h
-@@ -0,0 +1,165 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_url_api.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_URL_API_H
-+#define PHP_HTTP_URL_API_H
-+
-+#include "ext/standard/url.h"
-+
-+extern PHP_MINIT_FUNCTION(http_url);
-+
-+#define http_absolute_url(u) _http_absolute_url_ex((u), HTTP_URL_REPLACE TSRMLS_CC)
-+#define http_absolute_url_ex(u, f) _http_absolute_url_ex((u), (f) TSRMLS_CC)
-+PHP_HTTP_API char *_http_absolute_url_ex(const char *url, int flags TSRMLS_DC);
-+
-+#define HTTP_URL_REPLACE 0x000
-+#define HTTP_URL_JOIN_PATH 0x001
-+#define HTTP_URL_JOIN_QUERY 0x002
-+#define HTTP_URL_STRIP_USER 0x004
-+#define HTTP_URL_STRIP_PASS 0x008
-+#define HTTP_URL_STRIP_AUTH (HTTP_URL_STRIP_USER|HTTP_URL_STRIP_PASS)
-+#define HTTP_URL_STRIP_PORT 0x020
-+#define HTTP_URL_STRIP_PATH 0x040
-+#define HTTP_URL_STRIP_QUERY 0x080
-+#define HTTP_URL_STRIP_FRAGMENT 0x100
-+#define HTTP_URL_STRIP_ALL ( \
-+ HTTP_URL_STRIP_AUTH | \
-+ HTTP_URL_STRIP_PORT | \
-+ HTTP_URL_STRIP_PATH | \
-+ HTTP_URL_STRIP_QUERY | \
-+ HTTP_URL_STRIP_FRAGMENT \
-+)
-+#define HTTP_URL_FROM_ENV 0x1000
-+
-+#define http_build_url(f, o, n, p, s, l) _http_build_url((f), (o), (n), (p), (s), (l) TSRMLS_CC)
-+PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_url *new_url, php_url **url_ptr, char **url_str, size_t *url_len TSRMLS_DC);
-+
-+#define http_urlencode_hash(h, q) _http_urlencode_hash_ex((h), 1, NULL, 0, (q), NULL TSRMLS_CC)
-+#define http_urlencode_hash_ex(h, o, p, pl, q, ql) _http_urlencode_hash_ex((h), (o), (p), (pl), (q), (ql) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_urlencode_hash_ex(HashTable *hash, zend_bool override_argsep, char *pre_encoded_data, size_t pre_encoded_len, char **encoded_data, size_t *encoded_len TSRMLS_DC);
-+
-+#define http_urlencode_hash_recursive(ht, s, as, al, pr, pl) _http_urlencode_hash_recursive((ht), (s), (as), (al), (pr), (pl) TSRMLS_CC)
-+PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, const char *arg_sep, size_t arg_sep_len, const char *prefix, size_t prefix_len TSRMLS_DC);
-+
-+#define http_url_from_struct(u, ht) _http_url_from_struct((u), (ht) TSRMLS_CC)
-+static inline php_url *_http_url_from_struct(php_url *url, HashTable *ht TSRMLS_DC)
-+{
-+ zval **e;
-+
-+ if (!url) {
-+ url = ecalloc(1, sizeof(php_url));
-+ }
-+
-+ if ((SUCCESS == zend_hash_find(ht, "scheme", sizeof("scheme"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->scheme = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "user", sizeof("user"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->user = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "pass", sizeof("pass"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->pass = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "host", sizeof("host"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->host = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "path", sizeof("path"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->path = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "query", sizeof("query"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->query = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if ((SUCCESS == zend_hash_find(ht, "fragment", sizeof("fragment"), (void *) &e))
-+ && (Z_TYPE_PP(e) == IS_STRING) && Z_STRLEN_PP(e)) {
-+ url->fragment = estrndup(Z_STRVAL_PP(e), Z_STRLEN_PP(e));
-+ }
-+ if (SUCCESS == zend_hash_find(ht, "port", sizeof("port"), (void *) &e)) {
-+ if (Z_TYPE_PP(e) == IS_LONG) {
-+ url->port = (unsigned short) Z_LVAL_PP(e);
-+ } else {
-+ zval *o = http_zsep(IS_LONG, *e);
-+
-+ url->port = (unsigned short) Z_LVAL_P(o);
-+ zval_ptr_dtor(&o);
-+ }
-+ }
-+
-+ return url;
-+}
-+
-+#define http_url_tostruct(u, strct) _http_url_tostruct((u), (strct) TSRMLS_CC)
-+static inline HashTable *_http_url_tostruct(php_url *url, zval *strct TSRMLS_DC)
-+{
-+ zval arr;
-+
-+ if (strct) {
-+ switch (Z_TYPE_P(strct)) {
-+ default:
-+ zval_dtor(strct);
-+ array_init(strct);
-+ case IS_ARRAY:
-+ case IS_OBJECT:
-+ INIT_ZARR(arr, HASH_OF(strct));
-+ }
-+ } else {
-+ INIT_PZVAL(&arr);
-+ array_init(&arr);
-+ }
-+
-+ if (url) {
-+ if (url->scheme) {
-+ add_assoc_string(&arr, "scheme", url->scheme, 1);
-+ }
-+ if (url->user) {
-+ add_assoc_string(&arr, "user", url->user, 1);
-+ }
-+ if (url->pass) {
-+ add_assoc_string(&arr, "pass", url->pass, 1);
-+ }
-+ if (url->host) {
-+ add_assoc_string(&arr, "host", url->host, 1);
-+ }
-+ if (url->port) {
-+ add_assoc_long(&arr, "port", (long) url->port);
-+ }
-+ if (url->path) {
-+ add_assoc_string(&arr, "path", url->path, 1);
-+ }
-+ if (url->query) {
-+ add_assoc_string(&arr, "query", url->query, 1);
-+ }
-+ if (url->fragment) {
-+ add_assoc_string(&arr, "fragment", url->fragment, 1);
-+ }
-+ }
-+
-+ return Z_ARRVAL(arr);
-+}
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/php_http_util_object.h
-@@ -0,0 +1,35 @@
-+/*
-+ +--------------------------------------------------------------------+
-+ | PECL :: http |
-+ +--------------------------------------------------------------------+
-+ | Redistribution and use in source and binary forms, with or without |
-+ | modification, are permitted provided that the conditions mentioned |
-+ | in the accompanying LICENSE file are met. |
-+ +--------------------------------------------------------------------+
-+ | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
-+ +--------------------------------------------------------------------+
-+*/
-+
-+/* $Id: php_http_util_object.h 292841 2009-12-31 08:48:57Z mike $ */
-+
-+#ifndef PHP_HTTP_UTIL_OBJECT_H
-+#define PHP_HTTP_UTIL_OBJECT_H
-+#ifdef ZEND_ENGINE_2
-+
-+extern zend_class_entry *http_util_object_ce;
-+extern zend_function_entry http_util_object_fe[];
-+
-+extern PHP_MINIT_FUNCTION(http_util_object);
-+
-+#endif
-+#endif
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/phpstr/phpstr.c
-@@ -0,0 +1,379 @@
-+
-+/* $Id: phpstr.c 211942 2006-04-24 17:17:09Z mike $ */
-+
-+#include "php.h"
-+#include "phpstr.h"
-+
-+PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags)
-+{
-+ if (!buf) {
-+ buf = pemalloc(sizeof(phpstr), flags & PHPSTR_INIT_PERSISTENT);
-+ }
-+
-+ if (buf) {
-+ buf->size = (chunk_size) ? chunk_size : PHPSTR_DEFAULT_SIZE;
-+ buf->pmem = (flags & PHPSTR_INIT_PERSISTENT) ? 1 : 0;
-+ buf->data = (flags & PHPSTR_INIT_PREALLOC) ? pemalloc(buf->size, buf->pmem) : NULL;
-+ buf->free = (flags & PHPSTR_INIT_PREALLOC) ? buf->size : 0;
-+ buf->used = 0;
-+ }
-+
-+ return buf;
-+}
-+
-+PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t length)
-+{
-+ if ((buf = phpstr_init(buf))) {
-+ if (PHPSTR_NOMEM == phpstr_append(buf, string, length)) {
-+ pefree(buf, buf->pmem);
-+ buf = NULL;
-+ }
-+ }
-+ return buf;
-+}
-+
-+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size, int allow_error)
-+{
-+ char *ptr = NULL;
-+#if 0
-+ fprintf(stderr, "RESIZE: size=%lu, used=%lu, free=%lu\n", buf->size, buf->used, buf->free);
-+#endif
-+ if (buf->free < len) {
-+ size_t size = override_size ? override_size : buf->size;
-+
-+ while ((size + buf->free) < len) {
-+ size <<= 1;
-+ }
-+
-+ if (allow_error) {
-+ ptr = perealloc_recoverable(buf->data, buf->used + buf->free + size, buf->pmem);
-+ } else {
-+ ptr = perealloc(buf->data, buf->used + buf->free + size, buf->pmem);
-+ }
-+
-+ if (ptr) {
-+ buf->data = ptr;
-+ } else {
-+ return PHPSTR_NOMEM;
-+ }
-+
-+ buf->free += size;
-+ return size;
-+ }
-+ return 0;
-+}
-+
-+PHPSTR_API size_t phpstr_shrink(phpstr *buf)
-+{
-+ /* avoid another realloc on fixation */
-+ if (buf->free > 1) {
-+ char *ptr = perealloc(buf->data, buf->used + 1, buf->pmem);
-+
-+ if (ptr) {
-+ buf->data = ptr;
-+ } else {
-+ return PHPSTR_NOMEM;
-+ }
-+ buf->free = 1;
-+ }
-+ return buf->used;
-+}
-+
-+PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len)
-+{
-+ if (PHPSTR_NOMEM == phpstr_resize(buf, append_len)) {
-+ return PHPSTR_NOMEM;
-+ }
-+ memcpy(buf->data + buf->used, append, append_len);
-+ buf->used += append_len;
-+ buf->free -= append_len;
-+ return append_len;
-+}
-+
-+PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...)
-+{
-+ va_list argv;
-+ char *append;
-+ size_t append_len, alloc;
-+
-+ va_start(argv, format);
-+ append_len = vspprintf(&append, 0, format, argv);
-+ va_end(argv);
-+
-+ alloc = phpstr_append(buf, append, append_len);
-+ efree(append);
-+
-+ if (PHPSTR_NOMEM == alloc) {
-+ return PHPSTR_NOMEM;
-+ }
-+ return append_len;
-+}
-+
-+PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset)
-+{
-+ if (PHPSTR_NOMEM == phpstr_resize(buf, insert_len)) {
-+ return PHPSTR_NOMEM;
-+ }
-+ memmove(buf->data + offset + insert_len, buf->data + offset, insert_len);
-+ memcpy(buf->data + offset, insert, insert_len);
-+ buf->used += insert_len;
-+ buf->free -= insert_len;
-+ return insert_len;
-+}
-+
-+PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...)
-+{
-+ va_list argv;
-+ char *insert;
-+ size_t insert_len, alloc;
-+
-+ va_start(argv, format);
-+ insert_len = vspprintf(&insert, 0, format, argv);
-+ va_end(argv);
-+
-+ alloc = phpstr_insert(buf, insert, insert_len, offset);
-+ efree(insert);
-+
-+ if (PHPSTR_NOMEM == alloc) {
-+ return PHPSTR_NOMEM;
-+ }
-+ return insert_len;
-+}
-+
-+PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len)
-+{
-+ if (PHPSTR_NOMEM == phpstr_resize(buf, prepend_len)) {
-+ return PHPSTR_NOMEM;
-+ }
-+ memmove(buf->data + prepend_len, buf->data, buf->used);
-+ memcpy(buf->data, prepend, prepend_len);
-+ buf->used += prepend_len;
-+ buf->free -= prepend_len;
-+ return prepend_len;
-+}
-+
-+PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...)
-+{
-+ va_list argv;
-+ char *prepend;
-+ size_t prepend_len, alloc;
-+
-+ va_start(argv, format);
-+ prepend_len = vspprintf(&prepend, 0, format, argv);
-+ va_end(argv);
-+
-+ alloc = phpstr_prepend(buf, prepend, prepend_len);
-+ efree(prepend);
-+
-+ if (PHPSTR_NOMEM == alloc) {
-+ return PHPSTR_NOMEM;
-+ }
-+ return prepend_len;
-+}
-+
-+PHPSTR_API char *phpstr_data(const phpstr *buf, char **into, size_t *len)
-+{
-+ char *copy = ecalloc(1, buf->used + 1);
-+ memcpy(copy, buf->data, buf->used);
-+ if (into) {
-+ *into = copy;
-+ }
-+ if (len) {
-+ *len = buf->used;
-+ }
-+ return copy;
-+}
-+
-+PHPSTR_API phpstr *phpstr_dup(const phpstr *buf)
-+{
-+ phpstr *dup = phpstr_clone(buf);
-+ if (PHPSTR_NOMEM == phpstr_append(dup, buf->data, buf->used)) {
-+ phpstr_free(&dup);
-+ }
-+ return dup;
-+}
-+
-+PHPSTR_API size_t phpstr_cut(phpstr *buf, size_t offset, size_t length)
-+{
-+ if (offset >= buf->used) {
-+ return 0;
-+ }
-+ if (offset + length > buf->used) {
-+ length = buf->used - offset;
-+ }
-+ memmove(buf->data + offset, buf->data + offset + length, buf->used - length);
-+ buf->used -= length;
-+ buf->free += length;
-+ return length;
-+}
-+
-+PHPSTR_API phpstr *phpstr_sub(const phpstr *buf, size_t offset, size_t length)
-+{
-+ if (offset >= buf->used) {
-+ return NULL;
-+ } else {
-+ size_t need = 1 + ((length + offset) > buf->used ? (buf->used - offset) : (length - offset));
-+ phpstr *sub = phpstr_init_ex(NULL, need, PHPSTR_INIT_PREALLOC | (buf->pmem ? PHPSTR_INIT_PERSISTENT:0));
-+ if (sub) {
-+ if (PHPSTR_NOMEM == phpstr_append(sub, buf->data + offset, need)) {
-+ phpstr_free(&sub);
-+ } else {
-+ sub->size = buf->size;
-+ }
-+ }
-+ return sub;
-+ }
-+}
-+
-+PHPSTR_API phpstr *phpstr_right(const phpstr *buf, size_t length)
-+{
-+ if (length < buf->used) {
-+ return phpstr_sub(buf, buf->used - length, length);
-+ } else {
-+ return phpstr_sub(buf, 0, buf->used);
-+ }
-+}
-+
-+
-+PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv)
-+{
-+ unsigned i = 0;
-+ buf = phpstr_init(buf);
-+
-+ if (buf) {
-+ while (argc > i++) {
-+ phpstr_free_t f = va_arg(argv, phpstr_free_t);
-+ phpstr *current = va_arg(argv, phpstr *);
-+ phpstr_append(buf, current->data, current->used);
-+ FREE_PHPSTR(f, current);
-+ }
-+ }
-+
-+ return buf;
-+}
-+
-+PHPSTR_API phpstr *phpstr_merge_ex(phpstr *buf, unsigned argc, ...)
-+{
-+ va_list argv;
-+ phpstr *ret;
-+
-+ va_start(argv, argc);
-+ ret = phpstr_merge_va(buf, argc, argv);
-+ va_end(argv);
-+ return ret;
-+}
-+
-+PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...)
-+{
-+ va_list argv;
-+ phpstr *ret;
-+
-+ va_start(argv, argc);
-+ ret = phpstr_merge_va(NULL, argc, argv);
-+ va_end(argv);
-+ return ret;
-+}
-+
-+PHPSTR_API phpstr *phpstr_fix(phpstr *buf)
-+{
-+ if (PHPSTR_NOMEM == phpstr_resize_ex(buf, 1, 1, 0)) {
-+ return NULL;
-+ }
-+ buf->data[buf->used] = '\0';
-+ return buf;
-+}
-+
-+PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right)
-+{
-+ if (left->used > right->used) {
-+ return -1;
-+ } else if (right->used > left->used) {
-+ return 1;
-+ } else {
-+ return memcmp(left->data, right->data, left->used);
-+ }
-+}
-+
-+PHPSTR_API void phpstr_reset(phpstr *buf)
-+{
-+ buf->free += buf->used;
-+ buf->used = 0;
-+}
-+
-+PHPSTR_API void phpstr_dtor(phpstr *buf)
-+{
-+ if (buf->data) {
-+ pefree(buf->data, buf->pmem);
-+ buf->data = NULL;
-+ }
-+ buf->used = 0;
-+ buf->free = 0;
-+}
-+
-+PHPSTR_API void phpstr_free(phpstr **buf)
-+{
-+ if (*buf) {
-+ phpstr_dtor(*buf);
-+ pefree(*buf, (*buf)->pmem);
-+ *buf = NULL;
-+ }
-+}
-+
-+PHPSTR_API size_t phpstr_chunk_buffer(phpstr **s, const char *data, size_t data_len, char **chunk, size_t chunk_size)
-+{
-+ phpstr *storage;
-+
-+ *chunk = NULL;
-+
-+ if (!*s) {
-+ *s = phpstr_init_ex(NULL, chunk_size << 1, chunk_size ? PHPSTR_INIT_PREALLOC : 0);
-+ }
-+ storage = *s;
-+
-+ if (data_len) {
-+ phpstr_append(storage, data, data_len);
-+ }
-+
-+ if (!chunk_size) {
-+ phpstr_data(storage, chunk, &chunk_size);
-+ phpstr_free(s);
-+ return chunk_size;
-+ }
-+
-+ if (storage->used >= (chunk_size = storage->size >> 1)) {
-+ *chunk = estrndup(storage->data, chunk_size);
-+ phpstr_cut(storage, 0, chunk_size);
-+ return chunk_size;
-+ }
-+
-+ return 0;
-+}
-+
-+PHPSTR_API void phpstr_chunked_output(phpstr **s, const char *data, size_t data_len, size_t chunk_len, phpstr_passthru_func passthru, void *opaque TSRMLS_DC)
-+{
-+ char *chunk = NULL;
-+ size_t got = 0;
-+
-+ while ((got = phpstr_chunk_buffer(s, data, data_len, &chunk, chunk_len))) {
-+ passthru(opaque, chunk, got TSRMLS_CC);
-+ if (!chunk_len) {
-+ /* we already got the last chunk,
-+ and freed all resources */
-+ break;
-+ }
-+ data = NULL;
-+ data_len = 0;
-+ STR_SET(chunk, NULL);
-+ }
-+ STR_FREE(chunk);
-+}
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
-+
---- /dev/null
-+++ b/ext/http/phpstr/phpstr.h
-@@ -0,0 +1,224 @@
-+
-+/* $Id: phpstr.h 229282 2007-02-07 15:31:50Z mike $ */
-+
-+#ifndef _PHPSTR_H_
-+#define _PHPSTR_H_
-+
-+#ifndef PHPSTR_DEFAULT_SIZE
-+# define PHPSTR_DEFAULT_SIZE 256
-+#endif
-+
-+#define PHPSTR_NOMEM ((size_t) -1)
-+
-+#ifndef STR_FREE
-+# define STR_FREE(STR) \
-+ { \
-+ if (STR) { \
-+ efree(STR); \
-+ } \
-+ }
-+#endif
-+#ifndef STR_SET
-+# define STR_SET(STR, SET) \
-+ { \
-+ STR_FREE(STR); \
-+ STR = SET; \
-+ }
-+#endif
-+#ifndef TSRMLS_D
-+# define TSRMLS_D
-+# define TSRMLS_DC
-+# define TSRMLS_CC
-+# define TSRMLS_C
-+#endif
-+#ifdef PHP_ATTRIBUTE_FORMAT
-+# define PHPSTR_ATTRIBUTE_FORMAT(f, a, b) PHP_ATTRIBUTE_FORMAT(f, a, b)
-+#else
-+# define PHPSTR_ATTRIBUTE_FORMAT(f, a, b)
-+#endif
-+#ifndef pemalloc
-+# define pemalloc(s,p) malloc(s)
-+# define pefree(x,p) free(x)
-+# define perealloc(x,s,p) realloc(x,s)
-+# define perealloc_recoverable perealloc
-+# define ecalloc calloc
-+static inline void *estrndup(void *p, size_t s)
-+{
-+ char *r = (char *) malloc(s+1);
-+ if (r) memcpy((void *) r, p, s), r[s] = '\0';
-+ return (void *) r;
-+}
-+#endif
-+
-+#if defined(PHP_WIN32)
-+# if defined(PHPSTR_EXPORTS)
-+# define PHPSTR_API __declspec(dllexport)
-+# elif defined(COMPILE_DL_PHPSTR)
-+# define PHPSTR_API __declspec(dllimport)
-+# else
-+# define PHPSTR_API
-+# endif
-+#else
-+# define PHPSTR_API
-+#endif
-+
-+#define PHPSTR(p) ((phpstr *) (p))
-+#define PHPSTR_VAL(p) (PHPSTR(p))->data
-+#define PHPSTR_LEN(p) (PHPSTR(p))->used
-+
-+#define FREE_PHPSTR_PTR(STR) pefree(STR, STR->pmem)
-+#define FREE_PHPSTR_VAL(STR) phpstr_dtor(STR)
-+#define FREE_PHPSTR_ALL(STR) phpstr_free(&(STR))
-+#define FREE_PHPSTR(free, STR) \
-+ switch (free) \
-+ { \
-+ case PHPSTR_FREE_NOT: break; \
-+ case PHPSTR_FREE_PTR: pefree(STR, STR->pmem); break; \
-+ case PHPSTR_FREE_VAL: phpstr_dtor(STR); break; \
-+ case PHPSTR_FREE_ALL: \
-+ { \
-+ phpstr *PTR = (STR); \
-+ phpstr_free(&PTR); \
-+ } \
-+ break; \
-+ default: break; \
-+ }
-+
-+#define RETURN_PHPSTR_PTR(STR) RETURN_PHPSTR((STR), PHPSTR_FREE_PTR, 0)
-+#define RETURN_PHPSTR_VAL(STR) RETURN_PHPSTR((STR), PHPSTR_FREE_NOT, 0)
-+#define RETURN_PHPSTR_DUP(STR) RETURN_PHPSTR((STR), PHPSTR_FREE_NOT, 1)
-+#define RETVAL_PHPSTR_PTR(STR) RETVAL_PHPSTR((STR), PHPSTR_FREE_PTR, 0)
-+#define RETVAL_PHPSTR_VAL(STR) RETVAL_PHPSTR((STR), PHPSTR_FREE_NOT, 0)
-+#define RETVAL_PHPSTR_DUP(STR) RETVAL_PHPSTR((STR), PHPSTR_FREE_NOT, 1)
-+/* RETURN_PHPSTR(buf, PHPSTR_FREE_PTR, 0) */
-+#define RETURN_PHPSTR(STR, free, dup) \
-+ RETVAL_PHPSTR((STR), (free), (dup)); \
-+ return;
-+
-+#define RETVAL_PHPSTR(STR, free, dup) \
-+ phpstr_fix(STR); \
-+ RETVAL_STRINGL((STR)->data, (STR)->used, (dup)); \
-+ FREE_PHPSTR((free), (STR));
-+
-+typedef struct _phpstr_t {
-+ char *data;
-+ size_t used;
-+ size_t free;
-+ size_t size;
-+ unsigned pmem:1;
-+ unsigned reserved:31;
-+} phpstr;
-+
-+typedef enum _phpstr_free_t {
-+ PHPSTR_FREE_NOT = 0,
-+ PHPSTR_FREE_PTR, /* pefree() */
-+ PHPSTR_FREE_VAL, /* phpstr_dtor() */
-+ PHPSTR_FREE_ALL /* phpstr_free() */
-+} phpstr_free_t;
-+
-+#define PHPSTR_ALL_FREE(STR) PHPSTR_FREE_ALL,(STR)
-+#define PHPSTR_PTR_FREE(STR) PHPSTR_FREE_PTR,(STR)
-+#define PHPSTR_VAL_FREE(STR) PHPSTR_FREE_VAL,(STR)
-+#define PHPSTR_NOT_FREE(STR) PHPSTR_FREE_NOT,(STR)
-+
-+#define PHPSTR_INIT_PREALLOC 0x01
-+#define PHPSTR_INIT_PERSISTENT 0x02
-+
-+/* create a new phpstr */
-+#define phpstr_new() phpstr_init(NULL)
-+#define phpstr_init(b) phpstr_init_ex(b, PHPSTR_DEFAULT_SIZE, 0)
-+#define phpstr_clone(phpstr_pointer) phpstr_init_ex(NULL, (phpstr_pointer)->size, (phpstr_pointer)->pmem ? PHPSTR_INIT_PERSISTENT:0)
-+PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags);
-+
-+/* create a phpstr from a zval or c-string */
-+#define phpstr_from_zval(z) phpstr_from_string(Z_STRVAL(z), Z_STRLEN(z))
-+#define phpstr_from_zval_ex(b, z) phpstr_from_string_ex(b, Z_STRVAL(z), Z_STRLEN(z))
-+#define phpstr_from_string(s, l) phpstr_from_string_ex(NULL, (s), (l))
-+PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t length);
-+
-+/* usually only called from within the internal functions */
-+#define phpstr_resize(b, s) phpstr_resize_ex((b), (s), 0, 0)
-+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size, int allow_error);
-+
-+/* shrink memory chunk to actually used size (+1) */
-+PHPSTR_API size_t phpstr_shrink(phpstr *buf);
-+
-+/* append data to the phpstr */
-+#define phpstr_appends(b, a) phpstr_append((b), (a), sizeof(a)-1)
-+#define phpstr_appendl(b, a) phpstr_append((b), (a), strlen(a))
-+PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len);
-+PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...) PHPSTR_ATTRIBUTE_FORMAT(printf, 2, 3);
-+
-+/* insert data at a specific position of the phpstr */
-+#define phpstr_inserts(b, i, o) phpstr_insert((b), (i), sizeof(i)-1, (o))
-+#define phpstr_insertl(b, i, o) phpstr_insert((b), (i), strlen(i), (o))
-+PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset);
-+PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...) PHPSTR_ATTRIBUTE_FORMAT(printf, 3, 4);
-+
-+/* prepend data */
-+#define phpstr_prepends(b, p) phpstr_prepend((b), (p), sizeof(p)-1)
-+#define phpstr_prependl(b, p) phpstr_prepend((b), (p), strlen(p))
-+PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len);
-+PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...) PHPSTR_ATTRIBUTE_FORMAT(printf, 2, 3);
-+
-+/* get a zero-terminated string */
-+PHPSTR_API char *phpstr_data(const phpstr *buf, char **into, size_t *len);
-+
-+/* get a part of the phpstr */
-+#define phpstr_mid(b, o, l) phpstr_sub((b), (o), (l))
-+#define phpstr_left(b, l) phpstr_sub((b), 0, (l))
-+PHPSTR_API phpstr *phpstr_right(const phpstr *buf, size_t length);
-+PHPSTR_API phpstr *phpstr_sub(const phpstr *buf, size_t offset, size_t len);
-+
-+/* remove a substring */
-+PHPSTR_API size_t phpstr_cut(phpstr *buf, size_t offset, size_t length);
-+
-+/* get a complete phpstr duplicate */
-+PHPSTR_API phpstr *phpstr_dup(const phpstr *buf);
-+
-+/* merge several phpstr objects
-+ use like:
-+
-+ phpstr *final = phpstr_merge(3,
-+ PHPSTR_NOT_FREE(&keep),
-+ PHPSTR_ALL_FREE(middle_ptr),
-+ PHPSTR_VAL_FREE(&local);
-+*/
-+PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...);
-+PHPSTR_API phpstr *phpstr_merge_ex(phpstr *buf, unsigned argc, ...);
-+PHPSTR_API phpstr *phpstr_merge_va(phpstr *buf, unsigned argc, va_list argv);
-+
-+/* sets a trailing NUL byte */
-+PHPSTR_API phpstr *phpstr_fix(phpstr *buf);
-+
-+/* memcmp for phpstr objects */
-+PHPSTR_API int phpstr_cmp(phpstr *left, phpstr *right);
-+
-+/* reset phpstr object */
-+PHPSTR_API void phpstr_reset(phpstr *buf);
-+
-+/* free a phpstr objects contents */
-+PHPSTR_API void phpstr_dtor(phpstr *buf);
-+
-+/* free a phpstr object completely */
-+PHPSTR_API void phpstr_free(phpstr **buf);
-+
-+/* stores data in a phpstr until it reaches chunk_size */
-+PHPSTR_API size_t phpstr_chunk_buffer(phpstr **s, const char *data, size_t data_len, char **chunk, size_t chunk_size);
-+
-+typedef void (*phpstr_passthru_func)(void *opaque, const char *, size_t TSRMLS_DC);
-+
-+/* wrapper around phpstr_chunk_buffer, which passes available chunks to passthru() */
-+PHPSTR_API void phpstr_chunked_output(phpstr **s, const char *data, size_t data_len, size_t chunk_size, phpstr_passthru_func passthru, void *opaque TSRMLS_DC);
-+
-+#endif
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_001.phpt
-@@ -0,0 +1,70 @@
-+--TEST--
-+HttpMessage
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$m = new HttpMessage(
-+ "HTTP/1.1 301\r\n".
-+ "Location: /anywhere\r\n".
-+ "HTTP/1.1 302\r\n".
-+ "Location: /somewhere\r\n".
-+ "HTTP/1.1 206 Partial content\r\n".
-+ "Content-Range: bytes=2-3\r\n".
-+ "Transfer-Encoding: chunked\r\n".
-+ "\r\n".
-+ "01\r\n".
-+ "X\r\n".
-+ "00"
-+);
-+
-+var_dump($m->getResponseStatus());
-+
-+$x = $m->getParentMessage();
-+$x = $m->getParentMessage();
-+$x = $m->getParentMessage();
-+
-+var_dump($m->getBody());
-+var_dump(HttpMessage::fromString($m->toString(true))->toString(true));
-+try {
-+ do {
-+ var_dump($m->toString());
-+ } while ($m = $m->getParentMessage());
-+} catch (HttpException $ex) {
-+}
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(15) "Partial content"
-+string(1) "X"
-+string(190) "HTTP/1.1 301
-+Location: /anywhere
-+HTTP/1.1 302
-+Location: /somewhere
-+HTTP/1.1 206 Partial content
-+Content-Range: bytes=2-3
-+X-Original-Transfer-Encoding: chunked
-+Content-Length: 1
-+
-+X
-+"
-+string(119) "HTTP/1.1 206 Partial content
-+Content-Range: bytes=2-3
-+X-Original-Transfer-Encoding: chunked
-+Content-Length: 1
-+
-+X
-+"
-+string(36) "HTTP/1.1 302
-+Location: /somewhere
-+"
-+string(35) "HTTP/1.1 301
-+Location: /anywhere
-+"
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_002.phpt
-@@ -0,0 +1,65 @@
-+--TEST--
-+HttpMessage properties
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpMessage');
-+?>
-+--FILE--
-+<?php
-+class Message extends HttpMessage
-+{
-+ var $var_property = 'var';
-+ public $public_property = 'public';
-+ protected $protected_property = 'protected';
-+ private $private_property = 'private';
-+
-+ public function test()
-+ {
-+ var_dump($this->var_property);
-+ var_dump($this->public_property);
-+ var_dump($this->protected_property);
-+ var_dump($this->private_property);
-+ var_dump($this->non_ex_property);
-+ $this->var_property.='_property';
-+ $this->public_property.='_property';
-+ $this->protected_property.='_property';
-+ $this->private_property.='_property';
-+ $this->non_ex_property = 'non_ex';
-+ var_dump($this->var_property);
-+ var_dump($this->public_property);
-+ var_dump($this->protected_property);
-+ var_dump($this->private_property);
-+ var_dump($this->non_ex_property);
-+
-+ print_r($this->headers);
-+ $this->headers['Foo'] = 'Bar';
-+ }
-+}
-+
-+error_reporting(E_ALL|E_STRICT);
-+
-+echo "-TEST\n";
-+$m = new Message;
-+$m->test();
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(3) "var"
-+string(6) "public"
-+string(9) "protected"
-+string(7) "private"
-+
-+Notice: Undefined property: Message::$non_ex_property in %s
-+NULL
-+string(12) "var_property"
-+string(15) "public_property"
-+string(18) "protected_property"
-+string(16) "private_property"
-+string(6) "non_ex"
-+Array
-+(
-+)
-+%aFatal error%sCannot access HttpMessage properties by reference or array key/index in%s
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_003.phpt
-@@ -0,0 +1,70 @@
-+--TEST--
-+HttpMessage implements Serializable, Countable
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$m = new HttpMessage(
-+ "HTTP/1.1 301\r\n".
-+ "Location: /anywhere\r\n".
-+ "HTTP/1.1 302\r\n".
-+ "Location: /somewhere\r\n".
-+ "HTTP/1.1 200\r\n".
-+ "Transfer-Encoding: chunked\r\n".
-+ "\r\n".
-+ "01\r\n".
-+ "X\r\n".
-+ "00"
-+);
-+
-+var_dump($m->count());
-+var_dump($m->serialize());
-+$m->unserialize("HTTP/1.1 200 Ok\r\nServer: Funky/1.0");
-+var_dump($m);
-+var_dump($m->count());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+int(3)
-+string(148) "HTTP/1.1 301
-+Location: /anywhere
-+HTTP/1.1 302
-+Location: /somewhere
-+HTTP/1.1 200
-+X-Original-Transfer-Encoding: chunked
-+Content-Length: 1
-+
-+X
-+"
-+object(HttpMessage)#%d (%d) {
-+ ["type%s]=>
-+ int(2)
-+ ["body%s]=>
-+ string(0) ""
-+ ["requestMethod%s]=>
-+ string(0) ""
-+ ["requestUrl%s]=>
-+ string(0) ""
-+ ["responseStatus%s]=>
-+ string(2) "Ok"
-+ ["responseCode%s]=>
-+ int(200)
-+ ["httpVersion%s]=>
-+ float(1.1)
-+ ["headers%s]=>
-+ array(1) {
-+ ["Server"]=>
-+ string(9) "Funky/1.0"
-+ }
-+ ["parentMessage%s]=>
-+ NULL
-+}
-+int(1)
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_004.phpt
-@@ -0,0 +1,36 @@
-+--TEST--
-+HttpMessage::detach()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$m = new HttpMessage("
-+GET / HTTP/1.1
-+Host: example.com
-+Accept: */*
-+Connection: close
-+HTTP/1.1 200 ok
-+Server: Funky/1.0
-+Content-Type: text/plain
-+Content-Length: 3
-+
-+Hi!"
-+);
-+
-+$d = $m->detach();
-+$d->addHeaders(array('Server'=>'Funky/2.0'));
-+var_dump($d->getHeaders() == $m->getHeaders());
-+var_dump($d->getBody());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(false)
-+string(3) "Hi!"
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_005.phpt
-@@ -0,0 +1,86 @@
-+--TEST--
-+HttpMessage::prepend()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$m1 = new HttpMessage("
-+GET / HTTP/1.1
-+Host: example.com
-+Accept: */*
-+Connection: close
-+HTTP/1.1 200 ok
-+Server: Funky/1.0
-+Content-Type: text/plain
-+Content-Length: 3
-+
-+Hi!"
-+);
-+
-+$m2 = new HttpMessage("
-+GET http://example.com/ HTTP/1.0
-+HTTP/1.1 200 ok
-+Server: Funky/2.0
-+Content-Type: text/html
-+Content-Length: 9
-+
-+Hi there!"
-+);
-+
-+$m1->prepend($m2);
-+$m2 = NULL;
-+echo $m1->toString(true);
-+
-+$m1->prepend($m1->detach(), false);
-+echo $m1->toString(true);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+GET http://example.com/ HTTP/1.0
-+HTTP/1.1 200 ok
-+Server: Funky/2.0
-+Content-Type: text/html
-+Content-Length: 9
-+
-+Hi there!
-+GET / HTTP/1.1
-+Host: example.com
-+Accept: */*
-+Connection: close
-+HTTP/1.1 200 ok
-+Server: Funky/1.0
-+Content-Type: text/plain
-+Content-Length: 3
-+
-+Hi!
-+GET http://example.com/ HTTP/1.0
-+HTTP/1.1 200 ok
-+Server: Funky/2.0
-+Content-Type: text/html
-+Content-Length: 9
-+
-+Hi there!
-+GET / HTTP/1.1
-+Host: example.com
-+Accept: */*
-+Connection: close
-+HTTP/1.1 200 ok
-+Server: Funky/1.0
-+Content-Type: text/plain
-+Content-Length: 3
-+
-+Hi!
-+HTTP/1.1 200 ok
-+Server: Funky/1.0
-+Content-Type: text/plain
-+Content-Length: 3
-+
-+Hi!
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_006.phpt
-@@ -0,0 +1,35 @@
-+--TEST--
-+HttpMessage iterator
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$m = new HttpMessage("
-+GET / HTTP/1.1
-+HTTP/1.1 200 OK
-+GET /foo HTTP/1.1
-+HTTP/1.1 304 Not Modified
-+");
-+
-+foreach ($m as $msg) {
-+ echo "==\n", $msg;
-+}
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+==
-+HTTP/1.1 304 Not Modified
-+==
-+GET /foo HTTP/1.1
-+==
-+HTTP/1.1 200 OK
-+==
-+GET / HTTP/1.1
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_007.phpt
-@@ -0,0 +1,46 @@
-+--TEST--
-+HttpMessage::reverse()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$s = "GET /first HTTP/1.1\nHTTP/1.1 200 Ok-first\nGET /second HTTP/1.1\nHTTP/1.1 200 Ok-second\nGET /third HTTP/1.1\nHTTP/1.1 200 Ok-third\n";
-+echo HttpMessage::fromString($s)->toString(true);
-+echo "===\n";
-+echo HttpMessage::fromString($s)->reverse()->toString(true);
-+
-+$m = new HttpMessage($s);
-+$r = $m->reverse();
-+unset($m);
-+var_dump($r->count());
-+echo $r->toString(true);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+GET /first HTTP/1.1
-+HTTP/1.1 200 Ok-first
-+GET /second HTTP/1.1
-+HTTP/1.1 200 Ok-second
-+GET /third HTTP/1.1
-+HTTP/1.1 200 Ok-third
-+===
-+HTTP/1.1 200 Ok-third
-+GET /third HTTP/1.1
-+HTTP/1.1 200 Ok-second
-+GET /second HTTP/1.1
-+HTTP/1.1 200 Ok-first
-+GET /first HTTP/1.1
-+int(6)
-+HTTP/1.1 200 Ok-third
-+GET /third HTTP/1.1
-+HTTP/1.1 200 Ok-second
-+GET /second HTTP/1.1
-+HTTP/1.1 200 Ok-first
-+GET /first HTTP/1.1
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_008.phpt
-@@ -0,0 +1,41 @@
-+--TEST--
-+HttpMessage::toMessageTypeObject()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$b = HttpRequest::encodeBody(array("a"=>"b",1=>2),null);
-+
-+$m = new HttpMessage;
-+$m->setType(HttpMessage::TYPE_REQUEST);
-+$m->setRequestMethod('POST');
-+$m->setRequestUrl("http://www.example.com");
-+$m->setHttpVersion('1.1');
-+$m->addHeaders(
-+ array(
-+ "Content-Type" => "application/x-www-form-urlencoded",
-+ "Host" => "www.example.com",
-+ "Content-Length"=> strlen($b),
-+ )
-+);
-+$m->setBody($b);
-+$r = $m->toMessageTypeObject();
-+echo $m,"\n";
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+POST http://www.example.com HTTP/1.1
-+Content-Type: application/x-www-form-urlencoded
-+Host: www.example.com
-+Content-Length: 7
-+
-+a=b&1=2
-+
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpMessage_009_bug16700.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+Bug #16700 - child classes of HttpMessage cannot not have array properties
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+class ChildMessage extends HttpMessage {
-+ public $properties = array();
-+}
-+
-+$child = new ChildMessage;
-+$child->properties['foo'] = 'bar';
-+echo $child->properties['foo'], "\n";
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bar
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpQueryString_001.phpt
-@@ -0,0 +1,116 @@
-+--TEST--
-+HttpQueryString global
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$_GET = array('a'=>'b','c'=>'3.4','r'=>array(1,2,3));
-+$_SERVER['QUERY_STRING'] = 'a=b&c=3.4&r[0]=1&r[1]=2&r[2]=3';
-+
-+var_dump(HttpQueryString::singleton()->get());
-+var_dump(HttpQueryString::singleton()->get('n'));
-+var_dump(HttpQueryString::singleton()->get('a'));
-+var_dump(HttpQueryString::singleton()->get('a', "i", 0, true));
-+var_dump(HttpQueryString::singleton()->get('a', "string", 'hi!'));
-+var_dump(HttpQueryString::singleton()->get('c'));
-+var_dump(HttpQueryString::singleton()->get('c', HttpQueryString::TYPE_INT));
-+var_dump(HttpQueryString::singleton()->get('c', HttpQueryString::TYPE_FLOAT));
-+var_dump(HttpQueryString::singleton()->get('c', HttpQueryString::TYPE_BOOL));
-+var_dump(HttpQueryString::singleton()->get('r'));
-+var_dump(HttpQueryString::singleton()->get('r', HttpQueryString::TYPE_ARRAY));
-+var_dump(HttpQueryString::singleton()->get('r', HttpQueryString::TYPE_OBJECT));
-+
-+HttpQueryString::singleton()->set(new HttpQueryString(false, 'z[0]=2'));
-+
-+HttpQueryString::singleton()->set(array('a'=>'b', 'c'=> "3.4"));
-+HttpQueryString::singleton()->set(array('a' => NULL));
-+
-+var_dump(HttpQueryString::singleton());
-+var_dump($_GET);
-+var_dump($_SERVER['QUERY_STRING']);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(42) "a=b&c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3"
-+NULL
-+string(1) "b"
-+int(0)
-+string(3) "hi!"
-+string(3) "3.4"
-+int(3)
-+float(3.4)
-+bool(true)
-+array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+object(stdClass)#%d (%d) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+object(HttpQueryString)#1 (2) {
-+ ["queryArray%s]=>
-+ &array(3) {
-+ ["c"]=>
-+ string(3) "3.4"
-+ ["r"]=>
-+ array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ }
-+ ["z"]=>
-+ array(1) {
-+ [0]=>
-+ string(1) "2"
-+ }
-+ }
-+ ["queryString%s]=>
-+ &string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
-+}
-+array(3) {
-+ ["c"]=>
-+ string(3) "3.4"
-+ ["r"]=>
-+ array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ }
-+ ["z"]=>
-+ array(1) {
-+ [0]=>
-+ string(1) "2"
-+ }
-+}
-+string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/HttpQueryString_002.phpt
-@@ -0,0 +1,108 @@
-+--TEST--
-+HttpQueryString local
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$q = new HttpQueryString(false, $array = array('a'=>'b','c'=>'3.4','r'=>array(1,2,3)));
-+var_dump($q->get());
-+var_dump($q->get('n'));
-+var_dump($q->get('a'));
-+var_dump($q->get('a', "i", 0, true));
-+var_dump($q->get('a', "string", 'hi!'));
-+var_dump($q->get('c'));
-+var_dump($q->get('c', HttpQueryString::TYPE_INT));
-+var_dump($q->get('c', HttpQueryString::TYPE_FLOAT));
-+var_dump($q->get('c', HttpQueryString::TYPE_BOOL));
-+var_dump($q->get('r'));
-+var_dump($q->get('r', HttpQueryString::TYPE_ARRAY));
-+var_dump($q->get('r', HttpQueryString::TYPE_OBJECT));
-+
-+$q->set('z[0]=2');
-+$q->set(array('a'=>'b', 'c'=> "3.4"));
-+$q->set(array('a' => NULL));
-+
-+var_dump($q);
-+var_dump($array);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(42) "a=b&c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3"
-+NULL
-+string(1) "b"
-+int(0)
-+string(3) "hi!"
-+string(3) "3.4"
-+int(3)
-+float(3.4)
-+bool(true)
-+array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+object(stdClass)#%d (%d) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+}
-+object(HttpQueryString)#1 (2) {
-+ ["queryArray%s]=>
-+ array(3) {
-+ ["c"]=>
-+ string(3) "3.4"
-+ ["r"]=>
-+ array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ }
-+ ["z"]=>
-+ array(1) {
-+ [0]=>
-+ string(1) "2"
-+ }
-+ }
-+ ["queryString%s]=>
-+ string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
-+}
-+array(3) {
-+ ["a"]=>
-+ string(1) "b"
-+ ["c"]=>
-+ string(3) "3.4"
-+ ["r"]=>
-+ array(3) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ int(2)
-+ [2]=>
-+ int(3)
-+ }
-+}
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/HttpQueryString_003.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+HttpQueryString xlate
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkext('iconv');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$qs = new HttpQueryString(false, "ä[0]=ü&ö[a]=ß");
-+var_dump($qs->get());
-+$qs->xlate("latin1", "utf8");
-+var_dump($qs->get());
-+$qs->xlate("utf8", "latin1");
-+var_dump($qs->get());
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+string(29) "%E4%5B0%5D=%FC&%F6%5Ba%5D=%DF"
-+string(41) "%C3%A4%5B0%5D=%C3%BC&%C3%B6%5Ba%5D=%C3%9F"
-+string(29) "%E4%5B0%5D=%FC&%F6%5Ba%5D=%DF"
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpQueryString_004.phpt
-@@ -0,0 +1,54 @@
-+--TEST--
-+HttpQueryString w/ objects
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+class test_props {
-+ public $bar;
-+ public $baz;
-+ protected $dont_show;
-+ private $dont_show2;
-+ function __construct() {
-+ $this->bar = (object) array("baz"=>1);
-+ $this->dont_show = 'xxx';
-+ $this->dont_show2 = 'zzz';
-+ }
-+}
-+$foo = new test_props;
-+var_dump($q = new HttpQueryString(false, $foo));
-+$foo->bar->baz = 0;
-+var_dump($q->mod($foo));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(HttpQueryString)#3 (2) {
-+ ["queryArray%s]=>
-+ array(1) {
-+ ["bar"]=>
-+ array(1) {
-+ ["baz"]=>
-+ int(1)
-+ }
-+ }
-+ ["queryString%s]=>
-+ string(14) "bar%5Bbaz%5D=1"
-+}
-+object(HttpQueryString)#4 (2) {
-+ ["queryArray%s]=>
-+ array(1) {
-+ ["bar"]=>
-+ array(1) {
-+ ["baz"]=>
-+ int(0)
-+ }
-+ }
-+ ["queryString%s]=>
-+ string(14) "bar%5Bbaz%5D=0"
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestDataShare_001.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+HttpRequestDataShare
-+--SKIPIF--
-+<?php
-+include "skip.inc";
-+checkurl("www.google.com");
-+checkcls("HttpRequestDataShare");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$s = new HttpRequestDataShare;
-+$s->dns = true;
-+$s->cookie = true;
-+
-+$r1 = new HttpRequest("http://www.google.com/");
-+$r2 = new HttpRequest("http://www.google.com/");
-+
-+$r1->enableCookies();
-+$r2->enableCookies();
-+
-+$s->attach($r1);
-+$s->attach($r2);
-+
-+$r1->send();
-+$r2->send();
-+
-+$s->reset();
-+
-+var_dump(current($r1->getResponseCookies())->cookies["PREF"] === HttpUtil::parseCookie($r2->getRequestMessage()->getHeader("Cookie"))->cookies["PREF"]);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestDataShare_002.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+HttpRequestDataShare global
-+--SKIPIF--
-+<?php
-+include "skip.inc";
-+checkurl("www.google.com");
-+checkcls("HttpRequestDataShare");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$s = HttpRequestDataShare::singleton(true);
-+$s->cookie = true;
-+var_dump($s);
-+
-+$r1 = new HttpRequest("http://www.google.com/");
-+$r2 = new HttpRequest("http://www.google.com/");
-+
-+$r1->enableCookies();
-+$r2->enableCookies();
-+
-+$s->attach($r1);
-+$s->attach($r2);
-+
-+$r1->send();
-+$r2->send();
-+
-+$s->reset();
-+
-+if (current($r1->getResponseCookies())->cookies["PREF"] !== HttpUtil::parseCookie($r2->getRequestMessage()->getHeader("Cookie"))->cookies["PREF"]) {
-+ var_dump(
-+ current($r1->getResponseCookies())->cookies["PREF"],
-+ HttpUtil::parseCookie($r2->getRequestMessage()->getHeader("Cookie"))->cookies["PREF"]
-+ );
-+}
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(HttpRequestDataShare)#1 (4) {
-+ ["cookie"]=>
-+ bool(true)
-+ ["dns"]=>
-+ bool(true)
-+ ["ssl"]=>
-+ bool(false)
-+ ["connect"]=>
-+ bool(false)
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_001.phpt
-@@ -0,0 +1,51 @@
-+--TEST--
-+HttpRequestPool
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequestPool');
-+checkurl('www.php.net');
-+checkurl('dev.iworks.at');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$post = new HttpRequest('http://dev.iworks.at/ext-http/.print_request.php', HTTP_METH_POST);
-+$post->addPostFields(array('a'=>1,'b'=>2)) ;
-+
-+$pool = new HttpRequestPool(
-+ new HttpRequest('http://www.php.net/', HTTP_METH_HEAD),
-+ $post
-+);
-+
-+$pool->send();
-+
-+foreach ($pool as $req) {
-+ echo $req->getUrl(), '=',
-+ $req->getResponseCode(), ':',
-+ $req->getResponseMessage()->getResponseCode(), "\n";
-+}
-+
-+foreach ($pool as $req) {
-+ try {
-+ $pool->attach(new HttpRequest('http://foo.bar'));
-+ } catch (HttpRequestPoolException $x) {
-+ echo ".\n";
-+ }
-+}
-+
-+foreach ($pool as $req) {
-+ $pool->detach($req);
-+}
-+
-+echo "Done\n";
-+?>
-+
-+--EXPECTF--
-+%aTEST
-+http://www.php.net/=200:200
-+http://dev.iworks.at/ext-http/.print_request.php=200:200
-+.
-+.
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_002.phpt
-@@ -0,0 +1,51 @@
-+--TEST--
-+extending HttpRequestPool
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequestPool');
-+checkurl('www.php.net');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+class MyPool extends HttpRequestPool
-+{
-+ public function send()
-+ {
-+ while ($this->socketPerform()) {
-+ if (!$this->socketSelect()) {
-+ throw new HttpSocketException;
-+ }
-+ }
-+ }
-+
-+ protected final function socketPerform()
-+ {
-+ $result = parent::socketPerform();
-+
-+ echo ".";
-+ foreach ($this->getFinishedRequests() as $r) {
-+ echo "=", $r->getResponseCode(), "=";
-+ $this->detach($r);
-+ }
-+
-+ return $result;
-+ }
-+}
-+
-+$pool = new MyPool(
-+ new HttpRequest('http://www.php.net/', HTTP_METH_HEAD),
-+ new HttpRequest('http://www.php.net/', HTTP_METH_HEAD),
-+ new HttpRequest('http://www.php.net/', HTTP_METH_HEAD)
-+);
-+
-+$pool->send();
-+
-+echo "\nDone\n";
-+?>
-+--EXPECTREGEX--
-+.+TEST
-+\.*=200=\.*=200=\.*=200=
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_003.phpt
-@@ -0,0 +1,175 @@
-+--TEST--
-+HttpRequestPool chain
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+checkcls('HttpRequestPool');
-+?>
-+--FILE--
-+<?php
-+
-+echo "-TEST\n";
-+
-+set_time_limit(0);
-+ini_set('error_reporting', E_ALL);
-+ini_set('html_errors', 0);
-+
-+class Pool extends HttpRequestPool
-+{
-+ private $all;
-+ private $rem;
-+ private $dir;
-+
-+ public final function __construct($urls_file = 'urls.txt', $cache_dir = 'HttpRequestPool_cache')
-+ {
-+ $this->dir = (is_dir($cache_dir) or @mkdir($cache_dir)) ? $cache_dir : null;
-+
-+ foreach (array_map('trim', file($urls_file)) as $url) {
-+ $this->all[$url] = $this->dir ? $this->dir .'/'. md5($url) : null;
-+ }
-+
-+ $this->send();
-+ }
-+
-+ public final function send()
-+ {
-+ if (RMAX) {
-+ $now = array_slice($this->all, 0, RMAX);
-+ $this->rem = array_slice($this->all, RMAX);
-+ } else {
-+ $now = $urls;
-+ $this->rem = array();
-+ }
-+
-+ foreach ($now as $url => $file) {
-+ $this->attach(
-+ new HttpRequest(
-+ $url,
-+ HttpRequest::METH_GET,
-+ array(
-+ 'redirect' => 5,
-+ 'compress' => GZIP,
-+ 'timeout' => TOUT,
-+ 'connecttimeout' => TOUT,
-+ 'lastmodified' => is_file($file)?filemtime($file):0
-+ )
-+ )
-+ );
-+ }
-+
-+ while ($this->socketPerform()) {
-+ if (!$this->socketSelect()) {
-+ throw new HttpSocketException;
-+ }
-+ }
-+ }
-+
-+ protected final function socketPerform()
-+ {
-+ try {
-+ $rc = parent::socketPerform();
-+ } catch (HttpRequestException $x) {
-+ // a request may have thrown an exception,
-+ // but it is still save to continue
-+ echo $x->getMessage(), "\n";
-+ }
-+
-+ foreach ($this->getFinishedRequests() as $r) {
-+ $this->detach($r);
-+
-+ $u = $r->getUrl();
-+ $c = $r->getResponseCode();
-+ $b = $r->getResponseBody();
-+
-+ printf("%d %s %d\n", $c, $u, strlen($b));
-+
-+ if ($c == 200 && $this->dir) {
-+ file_put_contents($this->all[$u], $b);
-+ }
-+
-+ if ($a = each($this->rem)) {
-+ list($url, $file) = $a;
-+ $this->attach(
-+ new HttpRequest(
-+ $url,
-+ HttpRequest::METH_GET,
-+ array(
-+ 'redirect' => 5,
-+ 'compress' => GZIP,
-+ 'timeout' => TOUT,
-+ 'connecttimeout' => TOUT,
-+ 'lastmodified' => is_file($file)?filemtime($file):0
-+ )
-+ )
-+ );
-+ }
-+ }
-+ return $rc;
-+ }
-+}
-+
-+define('GZIP', true);
-+define('TOUT', 50);
-+define('RMAX', 10);
-+chdir(dirname(__FILE__));
-+
-+$time = microtime(true);
-+$pool = new Pool();
-+printf("Elapsed: %0.3fs\n", microtime(true)-$time);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+%d %s %d
-+Elapsed: %fs
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_004.phpt
-@@ -0,0 +1,19 @@
-+--TEST--
-+HttpRequestPool::__destruct() invalid curl handle
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequest');
-+checkcls('HttpRequestPool');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$p = new HttpRequestPool(new HttpRequest('http://example.com'));
-+$p = null;
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_005.phpt
-@@ -0,0 +1,46 @@
-+--TEST--
-+HttpRequestPool exception
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequestPool');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$p = new HttpRequestPool(new HttpRequest('http://_____'));
-+try {
-+ $p->send();
-+} catch (HttpRequestPoolException $x) {
-+ for ($i=0; $x; ++$i, $x = @$x->innerException) {
-+ printf("%s%s: %s\n", str_repeat("\t", $i), get_class($x), $x->getMessage());
-+ }
-+ var_dump($i);
-+}
-+$p = new HttpRequestPool(new HttpRequest('http://_____'), new HttpRequest('http://_____'));
-+try {
-+ $p->send();
-+} catch (HttpRequestPoolException $x) {
-+ for ($i=0; $x; ++$i, $x = @$x->innerException) {
-+ printf("%s%s: %s\n", str_repeat("\t", $i), get_class($x), $x->getMessage());
-+ }
-+ var_dump($i);
-+}
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+HttpRequestPoolException: Exception caused by 2 inner exception(s)
-+ HttpInvalidParamException: Empty or too short HTTP message: ''
-+ HttpRequestException: %souldn't resolve host name; %s (http://_____/)
-+int(3)
-+HttpRequestPoolException: Exception caused by 4 inner exception(s)
-+ HttpInvalidParamException: Empty or too short HTTP message: ''
-+ HttpRequestException: %souldn't resolve host name; %s (http://_____/)
-+ HttpInvalidParamException: Empty or too short HTTP message: ''
-+ HttpRequestException: %souldn't resolve host name; %s (http://_____/)
-+int(5)
-+Done
-+
---- /dev/null
-+++ b/ext/http/tests/HttpRequestPool_006.phpt
-@@ -0,0 +1,50 @@
-+--TEST--
-+HttpRequestPool detaching in callbacks
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls("HttpRequestPool");
-+checkurl("at.php.net");
-+checkurl("de.php.net");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+class r extends HttpRequest {
-+ function onProgress() {
-+ static $i = array();
-+ if (empty($i[$this->getUrl()])) {
-+ $i[$this->getUrl()] = true;
-+ try {
-+ $GLOBALS['p']->detach($this);
-+ } catch (Exception $ex) {
-+ echo $ex, "\n";
-+ }
-+ }
-+ }
-+ function onFinish() {
-+ $GLOBALS['p']->detach($this);
-+ }
-+}
-+$p = new HttpRequestPool(new r("http://at.php.net"), new r("http://de.php.net"));
-+$p->send();
-+var_dump($p->getAttachedRequests());
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+exception 'HttpRequestPoolException' with message 'HttpRequest object(#%d) cannot be detached from the HttpRequestPool while executing the progress callback' in %aHttpRequestPool_006.php:%d
-+Stack trace:
-+#0 %aHttpRequestPool_006.php(%d): HttpRequestPool->detach(Object(r))
-+#1 [internal function]: r->onProgress(Array)
-+#2 %aHttpRequestPool_006.php(%d): HttpRequestPool->send()
-+#3 {main}
-+exception 'HttpRequestPoolException' with message 'HttpRequest object(#%d) cannot be detached from the HttpRequestPool while executing the progress callback' in %aHttpRequestPool_006.php:%d
-+Stack trace:
-+#0 %aHttpRequestPool_006.php(%d): HttpRequestPool->detach(Object(r))
-+#1 [internal function]: r->onProgress(Array)
-+#2 %aHttpRequestPool_006.php(%d): HttpRequestPool->send()
-+#3 {main}
-+array(0) {
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_001.phpt
-@@ -0,0 +1,51 @@
-+--TEST--
-+HttpRequest options
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$r1 = new HttpRequest(null, 0, array('redirect'=>11, 'headers'=>array('X-Foo'=>'Bar')));
-+$r2 = new HttpRequest;
-+$r2->setOptions(array('redirect'=>99, 'headers'=>array('X-Bar'=>'Foo')));
-+$o1 = $r1->getOptions();
-+$o2 = $r2->getOptions();
-+$r1->setOptions($o2);
-+$r2->setOptions($o1);
-+print_r(array($o1, $o2));
-+var_dump(serialize($r1->getOptions()) === serialize($r2->getOptions()));
-+$r1 = null;
-+$r2 = null;
-+?>
-+--EXPECTF--
-+%aTEST
-+Array
-+(
-+ [0] => Array
-+ (
-+ [headers] => Array
-+ (
-+ [X-Foo] => Bar
-+ [X-Bar] => Foo
-+ )
-+
-+ [redirect] => 11
-+ )
-+
-+ [1] => Array
-+ (
-+ [headers] => Array
-+ (
-+ [X-Bar] => Foo
-+ [X-Foo] => Bar
-+ )
-+
-+ [redirect] => 99
-+ )
-+
-+)
-+bool(false)
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_002.phpt
-@@ -0,0 +1,86 @@
-+--TEST--
-+HttpRequest GET/POST
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequest');
-+checkurl('www.google.com');
-+checkurl('dev.iworks.at');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest('http://www.google.com', HttpRequest::METH_GET);
-+$r->send();
-+print_r($r->getResponseInfo());
-+
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_request.php', HTTP_METH_POST);
-+$r->addCookies(array('MyCookie' => 'foobar'));
-+$r->addQueryData(array('gq'=>'foobar','gi'=>10));
-+$r->addPostFields(array('pq'=>'foobar','pi'=>10));
-+$r->addPostFile('upload', dirname(__FILE__).'/data.txt', 'text/plain');
-+$r->send();
-+echo $r->getResponseBody();
-+var_dump($r->getResponseMessage()->getResponseCode());
-+
-+echo "Done";
-+?>
-+--EXPECTF--
-+%aTEST
-+Array
-+(
-+ [effective_url] => http://www.google.com/
-+ [response_code] => 302
-+ [total_time] => %f
-+ [namelookup_time] => %f
-+ [connect_time] => %f
-+ [pretransfer_time] => %f
-+ [size_upload] => %d
-+ [size_download] => %d
-+ [speed_download] => %d
-+ [speed_upload] => %d
-+ [header_size] => %d
-+ [request_size] => %d
-+ [ssl_verifyresult] => %d
-+ [filetime] => -1
-+ [content_length_download] => %d
-+ [content_length_upload] => %d
-+ [starttransfer_time] => %f
-+ [content_type] => %s
-+ [redirect_time] => %d
-+ [redirect_count] => %d
-+ [connect_code] => %d
-+ [httpauth_avail] => %d
-+ [proxyauth_avail] => %d
-+ [os_errno] => %d
-+ [num_connects] => %d
-+ [ssl_engines] => Array
-+ %a
-+ [cookies] => Array
-+ %a
-+ [error] =>
-+)
-+Array
-+(
-+ [gq] => foobar
-+ [gi] => 10
-+ [pq] => foobar
-+ [pi] => 10
-+ [MyCookie] => foobar
-+)
-+Array
-+(
-+ [upload] => Array
-+ (
-+ [name] => data.txt
-+ [type] => text/plain
-+ [tmp_name] => %a
-+ [error] => 0
-+ [size] => 1010
-+ )
-+
-+)
-+int(200)
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_003.phpt
-@@ -0,0 +1,54 @@
-+--TEST--
-+HttpRequest SSL
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkurl('arweb.info');
-+skipif(!http_support(HTTP_SUPPORT_SSLREQUESTS), 'need ssl-request support')
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$o = array('redirect' => '3', 'ssl' => array('version' => '3', 'verifyhost' => '1'));
-+$r = new HttpRequest('https://ssl.irmler.at/iworks/data.txt');
-+$r->setOptions($o);
-+$r->send();
-+var_dump($r->getResponseBody());
-+var_dump(is_object($r->getResponseMessage()));
-+var_dump(is_object($r->getResponseMessage()));
-+var_dump(is_object($r->getResponseMessage()));
-+var_dump($o);
-+$r->setOptions($o);
-+$r->send();
-+var_dump($o);
-+?>
-+--EXPECTF--
-+%aTEST
-+string(10) "1234567890"
-+bool(true)
-+bool(true)
-+bool(true)
-+array(2) {
-+ ["redirect"]=>
-+ string(1) "3"
-+ ["ssl"]=>
-+ array(2) {
-+ ["version"]=>
-+ string(1) "3"
-+ ["verifyhost"]=>
-+ string(1) "1"
-+ }
-+}
-+array(2) {
-+ ["redirect"]=>
-+ string(1) "3"
-+ ["ssl"]=>
-+ array(2) {
-+ ["version"]=>
-+ string(1) "3"
-+ ["verifyhost"]=>
-+ string(1) "1"
-+ }
-+}
-+
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_004.phpt
-@@ -0,0 +1,162 @@
-+--TEST--
-+HttpRequest multiple posts
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$fields = array(
-+ array('int' => 1, 'dbl' => M_PI),
-+ array('str' => 'something', 'nil' => null)
-+);
-+
-+echo "\nFirst Request\n";
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_request.php', HttpRequest::METH_POST);
-+$r->setPostFields($fields[0]);
-+$r->addPostFields($fields[1]);
-+var_dump($r->send()->getBody());
-+var_dump($fields);
-+
-+echo "\nSecond Request\n";
-+$r->setPostFields($fields);
-+var_dump($r->send()->getBody());
-+var_dump($fields);
-+
-+echo "\nThird Request\n";
-+$r->addPostFields(array('x' => 'X'));
-+var_dump($r->send()->getBody());
-+var_dump($fields);
-+
-+echo "\nFourth Request\n";
-+$r->setPostFields(array());
-+var_dump($r->send()->getBody());
-+var_dump($fields);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+
-+First Request
-+string(%d) "Array
-+(
-+ [int] => 1
-+ [dbl] => 3.1415926535898
-+ [str] => something
-+ [nil] =>
-+)
-+string(44) "int=1&dbl=3.1415926535898&str=something&nil="
-+"
-+array(2) {
-+ [0]=>
-+ array(2) {
-+ ["int"]=>
-+ int(1)
-+ ["dbl"]=>
-+ float(3.1415926535898)
-+ }
-+ [1]=>
-+ array(2) {
-+ ["str"]=>
-+ string(9) "something"
-+ ["nil"]=>
-+ NULL
-+ }
-+}
-+
-+Second Request
-+string(%d) "Array
-+(
-+ [0] => Array
-+ (
-+ [int] => 1
-+ [dbl] => 3.1415926535898
-+ )
-+
-+ [1] => Array
-+ (
-+ [str] => something
-+ [nil] =>
-+ )
-+
-+)
-+string(72) "0%5Bint%5D=1&0%5Bdbl%5D=3.1415926535898&1%5Bstr%5D=something&1%5Bnil%5D="
-+"
-+array(2) {
-+ [0]=>
-+ array(2) {
-+ ["int"]=>
-+ int(1)
-+ ["dbl"]=>
-+ float(3.1415926535898)
-+ }
-+ [1]=>
-+ array(2) {
-+ ["str"]=>
-+ string(9) "something"
-+ ["nil"]=>
-+ NULL
-+ }
-+}
-+
-+Third Request
-+string(%d) "Array
-+(
-+ [0] => Array
-+ (
-+ [int] => 1
-+ [dbl] => 3.1415926535898
-+ )
-+
-+ [1] => Array
-+ (
-+ [str] => something
-+ [nil] =>
-+ )
-+
-+ [x] => X
-+)
-+string(76) "0%5Bint%5D=1&0%5Bdbl%5D=3.1415926535898&1%5Bstr%5D=something&1%5Bnil%5D=&x=X"
-+"
-+array(2) {
-+ [0]=>
-+ array(2) {
-+ ["int"]=>
-+ int(1)
-+ ["dbl"]=>
-+ float(3.1415926535898)
-+ }
-+ [1]=>
-+ array(2) {
-+ ["str"]=>
-+ string(9) "something"
-+ ["nil"]=>
-+ NULL
-+ }
-+}
-+
-+Fourth Request
-+string(13) "string(0) ""
-+"
-+array(2) {
-+ [0]=>
-+ array(2) {
-+ ["int"]=>
-+ int(1)
-+ ["dbl"]=>
-+ float(3.1415926535898)
-+ }
-+ [1]=>
-+ array(2) {
-+ ["str"]=>
-+ string(9) "something"
-+ ["nil"]=>
-+ NULL
-+ }
-+}
-+Done
-+
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_005.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+HttpRequest accessors
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+error_reporting(0);
-+$r = new HttpRequest;
-+foreach (get_class_methods('HttpRequest') as $method) {
-+ try {
-+ if (strlen($method) > 3 && substr($method, 0, 3) == 'get')
-+ $x = $r->$method();
-+ } catch (HttpException $e) {
-+ }
-+}
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_006.phpt
-@@ -0,0 +1,147 @@
-+--TEST--
-+HttpRequest XMLRPC
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkext('xmlrpc');
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_request.php', HTTP_METH_POST);
-+$r->setContentType('text/xml');
-+$r->setBody(xmlrpc_encode_request('testMethod', array('foo' => 'bar')));
-+var_dump($r->send());
-+var_dump($r->send());
-+var_dump($r->send());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(HttpMessage)#%d (%d) {
-+ ["type:protected"]=>
-+ int(2)
-+ ["body:protected"]=>
-+ string(309) "string(294) "<?xml version="1.0" encoding="iso-8859-1%s]>
-+<methodCall>
-+<methodName>testMethod</methodName>
-+<params>
-+ <param>
-+ <value>
-+ <struct>
-+ <member>
-+ <name>foo</name>
-+ <value>
-+ <string>bar</string>
-+ </value>
-+ </member>
-+ </struct>
-+ </value>
-+ </param>
-+</params>
-+</methodCall>
-+"
-+"
-+ ["requestMethod:protected"]=>
-+ string(0) ""
-+ ["requestUrl:protected"]=>
-+ string(0) ""
-+ ["responseStatus:protected"]=>
-+ string(2) "OK"
-+ ["responseCode:protected"]=>
-+ int(200)
-+ ["httpVersion:protected"]=>
-+ float(1.1)
-+ ["headers:protected"]=>
-+ array(6) {
-+ %a
-+ }
-+ ["parentMessage:protected"]=>
-+ NULL
-+}
-+object(HttpMessage)#%d (%d) {
-+ ["type:protected"]=>
-+ int(2)
-+ ["body:protected"]=>
-+ string(309) "string(294) "<?xml version="1.0" encoding="iso-8859-1%s]>
-+<methodCall>
-+<methodName>testMethod</methodName>
-+<params>
-+ <param>
-+ <value>
-+ <struct>
-+ <member>
-+ <name>foo</name>
-+ <value>
-+ <string>bar</string>
-+ </value>
-+ </member>
-+ </struct>
-+ </value>
-+ </param>
-+</params>
-+</methodCall>
-+"
-+"
-+ ["requestMethod:protected"]=>
-+ string(0) ""
-+ ["requestUrl:protected"]=>
-+ string(0) ""
-+ ["responseStatus:protected"]=>
-+ string(2) "OK"
-+ ["responseCode:protected"]=>
-+ int(200)
-+ ["httpVersion:protected"]=>
-+ float(1.1)
-+ ["headers:protected"]=>
-+ array(6) {
-+ %a
-+ }
-+ ["parentMessage:protected"]=>
-+ NULL
-+}
-+object(HttpMessage)#%d (%d) {
-+ ["type:protected"]=>
-+ int(2)
-+ ["body:protected"]=>
-+ string(309) "string(294) "<?xml version="1.0" encoding="iso-8859-1%s]>
-+<methodCall>
-+<methodName>testMethod</methodName>
-+<params>
-+ <param>
-+ <value>
-+ <struct>
-+ <member>
-+ <name>foo</name>
-+ <value>
-+ <string>bar</string>
-+ </value>
-+ </member>
-+ </struct>
-+ </value>
-+ </param>
-+</params>
-+</methodCall>
-+"
-+"
-+ ["requestMethod:protected"]=>
-+ string(0) ""
-+ ["requestUrl:protected"]=>
-+ string(0) ""
-+ ["responseStatus:protected"]=>
-+ string(2) "OK"
-+ ["responseCode:protected"]=>
-+ int(200)
-+ ["httpVersion:protected"]=>
-+ float(1.1)
-+ ["headers:protected"]=>
-+ array(6) {
-+ %a
-+ }
-+ ["parentMessage:protected"]=>
-+ NULL
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_007.phpt
-@@ -0,0 +1,63 @@
-+--TEST--
-+HttpRequest PUT
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_put.php5', HTTP_METH_PUT);
-+$r->recordHistory = true;
-+$r->addHeaders(array('content-type' => 'text/plain'));
-+$r->setPutFile(__FILE__);
-+$r->send();
-+var_dump($r->getHistory()->toString(true));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(%d) "PUT /ext-http/.print_put.php5 HTTP/1.1
-+User-Agent: PECL::HTTP/%a
-+Host: dev.iworks.at
-+Accept: */*
-+Content-Type: text/plain
-+Content-Length: %d
-+Expect: 100-continue
-+
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_put.php5', HTTP_METH_PUT);
-+$r->recordHistory = true;
-+$r->addHeaders(array('content-type' => 'text/plain'));
-+$r->setPutFile(__FILE__);
-+$r->send();
-+var_dump($r->getHistory()->toString(true));
-+echo "Done\n";
-+?>
-+
-+HTTP/1.1 100 Continue
-+HTTP/1.1 200 OK
-+Date: %a
-+Server: %a
-+Vary: Accept-Encoding
-+Content-Length: %d
-+Content-Type: text/html
-+
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_put.php5', HTTP_METH_PUT);
-+$r->recordHistory = true;
-+$r->addHeaders(array('content-type' => 'text/plain'));
-+$r->setPutFile(__FILE__);
-+$r->send();
-+var_dump($r->getHistory()->toString(true));
-+echo "Done\n";
-+?>
-+
-+"
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_008.phpt
-@@ -0,0 +1,32 @@
-+--TEST--
-+HttpRequest custom request method
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+HttpRequest::methodRegister('foobar');
-+$r = new HttpRequest('http://dev.iworks.at/ext-http/.print_request.php', HttpRequest::METH_FOOBAR);
-+$r->setContentType('text/plain');
-+$r->setBody('Yep, this is FOOBAR!');
-+var_dump($r->send()->getResponseCode());
-+var_dump($r->getRawRequestMessage());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+int(200)
-+string(%d) "FOOBAR /ext-http/.print_request.php HTTP/1.1
-+User-Agent: %a
-+Host: dev.iworks.at
-+Accept: */*
-+Content-Type: text/plain
-+Content-Length: 20
-+
-+Yep, this is FOOBAR!"
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_009.phpt
-@@ -0,0 +1,48 @@
-+--TEST--
-+HttpRequest callbacks
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+class _R extends HttpRequest
-+{
-+ function onProgress($progress)
-+ {
-+ print_r($progress);
-+ }
-+
-+ function onFinish()
-+ {
-+ var_dump($this->getResponseCode());
-+ }
-+}
-+
-+$r = new _R('http://dev.iworks.at/ext-http/.print_request.php', HTTP_METH_POST);
-+$r->addPostFile('upload', __FILE__, 'text/plain');
-+$r->send();
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Array
-+(
-+ [dltotal] => %f
-+ [dlnow] => %f
-+ [ultotal] => %f
-+ [ulnow] => %f
-+)
-+%array
-+(
-+ [dltotal] => %f
-+ [dlnow] => %f
-+ [ultotal] => %f
-+ [ulnow] => %f
-+)
-+int(200)
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpRequest_010.phpt
-@@ -0,0 +1,48 @@
-+--TEST--
-+HttpRequest cookie API
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls("HttpRequest");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$r = new HttpRequest("http://dev.iworks.at/ext-http/.cookie.php");
-+
-+$r->send();
-+$c[0] = $r->getResponseInfo("cookies");
-+if (!empty($c[0])) {
-+ var_dump('$c[0]', $c[0]);
-+}
-+
-+var_dump($r->enableCookies());
-+$r->send();
-+
-+$c[1] = $r->getResponseInfo("cookies");
-+if (empty($c[1])) {
-+ var_dump('$c[1]', $c[1]);
-+}
-+
-+var_dump($r->resetCookies());
-+$r->send();
-+
-+$c[2] = $r->getResponseInfo("cookies");
-+if ($c[1] === $c[2]) {
-+ var_dump('$c[1]', $c[1], '$c[2]', $c[2]);
-+}
-+
-+$r->send();
-+$c[3] = $r->getResponseInfo("cookies");
-+if ($c[2] !== $c[3]) {
-+ var_dump('$c[2]', $c[2], '$c[3]', $c[3]);
-+}
-+
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+bool(true)
-+Done
---- /dev/null
-+++ b/ext/http/tests/HttpResponse_001.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+HttpResponse - send data with caching headers
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcgi();
-+?>
-+--FILE--
-+<?php
-+HttpResponse::setCache(true);
-+HttpResponse::setCacheControl('public', 3600);
-+HttpResponse::setData('foobar');
-+HttpResponse::send();
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: public, must-revalidate, max-age=3600
-+Last-Modified: %a, %d %a 20%d %d:%d:%d GMT
-+Content-Type: %a
-+Accept-Ranges: bytes
-+ETag: "3858f62230ac3c915f300c664312c63f"
-+Content-Length: 6
-+
-+foobar
---- /dev/null
-+++ b/ext/http/tests/HttpResponse_002.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+HttpResponse - send gzipped file
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcgi();
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support");
-+?>
-+--ENV--
-+HTTP_ACCEPT_ENCODING=gzip
-+--FILE--
-+<?php
-+HttpResponse::setGzip(true);
-+HttpResponse::setFile(__FILE__);
-+HttpResponse::send();
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Content-Type: %a
-+Accept-Ranges: bytes
-+Content-Encoding: gzip
-+Vary: Accept-Encoding
-+
-+%a
---- /dev/null
-+++ b/ext/http/tests/HttpResponse_003.phpt
-@@ -0,0 +1,30 @@
-+--TEST--
-+HttpResponse - send gzipped file with caching headers
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcgi();
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support");
-+?>
-+--ENV--
-+HTTP_ACCEPT_ENCODING=gzip
-+--FILE--
-+<?php
-+HttpResponse::setGzip(true);
-+HttpResponse::setCache(true);
-+HttpResponse::setCacheControl('public', 3600);
-+HttpResponse::setFile(__FILE__);
-+HttpResponse::send();
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: public, must-revalidate, max-age=3600
-+Last-Modified: %a, %d %a 20%d %d:%d:%d GMT
-+Content-Type: %a
-+Accept-Ranges: bytes
-+ETag: "%a"
-+Content-Encoding: gzip
-+Vary: Accept-Encoding
-+
-+%a
---- /dev/null
-+++ b/ext/http/tests/HttpResponse_004.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+HttpResponse - send cached gzipped data
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.7");
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support");
-+?>
-+--ENV--
-+HTTP_IF_NONE_MATCH="900150983cd24fb0d6963f7d28e17f72"
-+HTTP_ACCEPT_ENCODING=gzip
-+--FILE--
-+<?php
-+HttpResponse::setGzip(true);
-+HttpResponse::setCache(true);
-+HttpResponse::setCacheControl('public', 3600);
-+HttpResponse::setData("abc");
-+HttpResponse::send();
-+?>
-+--EXPECTF--
-+Status: 304%s
-+X-Powered-By: PHP/%s
-+Cache-Control: public, must-revalidate, max-age=3600
-+Last-Modified: %s
-+Accept-Ranges: bytes
-+ETag: "900150983cd24fb0d6963f7d28e17f72"
---- /dev/null
-+++ b/ext/http/tests/HttpResponse_005.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+HttpResponse file not found
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set("error_reporting", 0);
-+ini_set("default_mimetype", "text/plain");
-+
-+HttpResponse::setContentType("application/pdf");
-+HttpResponse::setContentDisposition("doc.pdf");
-+HttpResponse::setFile("__nonexistant__.pdf");
-+HttpResponse::send();
-+?>
-+--EXPECTF--
-+Status: 404%s
-+X-Powered-By: PHP/%s
-+Content-Type: text/plain
-+
-+File not found
---- /dev/null
-+++ b/ext/http/tests/allowed_methods_002.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+allowed methods
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+include 'log.inc';
-+log_prepare(_AMETH_LOG);
-+ini_set('http.request.methods.allowed', 'POST');
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+Status: 405%s
-+X-Powered-By: PHP/%a
-+Allow: POST
-+Content-type: %a
-+
---- /dev/null
-+++ b/ext/http/tests/allowed_methods_002_logging.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+logging allowed methods
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=example.com
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+include 'log.inc';
-+log_content(_AMETH_LOG);
-+echo "Done";
-+?>
-+--EXPECTF--
-+%aTEST
-+%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d [405-ALLOWED] Allow: POST <%a>
-+Done
---- /dev/null
-+++ b/ext/http/tests/bug_15800.phpt
-@@ -0,0 +1,49 @@
-+--TEST--
-+Bug #15800 Double free when zval is separated in convert_to_*
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequest');
-+skipif(!function_exists('debug_zval_dump'), "need DEBUG version of PHP");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$o = array('ssl' => array('verifypeer'=>'1'));
-+debug_zval_dump($o);
-+
-+$r = new HttpRequest('http://www.google.com');
-+$r->setOptions($o);
-+$r->send();
-+debug_zval_dump($o);
-+
-+unset($r);
-+debug_zval_dump($o);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+array(1) refcount(2){
-+ ["ssl"]=>
-+ array(1) refcount(1){
-+ ["verifypeer"]=>
-+ string(1) "1" refcount(1)
-+ }
-+}
-+array(1) refcount(2){
-+ ["ssl"]=>
-+ array(1) refcount(1){
-+ ["verifypeer"]=>
-+ string(1) "1" refcount(3)
-+ }
-+}
-+array(1) refcount(2){
-+ ["ssl"]=>
-+ array(1) refcount(1){
-+ ["verifypeer"]=>
-+ string(1) "1" refcount(1)
-+ }
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/build_str_001.phpt
-@@ -0,0 +1,30 @@
-+--TEST--
-+http_build_str
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+parse_str("a=b", $q);
-+echo http_build_str($q, null, "&"), "\n";
-+
-+parse_str("a=b&c[0]=1", $q);
-+echo http_build_str($q, null, "&"), "\n";
-+
-+parse_str("a=b&c[0]=1&d[e]=f", $q);
-+echo http_build_str($q, null, "&"), "\n";
-+
-+echo http_build_str(array(1,2,array(3)), "foo", "&"), "\n";
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+a=b
-+a=b&c%5B0%5D=1
-+a=b&c%5B0%5D=1&d%5Be%5D=f
-+foo%5B0%5D=1&foo%5B1%5D=2&foo%5B2%5D%5B0%5D=3
-+Done
---- /dev/null
-+++ b/ext/http/tests/build_url_001.phpt
-@@ -0,0 +1,18 @@
-+--TEST--
-+http_build_url() with relative paths
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+echo http_build_url('page'), "\n";
-+echo http_build_url('with/some/path/'), "\n";
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+http://%a/page
-+http://%a/with/some/path/
-+Done
---- /dev/null
-+++ b/ext/http/tests/build_url_002.phpt
-@@ -0,0 +1,30 @@
-+--TEST--
-+http_build_url() with parse_url()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+echo http_build_url(parse_url("http://example.org/orig?q=1#f"),
-+ parse_url("https://www.example.com:9999/replaced#n")), "\n";
-+echo http_build_url(("http://example.org/orig?q=1#f"),
-+ ("https://www.example.com:9999/replaced#n"), 0, $u), "\n";
-+print_r($u);
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+https://www.example.com:9999/replaced?q=1#n
-+https://www.example.com:9999/replaced?q=1#n
-+Array
-+(
-+ [scheme] => https
-+ [host] => www.example.com
-+ [port] => 9999
-+ [path] => /replaced
-+ [query] => q=1
-+ [fragment] => n
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/build_url_003.phpt
-@@ -0,0 +1,26 @@
-+--TEST--
-+http_build_url()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=www.example.com
-+--FILE--
-+<?php
-+$url = '/path/?query#anchor';
-+echo "-TEST\n";
-+printf("-%s-\n", http_build_url($url));
-+printf("-%s-\n", http_build_url($url, array('scheme' => 'https')));
-+printf("-%s-\n", http_build_url($url, array('scheme' => 'https', 'host' => 'ssl.example.com')));
-+printf("-%s-\n", http_build_url($url, array('scheme' => 'ftp', 'host' => 'ftp.example.com', 'port' => 21)));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+-http://www.example.com/path/?query#anchor-
-+-https://www.example.com/path/?query#anchor-
-+-https://ssl.example.com/path/?query#anchor-
-+-ftp://ftp.example.com/path/?query#anchor-
-+Done
---- /dev/null
-+++ b/ext/http/tests/build_url_004.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+http_build_url flags
-+--SKPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+echo http_build_url("http://mike@www.example.com/foo/bar", "./baz", HTTP_URL_STRIP_AUTH|HTTP_URL_JOIN_PATH), "\n";
-+echo http_build_url("http://mike@www.example.com/foo/bar/", "../baz", HTTP_URL_STRIP_USER|HTTP_URL_JOIN_PATH), "\n";
-+echo http_build_url("http://mike:1234@www.example.com/foo/bar/", "./../baz", HTTP_URL_STRIP_PASS|HTTP_URL_JOIN_PATH), "\n";
-+echo http_build_url("http://www.example.com:8080/foo?a[0]=b#frag", "?a[0]=1&b=c&a[1]=b", HTTP_URL_JOIN_QUERY|HTTP_URL_STRIP_PORT|HTTP_URL_STRIP_FRAGMENT|HTTP_URL_STRIP_PATH), "\n";
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+http://www.example.com/foo/baz
-+http://www.example.com/foo/baz
-+http://mike@www.example.com/foo/baz
-+http://www.example.com/?a%5B0%5D=1&a%5B1%5D=b&b=c
-+Done
---- /dev/null
-+++ b/ext/http/tests/chunked_decode_001.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+http_chunked_decode() "\r\n"
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$data =
-+"02\r\n".
-+"ab\r\n".
-+"04\r\n".
-+"ra\nc\r\n".
-+"06\r\n".
-+"adabra\r\n".
-+"0\r\n".
-+"nothing\n";
-+var_dump(http_chunked_decode($data));
-+?>
-+--EXPECTF--
-+%aTEST
-+string(12) "abra
-+cadabra"
-+
---- /dev/null
-+++ b/ext/http/tests/chunked_decode_002.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+http_chunked_decode() "\n"
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$data =
-+"02\n".
-+"ab\n".
-+"04\n".
-+"ra\nc\n".
-+"06\n".
-+"adabra\n".
-+"0\n".
-+"hidden\n";
-+var_dump(http_chunked_decode($data));
-+?>
-+--EXPECTF--
-+%aTEST
-+string(12) "abra
-+cadabra"
-+
---- /dev/null
-+++ b/ext/http/tests/chunked_decode_003.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+http_chunked_decode() truncated message
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$data =
-+"02\r\n".
-+"ab\r\n".
-+"04\r\n".
-+"ra\nc\r\n".
-+"06\r\n".
-+"adabra\r\n".
-+"ff\r\n".
-+"\nall we got\n";
-+var_dump(http_chunked_decode($data));
-+?>
-+--EXPECTF--
-+%aTEST
-+%aWarning%ahttp_chunked_decode()%aTruncated message: chunk size 255 exceeds remaining data size 12 at pos 34 of 46 in%a
-+string(24) "abra
-+cadabra
-+all we got
-+"
---- /dev/null
-+++ b/ext/http/tests/chunked_decode_004.phpt
-@@ -0,0 +1,26 @@
-+--TEST--
-+http_chunked_decode() truncated message ending with NUL after a chunk
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$data =
-+"02\r\n".
-+"ab\r\n".
-+"04\r\n".
-+"ra\nc\r\n".
-+"06\r\n".
-+"adabra\r\n".
-+"0c\r\n".
-+"\nall we got\n";
-+var_dump(http_chunked_decode($data));
-+?>
-+--EXPECTF--
-+%aTEST
-+string(24) "abra
-+cadabra
-+all we got
-+"
---- /dev/null
-+++ b/ext/http/tests/cloning_001.phpt
-@@ -0,0 +1,29 @@
-+--TEST--
-+cloning
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+checkcls('HttpRequest');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$r1 = new HttpRequest;
-+$r2 = clone $r1;
-+$r1->setOptions(array('redirect' => 3));
-+var_dump($r1->getOptions() == $r2->getOptions());
-+$r1->setUrl('http://www.google.com/');
-+var_dump($r1->getUrl() == $r2->getUrl());
-+$r1->send();
-+var_dump($r1->getResponseInfo() == $r2->getResponseInfo());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(false)
-+bool(false)
-+bool(false)
-+Done
---- /dev/null
-+++ b/ext/http/tests/data.txt
-@@ -0,0 +1,10 @@
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
---- /dev/null
-+++ b/ext/http/tests/date_001.phpt
-@@ -0,0 +1,17 @@
-+--TEST--
-+http_date() with timestamp
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+echo http_date(1), "\n";
-+echo http_date(1234567890), "\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Thu, 01 Jan 1970 00:00:01 GMT
-+Fri, 13 Feb 2009 23:31:30 GMT
-+
---- /dev/null
-+++ b/ext/http/tests/date_002.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+http_date() without timestamp
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+ini_set('date.timezone', 'GMT');
-+$d = http_date();
-+$t = strtotime($d);
-+var_dump($t > 1);
-+echo "$t\n$d\nDone\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+%d
-+%a, %d %a %d %d:%d:%d GMT
-+Done
---- /dev/null
-+++ b/ext/http/tests/encoding_objects_001.phpt
-@@ -0,0 +1,35 @@
-+--TEST--
-+encoding stream objects
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$d = new HttpDeflateStream;
-+$i = new HttpInflateStream;
-+echo $i->flush($d->flush("Hi "));
-+echo $i->finish($d->finish("there!\n"));
-+echo $i->finish($d->finish("Yo...\n"));
-+
-+$id = $i->update($d->update($pd = file_get_contents(__FILE__)));
-+foreach (glob('*.phpt') as $f) {
-+ $id .= $i->update($d->update($tmp = file_get_contents($f)));
-+ $pd .= $tmp;
-+}
-+$id .= $i->finish($d->finish());
-+
-+var_dump($id == $pd);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Hi there!
-+Yo...
-+bool(true)
-+Done
-+
---- /dev/null
-+++ b/ext/http/tests/encodings.phpt
-@@ -0,0 +1,44 @@
-+--TEST--
-+encodings
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+skipif(!function_exists('http_deflate'), 'need zlib');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+set_time_limit(0);
-+error_reporting(E_ALL);
-+
-+$s = '';
-+
-+for ($i = 0; $i < 5000; ++$i) {
-+ $s .= chr(rand(0,255));
-+}
-+
-+var_dump($s == http_inflate(http_deflate($s, HTTP_DEFLATE_TYPE_ZLIB)));
-+var_dump($s == http_inflate(http_deflate($s, HTTP_DEFLATE_TYPE_GZIP)));
-+var_dump($s == http_inflate(http_deflate($s, HTTP_DEFLATE_TYPE_RAW)));
-+
-+if (extension_loaded('zlib')) {
-+
-+ $s = "A simple test string, which won't blow up ext/zlib.\n";
-+
-+ ($s == http_inflate(gzencode($s))) or print "GZIP Failed\n";
-+ ($s == http_inflate(gzdeflate($s))) or print "DEFLATE Failed\n";
-+ ($s == http_inflate(gzcompress($s))) or print "COMPRESS Failed\n";
-+
-+ ($s == gzinflate(http_deflate($s, HTTP_DEFLATE_TYPE_RAW))) or print "INFLATE Failed\n";
-+ ($s == gzuncompress(http_deflate($s, HTTP_DEFLATE_TYPE_ZLIB))) or print "UNCOMPRESS Failed\n";
-+}
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+bool(true)
-+bool(true)
-+Done
---- /dev/null
-+++ b/ext/http/tests/etag_mode_031.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+crc32 etag (may fail because PHPs crc32 is actually crc32b)
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', extension_loaded('hash')?'crc32b':'crc32');
-+http_cache_etag();
-+http_send_data("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+Accept-Ranges: bytes
-+ETag: "4e818847"
-+Content-Length: 4
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_032.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+sha1 etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'SHA1');
-+http_cache_etag();
-+http_send_data("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+Accept-Ranges: bytes
-+ETag: "03cfd743661f07975fa2f1220c5194cbaff48451"
-+Content-Length: 4
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_033.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+md5 etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'MD5');
-+http_cache_etag();
-+http_send_data("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+Accept-Ranges: bytes
-+ETag: "0bee89b07a248e27c83fc3d5951213c1"
-+Content-Length: 4
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_034.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+ext/hash etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+skipif(!extension_loaded('hash'), 'need ext/hash support');
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'sha256');
-+http_cache_etag();
-+http_send_data("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+Accept-Ranges: bytes
-+ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb"
-+Content-Length: 4
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_041.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+ob crc32 etag (may fail because PHPs crc32 is actually crc32b)
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', extension_loaded('hash')?'crc32b':'crc32');
-+http_cache_etag();
-+print("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "4e818847"
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_042.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+ob sha1 etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'SHA1');
-+http_cache_etag();
-+print("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "03cfd743661f07975fa2f1220c5194cbaff48451"
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_043.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+ob md5 etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'bogus');
-+http_cache_etag();
-+print("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "0bee89b07a248e27c83fc3d5951213c1"
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/etag_mode_044.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+ob ext/hash etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+skipif(!extension_loaded('hash'), 'need ext/hash support');
-+?>
-+--FILE--
-+<?php
-+ini_set('http.etag.mode', 'sha256');
-+http_cache_etag();
-+print("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%a
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb"
-+Content-type: %a
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/exceptions.phpt
-@@ -0,0 +1,53 @@
-+--TEST--
-+exceptions
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+ini_set('http.only_exceptions', true);
-+
-+$e = array(
-+ HTTP_E_RUNTIME => 'Runtime',
-+ HTTP_E_INVALID_PARAM => 'InvalidParam',
-+ HTTP_E_HEADER => 'Header',
-+ HTTP_E_MALFORMED_HEADERS => 'MalformedHeaders',
-+ HTTP_E_REQUEST_METHOD => 'RequestMethod',
-+ HTTP_E_MESSAGE_TYPE => 'MessageType',
-+ HTTP_E_ENCODING => 'Encoding',
-+ HTTP_E_REQUEST => 'Request',
-+ HTTP_E_REQUEST_POOL => 'RequestPool',
-+ HTTP_E_SOCKET => 'Socket',
-+ HTTP_E_RESPONSE => 'Response',
-+ HTTP_E_URL => 'Url',
-+);
-+
-+foreach ($e as $i => $c) {
-+ try {
-+ $n = "Http{$c}Exception";
-+ throw new $n;
-+ } catch (HttpException $x) {
-+ printf("%2d: %s\n", $i, get_class($x));
-+ }
-+}
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+ 1: HttpRuntimeException
-+ 2: HttpInvalidParamException
-+ 3: HttpHeaderException
-+ 4: HttpMalformedHeadersException
-+ 5: HttpRequestMethodException
-+ 6: HttpMessageTypeException
-+ 7: HttpEncodingException
-+ 8: HttpRequestException
-+ 9: HttpRequestPoolException
-+10: HttpSocketException
-+11: HttpResponseException
-+12: HttpUrlException
-+Done
---- /dev/null
-+++ b/ext/http/tests/get_request_data_001.phpt
-@@ -0,0 +1,40 @@
-+--TEST--
-+get request data
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--POST--
-+a=b&c=d
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$_SERVER['HTTP_ACCEPT_CHARSET'] = 'iso-8859-1, *';
-+$_SERVER['HTTP_ACCEPT_ENCODING'] = 'none';
-+$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0';
-+$_SERVER['HTTP_HOST'] = 'localhost';
-+
-+$h = http_get_request_headers();
-+ksort($h);
-+print_r($h);
-+var_dump(http_get_request_body());
-+var_dump(http_get_request_body());
-+var_dump(http_get_request_body());
-+var_dump(fread(http_get_request_body_stream(), 4096));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+Array
-+(
-+ [Accept-Charset] => iso-8859-1, *
-+ [Accept-Encoding] => none
-+ [Host] => localhost
-+ [User-Agent] => Mozilla/5.0
-+)
-+string(7) "a=b&c=d"
-+string(7) "a=b&c=d"
-+string(7) "a=b&c=d"
-+string(7) "a=b&c=d"
-+Done
---- /dev/null
-+++ b/ext/http/tests/log.inc
-@@ -0,0 +1,23 @@
-+<?php
-+define('_REDIR_LOG', '__r_log');
-+define('_CACHE_LOG', '__c_log');
-+define('_AMETH_LOG', '__m_log');
-+define('_CMPST_LOG', '__a_log');
-+
-+function log_prepare($log)
-+{
-+ is_file($log) and @unlink($log);
-+ switch ($log)
-+ {
-+ case _REDIR_LOG: ini_set('http.log.redirect', _REDIR_LOG); break;
-+ case _CACHE_LOG: ini_set('http.log.cache', _CACHE_LOG); break;
-+ case _AMETH_LOG: ini_set('http.log.allowed_methods', _AMETH_LOG); break;
-+ case _CMPTS_LOG: ini_set('http.log.composite', _CMPST_LOG); break;
-+ }
-+}
-+function log_content($log)
-+{
-+ echo file_get_contents($log);
-+ unlink($log);
-+}
-+?>
---- /dev/null
-+++ b/ext/http/tests/match_request_header_001.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+http_match_request_header()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_FOO=bar
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+var_dump(http_match_request_header("Foo", "bar", 1));
-+var_dump(http_match_request_header("fOO", "BAR", 0));
-+var_dump(http_match_request_header("foo", "BAR", 1));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+bool(true)
-+bool(false)
-+Done
---- /dev/null
-+++ b/ext/http/tests/negotiation_001.phpt
-@@ -0,0 +1,64 @@
-+--TEST--
-+negotiation
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_ACCEPT=application/xml, application/xhtml+xml, text/html ; q = .8
-+HTTP_ACCEPT_LANGUAGE=de-AT,de-DE;q=0.8,en-GB;q=0.3,en-US;q=0.2
-+HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q=0.7,*;q=0.7
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$langs = array(
-+ array('de', 'en', 'es'),
-+);
-+$csets = array(
-+ array('utf-8', 'iso-8859-1'),
-+);
-+$ctype = array(
-+ array('foo/bar', 'application/xhtml+xml', 'text/html')
-+);
-+var_dump(http_negotiate_language($langs[0]));
-+var_dump(http_negotiate_language($langs[0], $lresult));
-+var_dump(http_negotiate_charset($csets[0]));
-+var_dump(http_negotiate_charset($csets[0], $cresult));
-+var_dump(http_negotiate_content_type($ctype[0]));
-+var_dump(http_negotiate_content_type($ctype[0], $tresult));
-+var_dump(http_negotiate_language(array("unknown")));
-+var_dump(http_negotiate_charset(array("unknown")));
-+var_dump(http_negotiate_content_type(array("unknown")));
-+print_r($lresult);
-+print_r($cresult);
-+print_r($tresult);
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(2) "de"
-+string(2) "de"
-+string(10) "iso-8859-1"
-+string(10) "iso-8859-1"
-+string(21) "application/xhtml+xml"
-+string(21) "application/xhtml+xml"
-+string(7) "unknown"
-+string(7) "unknown"
-+string(7) "unknown"
-+Array
-+(
-+ [de] => 900
-+ [en] => 0.27
-+)
-+Array
-+(
-+ [iso-8859-1] => 1000
-+ [utf-8] => 0.7
-+)
-+Array
-+(
-+ [application/xhtml+xml] => 999
-+ [text/html] => 0.8
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/ob_deflatehandler_001.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+ob_deflatehandler
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib");
-+?>
-+--ENV--
-+HTTP_ACCEPT_ENCODING=gzip
-+--FILE--
-+<?php
-+ob_start('ob_deflatehandler');
-+echo "-TEST\n";
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%a
-+Content-Encoding: gzip
-+Vary: Accept-Encoding
-+%a
-+
---- /dev/null
-+++ b/ext/http/tests/ob_inflatehandler_001.phpt
-@@ -0,0 +1,16 @@
-+--TEST--
-+ob_inflatehandler
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib");
-+?>
-+--FILE--
-+<?php
-+ob_start('ob_inflatehandler');
-+echo http_deflate("TEST\n");
-+?>
-+--EXPECTF--
-+%aTEST
-+
---- /dev/null
-+++ b/ext/http/tests/parse_cookie_001.phpt
-@@ -0,0 +1,41 @@
-+--TEST--
-+parse cookie
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+var_dump(http_parse_cookie('name="value"; foo="bar\"baz"; hey=got"it ; path=/ ; comment=; expires='.http_date(1).' secure ; httpOnly', 0, array("comment")));
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(stdClass)%a {
-+ ["cookies"]=>
-+ array(3) {
-+ ["name"]=>
-+ string(5) "value"
-+ ["foo"]=>
-+ string(7) "bar"baz"
-+ ["hey"]=>
-+ string(6) "got"it"
-+ }
-+ ["extras"]=>
-+ array(1) {
-+ ["comment"]=>
-+ string(0) ""
-+ }
-+ ["flags"]=>
-+ int(32)
-+ ["expires"]=>
-+ int(1)
-+ ["path"]=>
-+ string(1) "/"
-+ ["domain"]=>
-+ string(0) ""
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_cookie_002.phpt
-@@ -0,0 +1,80 @@
-+--TEST--
-+parse cookie
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+var_dump(http_parse_cookie('foo')->cookies['foo']);
-+var_dump(http_parse_cookie('foo;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo ')->cookies['foo']);
-+var_dump(http_parse_cookie('foo ;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo ; ')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo =')->cookies['foo']);
-+var_dump(http_parse_cookie('foo =;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= ')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= ;')->cookies['foo']);
-+
-+var_dump(http_parse_cookie('foo=1')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=1;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=1 ;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= 1;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo = 1;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo = 1 ;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=1')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= 1')->cookies['foo']);
-+
-+var_dump(http_parse_cookie('foo="1"')->cookies['foo']);
-+var_dump(http_parse_cookie('foo="1" ')->cookies['foo']);
-+var_dump(http_parse_cookie('foo="1";')->cookies['foo']);
-+var_dump(http_parse_cookie('foo = "1" ;')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= "1" ')->cookies['foo']);
-+
-+var_dump(http_parse_cookie('foo=""')->cookies['foo']);
-+var_dump(http_parse_cookie('foo="\""')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=" "')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= "')->cookies['foo']);
-+var_dump(http_parse_cookie('foo=" ')->cookies['foo']);
-+var_dump(http_parse_cookie('foo= " ')->cookies['foo']);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(0) ""
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(1) "1"
-+string(0) ""
-+string(1) """
-+string(1) " "
-+string(1) """
-+string(1) """
-+string(1) """
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_headers_001.phpt
-@@ -0,0 +1,41 @@
-+--TEST--
-+http_parse_headers()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+print_r(http_parse_headers(
-+"Host: localhost\r\n".
-+"Host: ambigious\r\n".
-+"Nospace:here\r\n".
-+"Muchspace: there \r\n".
-+"Empty:\r\n".
-+"Empty2: \r\n".
-+"Folded: one\r\n".
-+"\ttwo\r\n".
-+" three\r\n\r\n".
-+"stop\r\n"
-+));
-+?>
-+--EXPECTF--
-+%aTEST
-+Array
-+(
-+ [Host] => Array
-+ (
-+ [0] => localhost
-+ [1] => ambigious
-+ )
-+
-+ [Nospace] => here
-+ [Muchspace] => there
-+ [Empty] =>
-+ [Empty2] =>
-+ [Folded] => one
-+ two
-+ three
-+)
-+
---- /dev/null
-+++ b/ext/http/tests/parse_message_001.phpt
-@@ -0,0 +1,18 @@
-+--TEST--
-+http_parse_message()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkurl('www.google.com');
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), 'need curl support');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+$m = http_parse_message(http_get('http://www.google.com'));
-+echo $m->body;
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+<HTML>%aThe document has moved%a</HTML>
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_message_002.phpt
-@@ -0,0 +1,39 @@
-+--TEST--
-+identity encoding trap
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$message =
-+"HTTP/1.1 200 Ok\n".
-+"Transfer-Encoding: identity\n".
-+"Content-Length: 3\n".
-+"Content-Type: text/plain\n\n".
-+"Hi!\n\n\n\n";
-+
-+print_r(http_parse_message($message));
-+
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+stdClass Object
-+(
-+ [type] => 2
-+ [httpVersion] => 1.1
-+ [responseCode] => 200
-+ [responseStatus] => Ok
-+ [headers] => Array
-+ (
-+ [Transfer-Encoding] => identity
-+ [Content-Length] => 3
-+ [Content-Type] => text/plain
-+ )
-+
-+ [body] => Hi!
-+ [parentMessage] =>
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_message_003.phpt
-@@ -0,0 +1,31 @@
-+--TEST--
-+content range message
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$message =
-+"HTTP/1.1 200 Ok\n".
-+"Content-Range: bytes: 0-1/5\n\n".
-+"OK\n";
-+
-+$msg = http_parse_message($message);
-+var_dump($msg->body);
-+
-+$message =
-+"HTTP/1.1 200 Ok\n".
-+"Content-Range: bytes 0-1/1\n\n".
-+"X\n";
-+
-+$msg = http_parse_message($message);
-+
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+string(2) "OK"
-+%a Invalid Content-Range header: bytes 0-1/1 in%a
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_message_004.phpt
-@@ -0,0 +1,115 @@
-+--TEST--
-+http_parse_message() recursive
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+
-+echo "-TEST\n";
-+$message =
-+"HEAD / HTTP/1.1
-+Host: www.example.com
-+Accept: */*
-+HTTP/1.1 200 Ok
-+Server: Funky/1.0
-+Content-Length: 10
-+GET / HTTP/1.1
-+Host: www.example.com
-+Accept: */*
-+HTTP/1.1 200 Ok
-+Server: Funky/1.0
-+Content-Length: 10
-+
-+1234567890
-+";
-+
-+var_dump(http_parse_message($message));
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(stdClass)%a {
-+ ["type"]=>
-+ int(2)
-+ ["httpVersion"]=>
-+ float(1.1)
-+ ["responseCode"]=>
-+ int(200)
-+ ["responseStatus"]=>
-+ string(2) "Ok"
-+ ["headers"]=>
-+ array(2) {
-+ ["Server"]=>
-+ string(9) "Funky/1.0"
-+ ["Content-Length"]=>
-+ string(2) "10"
-+ }
-+ ["body"]=>
-+ string(10) "1234567890"
-+ ["parentMessage"]=>
-+ object(stdClass)%a {
-+ ["type"]=>
-+ int(1)
-+ ["httpVersion"]=>
-+ float(1.1)
-+ ["requestMethod"]=>
-+ string(3) "GET"
-+ ["requestUrl"]=>
-+ string(1) "/"
-+ ["headers"]=>
-+ array(2) {
-+ ["Host"]=>
-+ string(15) "www.example.com"
-+ ["Accept"]=>
-+ string(3) "*/*"
-+ }
-+ ["body"]=>
-+ string(0) ""
-+ ["parentMessage"]=>
-+ object(stdClass)%a {
-+ ["type"]=>
-+ int(2)
-+ ["httpVersion"]=>
-+ float(1.1)
-+ ["responseCode"]=>
-+ int(200)
-+ ["responseStatus"]=>
-+ string(2) "Ok"
-+ ["headers"]=>
-+ array(2) {
-+ ["Server"]=>
-+ string(9) "Funky/1.0"
-+ ["Content-Length"]=>
-+ string(2) "10"
-+ }
-+ ["body"]=>
-+ string(0) ""
-+ ["parentMessage"]=>
-+ object(stdClass)%a {
-+ ["type"]=>
-+ int(1)
-+ ["httpVersion"]=>
-+ float(1.1)
-+ ["requestMethod"]=>
-+ string(4) "HEAD"
-+ ["requestUrl"]=>
-+ string(1) "/"
-+ ["headers"]=>
-+ array(2) {
-+ ["Host"]=>
-+ string(15) "www.example.com"
-+ ["Accept"]=>
-+ string(3) "*/*"
-+ }
-+ ["body"]=>
-+ string(0) ""
-+ ["parentMessage"]=>
-+ NULL
-+ }
-+ }
-+ }
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_message_005.phpt
-@@ -0,0 +1,60 @@
-+--TEST--
-+http_parse_message() content range header w/(o) =
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+print_r(http_parse_message(
-+"
-+HTTP/1.1 206
-+Server: Funky/1.0
-+Content-Range: bytes: 0-0/100
-+
-+1
-+
-+HTTP/1.1 206
-+Server: Funky/1.0
-+Content-Range: bytes 0-0/100
-+
-+1
-+
-+"
-+));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+stdClass Object
-+(
-+ [type] => 2
-+ [httpVersion] => 1.1
-+ [responseCode] => 206
-+ [responseStatus] =>
-+ [headers] => Array
-+ (
-+ [Server] => Funky/1.0
-+ [Content-Range] => bytes 0-0/100
-+ )
-+
-+ [body] => 1
-+ [parentMessage] => stdClass Object
-+ (
-+ [type] => 2
-+ [httpVersion] => 1.1
-+ [responseCode] => 206
-+ [responseStatus] =>
-+ [headers] => Array
-+ (
-+ [Server] => Funky/1.0
-+ [Content-Range] => bytes: 0-0/100
-+ )
-+
-+ [body] => 1
-+ [parentMessage] =>
-+ )
-+
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_message_006.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+mixed EOL trap
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$message =
-+"HTTP/1.1 200 Ok\n".
-+"Header: Value\r\n".
-+"Connection: close\r\n".
-+"\n".
-+"Bug!";
-+
-+print_r(http_parse_message($message));
-+
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+stdClass Object
-+(
-+ [type] => 2
-+ [httpVersion] => 1.1
-+ [responseCode] => 200
-+ [responseStatus] => Ok
-+ [headers] => Array
-+ (
-+ [Header] => Value
-+ [Connection] => close
-+ )
-+
-+ [body] => Bug!
-+ [parentMessage] =>
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/parse_params_001.phpt
-@@ -0,0 +1,75 @@
-+--TEST--
-+http_parse_params
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+var_dump(http_parse_params('text/html; charset=iso-8859-1'));
-+var_dump(http_parse_params('text/html; charset="iso-8859-1"'));
-+var_dump(http_parse_params('attachment; filename="gol;got,a.ext"'));
-+var_dump(http_parse_params('public, must-revalidate, max-age=0'));
-+$p = http_parse_params('a'); var_dump($p->params[0]);
-+$p = http_parse_params('a=b'); var_dump($p->params[0]);
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+object(stdClass)%a {
-+ ["params"]=>
-+ array(2) {
-+ [0]=>
-+ string(9) "text/html"
-+ [1]=>
-+ array(1) {
-+ ["charset"]=>
-+ string(10) "iso-8859-1"
-+ }
-+ }
-+}
-+object(stdClass)%a {
-+ ["params"]=>
-+ array(2) {
-+ [0]=>
-+ string(9) "text/html"
-+ [1]=>
-+ array(1) {
-+ ["charset"]=>
-+ string(10) "iso-8859-1"
-+ }
-+ }
-+}
-+object(stdClass)%a {
-+ ["params"]=>
-+ array(2) {
-+ [0]=>
-+ string(10) "attachment"
-+ [1]=>
-+ array(1) {
-+ ["filename"]=>
-+ string(13) "gol;got,a.ext"
-+ }
-+ }
-+}
-+object(stdClass)%a {
-+ ["params"]=>
-+ array(3) {
-+ [0]=>
-+ string(6) "public"
-+ [1]=>
-+ string(15) "must-revalidate"
-+ [2]=>
-+ array(1) {
-+ ["max-age"]=>
-+ string(1) "0"
-+ }
-+ }
-+}
-+string(1) "a"
-+array(1) {
-+ ["a"]=>
-+ string(1) "b"
-+}
-+Done
---- /dev/null
-+++ b/ext/http/tests/persistent_handles_001.phpt
-@@ -0,0 +1,91 @@
-+--TEST--
-+persistent handles
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+skipif(!function_exists('zend_thread_id'), "need ZTS build");
-+?>
-+--INI--
-+http.persistent.handles.limit=-1
-+http.persistent.handles.ident=GLOBAL
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+echo "No free handles!\n";
-+foreach (http_persistent_handles_count() as $provider => $idents) {
-+ foreach ((array)$idents as $ident => $counts) {
-+ if (!empty($counts["free"])) {
-+ printf("%a, %a, %a\n", $provider, $ident, $counts["free"]);
-+ }
-+ }
-+}
-+
-+http_get("http://www.google.com/", null, $info[]);
-+
-+echo "One free request handle within GLOBAL: ";
-+var_dump(http_persistent_handles_count()->http_request["GLOBAL"]["free"]);
-+
-+echo "Reusing request handle: ";
-+http_get("http://www.google.com/", null, $info[]);
-+var_dump($info[0]["pretransfer_time"] > 10 * $info[1]["pretransfer_time"], $info[0]["pretransfer_time"], $info[1]["pretransfer_time"]);
-+
-+echo "Handles' been cleaned up:\n";
-+http_persistent_handles_clean();
-+print_r(http_persistent_handles_count());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+No free handles!
-+One free request handle within GLOBAL: int(1)
-+Reusing request handle: bool(true)
-+float(%f)
-+float(%f)
-+Handles' been cleaned up:
-+stdClass Object
-+(
-+ [http_request] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+ [http_request_datashare] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+ [http_request_datashare_lock] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+ [http_request_pool] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/persistent_handles_002.phpt
-@@ -0,0 +1,83 @@
-+--TEST--
-+persistent handles
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+skipif(function_exists('zend_thread_id'), "need non-ZTS build");
-+?>
-+--INI--
-+http.persistent.handles.limit=-1
-+http.persistent.handles.ident=GLOBAL
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+echo "No free handles!\n";
-+foreach (http_persistent_handles_count() as $provider => $idents) {
-+ foreach ((array)$idents as $ident => $counts) {
-+ if (!empty($counts["free"])) {
-+ printf("%a, %a, %a\n", $provider, $ident, $counts["free"]);
-+ }
-+ }
-+}
-+
-+http_get("http://www.google.com/", null, $info[]);
-+
-+echo "One free request handle within GLOBAL: ";
-+$h = http_persistent_handles_count();
-+var_dump($h->http_request["GLOBAL"]["free"]);
-+
-+echo "Reusing request handle: ";
-+http_get("http://www.google.com/", null, $info[]);
-+var_dump($info[0]["pretransfer_time"] > 10 * $info[1]["pretransfer_time"], $info[0]["pretransfer_time"], $info[1]["pretransfer_time"]);
-+
-+echo "Handles' been cleaned up:\n";
-+http_persistent_handles_clean();
-+print_r(http_persistent_handles_count());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+No free handles!
-+One free request handle within GLOBAL: int(1)
-+Reusing request handle: bool(true)
-+float(%f)
-+float(%f)
-+Handles' been cleaned up:
-+stdClass Object
-+(
-+ [http_request] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+ [http_request_datashare] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+ [http_request_pool] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/persistent_handles_003.phpt
-@@ -0,0 +1,62 @@
-+--TEST--
-+persistent handles
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmax(4.4);
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+?>
-+--INI--
-+http.persistent.handles.limit=-1
-+http.persistent.handles.ident=GLOBAL
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+echo "No free handles!\n";
-+foreach (http_persistent_handles_count() as $provider => $idents) {
-+ foreach ((array)$idents as $ident => $counts) {
-+ if (!empty($counts["free"])) {
-+ printf("%a, %a, %a\n", $provider, $ident, $counts["free"]);
-+ }
-+ }
-+}
-+
-+http_get("http://www.google.com/", null, $info[]);
-+
-+echo "One free request handle within GLOBAL: ";
-+$h = http_persistent_handles_count();
-+var_dump($h->http_request["GLOBAL"]["free"]);
-+
-+echo "Reusing request handle: ";
-+http_get("http://www.google.com/", null, $info[]);
-+var_dump($info[0]["pretransfer_time"] > 10 * $info[1]["pretransfer_time"], $info[0]["pretransfer_time"], $info[1]["pretransfer_time"]);
-+
-+echo "Handles' been cleaned up:\n";
-+http_persistent_handles_clean();
-+print_r(http_persistent_handles_count());
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+No free handles!
-+One free request handle within GLOBAL: int(1)
-+Reusing request handle: bool(true)
-+float(%f)
-+float(%f)
-+Handles' been cleaned up:
-+stdClass Object
-+(
-+ [http_request] => Array
-+ (
-+ [GLOBAL] => Array
-+ (
-+ [used] => 0
-+ [free] => 0
-+ )
-+
-+ )
-+
-+)
-+Done
---- /dev/null
-+++ b/ext/http/tests/redirect_011.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+http_redirect() with params
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=localhost
-+--FILE--
-+<?php
-+include 'log.inc';
-+log_prepare(_REDIR_LOG);
-+http_redirect('redirect', array('a' => 1, 'b' => 2));
-+?>
-+--EXPECTF--
-+Status: 302%s
-+X-Powered-By: PHP/%a
-+Location: http://localhost/redirect?a=1&b=2
-+Content-type: %a
-+
-+Redirecting to <a href="http://localhost/redirect?a=1&b=2">http://localhost/redirect?a=1&b=2</a>.
-+
---- /dev/null
-+++ b/ext/http/tests/redirect_011_logging.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+logging redirects
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=example.com
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+include 'log.inc';
-+log_content(_REDIR_LOG);
-+echo "Done";
-+?>
-+--EXPECTF--
-+%aTEST
-+%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d [302-REDIRECT] Location: http%a <%a>
-+Done
---- /dev/null
-+++ b/ext/http/tests/redirect_012.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+http_redirect() with session
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+checkext('session');
-+?>
-+--ENV--
-+HTTP_HOST=localhost
-+--FILE--
-+<?php
-+include 'log.inc';
-+log_prepare(_REDIR_LOG);
-+session_start();
-+http_redirect('redirect', array('a' => 1), true);
-+?>
-+--EXPECTF--
-+Status: 302%s
-+X-Powered-By: PHP/%a
-+Set-Cookie: PHPSESSID=%a; path=/
-+Expires: %a
-+Cache-Control: %a
-+Pragma: %a
-+Location: http://localhost/redirect?a=1&PHPSESSID=%a
-+Content-type: %a
---- /dev/null
-+++ b/ext/http/tests/redirect_012_logging.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+logging redirects
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+checkext("session");
-+?>
-+--ENV--
-+HTTP_HOST=example.com
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+include 'log.inc';
-+log_content(_REDIR_LOG);
-+echo "Done";
-+?>
-+--EXPECTF--
-+%aTEST
-+%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d [302-REDIRECT] Location: http%a <%a>
-+Done
---- /dev/null
-+++ b/ext/http/tests/redirect_013.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+http_redirect() permanent
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=localhost
-+--FILE--
-+<?php
-+include 'log.inc';
-+log_prepare(_REDIR_LOG);
-+http_redirect('redirect', null, false, HTTP_REDIRECT_PERM);
-+?>
-+--EXPECTF--
-+Status: 301%s
-+X-Powered-By: PHP/%a
-+Location: http://localhost/redirect
-+Content-type: %a
-+
-+Redirecting to <a href="http://localhost/redirect">http://localhost/redirect</a>.
-+
---- /dev/null
-+++ b/ext/http/tests/redirect_013_logging.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+logging redirects
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_HOST=example.com
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+include 'log.inc';
-+log_content(_REDIR_LOG);
-+echo "Done";
-+?>
-+--EXPECTF--
-+%aTEST
-+%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d [301-REDIRECT] Location: http%a <%a>
-+Done
---- /dev/null
-+++ b/ext/http/tests/request_cookies.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+urlencoded cookies
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$cookies = array("name" => "val=ue");
-+
-+$r = new HttpRequest("http://dev.iworks.at/ext-http/.print_request.php", HTTP_METH_GET, array("cookies" => $cookies));
-+$r->recordHistory = true;
-+$r->send();
-+$r->setOptions(array('encodecookies' => false));
-+$r->send();
-+echo $r->getHistory()->toString(true);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+GET /ext-http/.print_request.php HTTP/1.1
-+User-Agent: %a
-+Host: dev.iworks.at
-+Accept: */*
-+Cookie: name=val%3Due
-+HTTP/1.1 200 OK
-+%a
-+
-+Array
-+(
-+ [name] => val=ue
-+)
-+
-+GET /ext-http/.print_request.php HTTP/1.1
-+User-Agent: %a
-+Host: dev.iworks.at
-+Accept: */*
-+Cookie: name=val=ue;
-+HTTP/1.1 200 OK
-+%a
-+
-+Array
-+(
-+ [name] => val=ue
-+)
-+
-+Done
---- /dev/null
-+++ b/ext/http/tests/request_etag.phpt
-@@ -0,0 +1,21 @@
-+--TEST--
-+request etag
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+var_dump(http_get("http://dev.iworks.at/ext-http/etag", array("etag" => '"26ad3a-5-95eb19c0"')));
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(%d) "HTTP/1.1 304 Not Modified
-+Date: %a
-+Server: %a
-+ETag: "26ad3a-5-95eb19c0"
-+"
-+Done
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/request_gzip.phpt
-@@ -0,0 +1,51 @@
-+--TEST--
-+GZIP request
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkurl('dev.iworks.at');
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), 'need curl support');
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+var_dump(http_parse_message(http_get('http://dev.iworks.at/ext-http/.print_request.php?gzip=1', array('compress' => true))));
-+
-+echo "Done\n";
-+--EXPECTF--
-+%aTEST
-+object(stdClass)%a {
-+ ["type"]=>
-+ int(2)
-+ ["httpVersion"]=>
-+ float(1.1)
-+ ["responseCode"]=>
-+ int(200)
-+ ["responseStatus"]=>
-+ string(2) "OK"
-+ ["headers"]=>
-+ array(%d) {
-+ %a
-+ ["Vary"]=>
-+ string(15) "Accept-Encoding"
-+ ["Content-Length"]=>
-+ string(2) "26"
-+ ["Content-Type"]=>
-+ string(9) "text/html"
-+ ["X-Original-Content-Encoding"]=>
-+ string(4) "gzip"
-+ ["X-Original-Content-Length"]=>
-+ string(2) "51"
-+ }
-+ ["body"]=>
-+ string(26) "Array
-+(
-+ [gzip] => 1
-+)
-+"
-+ ["parentMessage"]=>
-+ NULL
-+}
-+Done
-+
---- /dev/null
-+++ b/ext/http/tests/request_methods.phpt
-@@ -0,0 +1,144 @@
-+--TEST--
-+request methods
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+for ($i = 0; $i <= HTTP_METH_ACL+1; ++$i) {
-+ var_dump(http_request_method_exists($i));
-+ echo $name = http_request_method_name($i), "\n";
-+ var_dump(http_request_method_exists($name));
-+}
-+
-+for ($i = 0; $i < 5; ++$i) {
-+ $n = http_request_method_register("M$i");
-+ var_dump(http_request_method_exists($n));
-+ var_dump(http_request_method_exists("M$i"));
-+}
-+for ($i = 0; $i < 5; ++$i) {
-+ var_dump(http_request_method_unregister("M$i"));
-+ var_dump(http_request_method_exists("M$i"));
-+ var_dump(http_request_method_exists($i+HTTP_METH_ACL+1));
-+}
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+int(0)
-+UNKNOWN
-+int(0)
-+int(1)
-+GET
-+int(1)
-+int(2)
-+HEAD
-+int(2)
-+int(3)
-+POST
-+int(3)
-+int(4)
-+PUT
-+int(4)
-+int(5)
-+DELETE
-+int(5)
-+int(6)
-+OPTIONS
-+int(6)
-+int(7)
-+TRACE
-+int(7)
-+int(8)
-+CONNECT
-+int(8)
-+int(9)
-+PROPFIND
-+int(9)
-+int(10)
-+PROPPATCH
-+int(10)
-+int(11)
-+MKCOL
-+int(11)
-+int(12)
-+COPY
-+int(12)
-+int(13)
-+MOVE
-+int(13)
-+int(14)
-+LOCK
-+int(14)
-+int(15)
-+UNLOCK
-+int(15)
-+int(16)
-+VERSION-CONTROL
-+int(16)
-+int(17)
-+REPORT
-+int(17)
-+int(18)
-+CHECKOUT
-+int(18)
-+int(19)
-+CHECKIN
-+int(19)
-+int(20)
-+UNCHECKOUT
-+int(20)
-+int(21)
-+MKWORKSPACE
-+int(21)
-+int(22)
-+UPDATE
-+int(22)
-+int(23)
-+LABEL
-+int(23)
-+int(24)
-+MERGE
-+int(24)
-+int(25)
-+BASELINE-CONTROL
-+int(25)
-+int(26)
-+MKACTIVITY
-+int(26)
-+int(27)
-+ACL
-+int(27)
-+int(0)
-+UNKNOWN
-+int(0)
-+int(28)
-+int(28)
-+int(29)
-+int(29)
-+int(30)
-+int(30)
-+int(31)
-+int(31)
-+int(32)
-+int(32)
-+bool(true)
-+int(0)
-+int(0)
-+bool(true)
-+int(0)
-+int(0)
-+bool(true)
-+int(0)
-+int(0)
-+bool(true)
-+int(0)
-+int(0)
-+bool(true)
-+int(0)
-+int(0)
-+Done
---- /dev/null
-+++ b/ext/http/tests/request_put_data.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+http_put_data()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+skipif(!http_support(HTTP_SUPPORT_REQUESTS), "need request support");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+$data = str_repeat("abc", 6000/* > CURLBUF_SIZE */);
-+$resp = http_put_data("http://dev.iworks.at/ext-http/.print_put.php5", $data);
-+$mess = http_parse_message($resp);
-+var_dump($data === $mess->body);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+Done
---- /dev/null
-+++ b/ext/http/tests/send_data_001.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+http_send_data() NIL-NUM range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=-5
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Content-Type: text/plain
-+Accept-Ranges: bytes
-+Content-Range: bytes 5995-5999/6000
-+Content-Length: 5
-+
-+23abc
---- /dev/null
-+++ b/ext/http/tests/send_data_002.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+http_send_data() NUM-NUM range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=5-6
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Content-Type: text/plain
-+Accept-Ranges: bytes
-+Content-Range: bytes 5-6/6000
-+Content-Length: 2
-+
-+c1
---- /dev/null
-+++ b/ext/http/tests/send_data_003.phpt
-@@ -0,0 +1,24 @@
-+--TEST--
-+http_send_data() NUM-NIL range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=5981-
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Content-Type: text/plain
-+Accept-Ranges: bytes
-+Content-Range: bytes 5981-5999/6000
-+Content-Length: 19
-+
-+c123abc123abc123abc
---- /dev/null
-+++ b/ext/http/tests/send_data_004.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+http_send_data() syntactically invalid range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin(5);
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=123,-wtf ?
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%s
-+Content-Type: text/plain
-+Accept-Ranges: bytes
-+Content-Length: 6000
-+
-+123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/send_data_005.phpt
-@@ -0,0 +1,17 @@
-+--TEST--
-+http_send_data() oversized range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=5990-6000
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+Status: 416%a
-\ No newline at end of file
---- /dev/null
-+++ b/ext/http/tests/send_data_006.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+http_send_data() multiple ranges
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=0-3, 4-5,9-11
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_data(str_repeat('123abc', 1000));
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Type: multipart/byteranges; boundary=%d.%d
-+
-+
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 0-3/6000
-+
-+123a
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 4-5/6000
-+
-+bc
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 9-11/6000
-+
-+abc
-+--%d.%d--
---- /dev/null
-+++ b/ext/http/tests/send_data_010.phpt
-@@ -0,0 +1,20 @@
-+--TEST--
-+http_send_data() HTTP_SENDBUF_SIZE long string
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin(5.1);
-+?>
-+--FILE--
-+<?php
-+http_throttle(0.01, 1);
-+http_send_data('00000000000000000000');
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Length: 20
-+Content-type: %s
-+
-+00000000000000000000
---- /dev/null
-+++ b/ext/http/tests/send_data_011.phpt
-@@ -0,0 +1,22 @@
-+--TEST--
-+http_send_data() last modified caching
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin(5.1);
-+?>
-+--FILE--
-+<?php
-+http_cache_last_modified(-5);
-+http_send_data("abc\n");
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%s
-+Cache-Control: private, must-revalidate, max-age=0
-+Last-Modified: %s, %d %s %d %d:%d:%d GMT
-+Accept-Ranges: bytes
-+Content-Length: 4
-+Content-type: %s
-+
-+abc
---- /dev/null
-+++ b/ext/http/tests/send_failed_precond_001.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+http_send() failed precondition
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkver(5.1);
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=0-1
-+HTTP_IF_UNMODIFIED_SINCE=Thu, 01 Jan 1970 00:16:40 GMT
-+--FILE--
-+<?php
-+http_cache_last_modified();
-+http_send_file(__FILE__);
-+?>
-+--EXPECTF--
-+Status: 412%s
-+X-Powered-By: %s
-+Cache-Control: private, must-revalidate, max-age=0
-+Last-Modified: %s
-+Accept-Ranges: bytes
-+Content-type: text/html
---- /dev/null
-+++ b/ext/http/tests/send_file_005.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+http_send_file() multiple ranges
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=0-3, 4-5,9-11
-+--FILE--
-+<?php
-+http_send_content_type('text/plain');
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Type: multipart/byteranges; boundary=%d.%d
-+
-+
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 0-3/1010
-+
-+0123
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 4-5/1010
-+
-+45
-+--%d.%d
-+Content-Type: text/plain
-+Content-Range: bytes 9-11/1010
-+
-+901
-+--%d.%d--
---- /dev/null
-+++ b/ext/http/tests/send_file_008.phpt
-@@ -0,0 +1,28 @@
-+--TEST--
-+http_send_file()
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin(5.1);
-+?>
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Length: 1010
-+Content-type: %s
-+
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
---- /dev/null
-+++ b/ext/http/tests/send_file_009.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+http_send_file() NUM-NUM range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=5-9
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Range: bytes 5-9/1010
-+Content-Length: 5
-+Content-type: %s
-+
-+56789
---- /dev/null
-+++ b/ext/http/tests/send_file_010.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+http_send_file() NIL-NUM range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=-9
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Range: bytes 1001-1009/1010
-+Content-Length: 9
-+Content-type: %s
-+
-+23456789
---- /dev/null
-+++ b/ext/http/tests/send_file_011.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+http_send_file() NUM-NIL range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=1000-
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Range: bytes 1000-1009/1010
-+Content-Length: 10
-+Content-type: %s
-+
-+123456789
---- /dev/null
-+++ b/ext/http/tests/send_file_012.phpt
-@@ -0,0 +1,30 @@
-+--TEST--
-+http_send_file() syntactically invalid range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin(5.1);
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=xxx
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-Length: 1010
-+Content-type: %s
-+
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
---- /dev/null
-+++ b/ext/http/tests/send_file_013.phpt
-@@ -0,0 +1,19 @@
-+--TEST--
-+http_send_file() oversized range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=-1111
-+--FILE--
-+<?php
-+http_send_file('data.txt');
-+?>
-+--EXPECTF--
-+Status: 416
-+X-Powered-By: PHP/%s
-+Accept-Ranges: bytes
-+Content-type: %s
---- /dev/null
-+++ b/ext/http/tests/send_ifrange_001.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+http_send() If-Range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=0-1
-+HTTP_IF_RANGE="abc"
-+--FILE--
-+<?php
-+http_cache_etag('abc');
-+http_send_file(__FILE__);
-+?>
-+--EXPECTF--
-+Status: 206%s
-+X-Powered-By: %s
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "abc"
-+Accept-Ranges: bytes
-+Content-Range: bytes 0-1/%d
-+Content-Length: 2
-+Content-type: text/html
-+
-+<?
---- /dev/null
-+++ b/ext/http/tests/send_ifrange_003.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+http_send() If-Range
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkcgi();
-+checkmin("5.2.5");
-+?>
-+--ENV--
-+HTTP_RANGE=bytes=0-1
-+HTTP_IF_RANGE="abcd"
-+--FILE--
-+<?php
-+http_cache_etag('abc');
-+http_send_file(__FILE__);
-+?>
-+--EXPECTF--
-+X-Powered-By: %s
-+Cache-Control: private, must-revalidate, max-age=0
-+ETag: "abc"
-+Accept-Ranges: bytes
-+Content-Length: %d
-+Content-type: text/html
-+
-+%a
---- /dev/null
-+++ b/ext/http/tests/skip.inc
-@@ -0,0 +1,15 @@
-+<?php
-+defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
-+if (!function_exists('fprintf')) {
-+ function fprintf(){ $a=func_get_args(); $s=array_shift($a); return fwrite($s, call_user_func_array('sprintf',$a)); }
-+}
-+function skipif($if, $skip) { if ($if) { fprintf(STDOUT, "skip $skip"); exit(); }}
-+function checkcgi() { skipif(!strncasecmp('CLI', PHP_SAPI, 3), 'need CGI SAPI'); }
-+function checkext($ext) { skipif(!extension_loaded($ext), "need ext/$ext"); }
-+function checkmin($ver) { skipif(version_compare(PHP_VERSION, $ver) < 0, sprintf("need PHP >= v%s",$ver)); }
-+function checkmax($ver) { skipif(version_compare(PHP_VERSION, $ver) > 0, sprintf("need PHP <= v%s",$ver)); }
-+function checkurl($url) { skipif(!@fsockopen($url, 80), "$url not responsive"); }
-+function checkcls($cls) { skipif(!class_exists($cls), "need class $cls"); }
-+function checkver($ver) { checkmin($ver); }
-+checkext('http');
-+?>
---- /dev/null
-+++ b/ext/http/tests/stream_filters_001.phpt
-@@ -0,0 +1,45 @@
-+--TEST--
-+stream filters
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+define('F', 'http.test_stream_filters');
-+
-+$f = fopen(F, 'w');
-+stream_filter_append($f, 'http.chunked_encode');
-+
-+fwrite($f, "Here ");
-+fwrite($f, "we");
-+fwrite($f, " go!\n");
-+fclose($f);
-+
-+var_dump(file_get_contents(F));
-+
-+$f = fopen(F, 'r');
-+stream_filter_append($f, 'http.chunked_decode');
-+var_dump(fread($f, 256));
-+fclose($f);
-+
-+unlink(F);
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+string(30) "5
-+Here
-+2
-+we
-+5
-+ go!
-+
-+0
-+"
-+string(12) "Here we go!
-+"
-+Done
---- /dev/null
-+++ b/ext/http/tests/stream_filters_002.phpt
-@@ -0,0 +1,50 @@
-+--TEST--
-+gzip stream filters
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkver(5);
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support");
-+?>
-+--FILE--
-+<?php
-+
-+echo "-TEST\n";
-+
-+$d = file_get_contents(__FILE__);
-+$n = tempnam(dirname(__FILE__), 'hsf');
-+
-+$f = fopen($n, 'wb');
-+stream_filter_append($f, 'http.deflate', STREAM_FILTER_WRITE, HTTP_DEFLATE_TYPE_GZIP);
-+fwrite($f, $d);
-+fflush($f);
-+fwrite($f, $d);
-+fclose($f);
-+var_dump($d.$d == http_inflate(file_get_contents($n)));
-+
-+$f = fopen($n, 'wb');
-+stream_filter_append($f, 'http.deflate', STREAM_FILTER_WRITE);
-+fwrite($f, $d);
-+fflush($f);
-+fwrite($f, $d);
-+fclose($f);
-+var_dump($d.$d == http_inflate(file_get_contents($n)));
-+
-+$f = fopen($n, 'wb');
-+stream_filter_append($f, 'http.deflate', STREAM_FILTER_WRITE, HTTP_DEFLATE_TYPE_RAW);
-+fwrite($f, $d);
-+fflush($f);
-+fwrite($f, $d);
-+fclose($f);
-+var_dump($d.$d == http_inflate(file_get_contents($n)));
-+
-+unlink($n);
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+%aTEST
-+bool(true)
-+bool(true)
-+bool(true)
-+Done
---- /dev/null
-+++ b/ext/http/tests/stream_filters_003.phpt
-@@ -0,0 +1,42 @@
-+--TEST--
-+stream filter fun
-+--SKIPIF--
-+<?php
-+include 'skip.inc';
-+checkmin("5.2.5");
-+skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib");
-+?>
-+--FILE--
-+<?php
-+echo "-TEST\n";
-+
-+define('OUT', fopen('php://output', 'w'));
-+
-+stream_filter_append(OUT, 'http.chunked_encode');
-+stream_filter_append(OUT, 'http.deflate');
-+stream_filter_append(OUT, 'http.chunked_encode');
-+stream_filter_append(OUT, 'http.deflate');
-+stream_filter_append(OUT, 'http.inflate');
-+stream_filter_append(OUT, 'http.chunked_decode');
-+stream_filter_append(OUT, 'http.inflate');
-+stream_filter_append(OUT, 'http.chunked_decode');
-+
-+$text = <<<SOME_TEXT
-+This is some stream filter fun; we'll see if it bails out or not.
-+The text should come out at the other end of the stream exactly like written to it.
-+Go figure!
-+SOME_TEXT;
-+
-+srand(time());
-+foreach (str_split($text, 5) as $part) {
-+ fwrite(OUT, $part);
-+ if (rand(0, 1)) {
-+ fflush(OUT);
-+ }
-+}
-+?>
-+--EXPECTF--
-+%aTEST
-+This is some stream filter fun; we'll see if it bails out or not.
-+The text should come out at the other end of the stream exactly like written to it.
-+Go figure!
---- /dev/null
-+++ b/ext/http/tests/urls.txt
-@@ -0,0 +1,49 @@
-+http://www.microsoft.com
-+http://www.opensource.org
-+http://www.google.com
-+http://www.yahoo.com
-+http://www.ibm.com
-+http://www.mysql.com
-+http://www.oracle.com
-+http://www.ripe.net
-+http://www.iana.org
-+http://www.amazon.com
-+http://www.netcraft.com
-+http://www.heise.de
-+http://www.chip.de
-+http://www.ca.com
-+http://www.cnet.com
-+http://www.news.com
-+http://www.cnn.com
-+http://www.wikipedia.org
-+http://www.dell.com
-+http://www.hp.com
-+http://www.cert.org
-+http://www.mit.edu
-+http://www.nist.gov
-+http://www.ebay.com
-+http://www.playstation.com
-+http://www.uefa.com
-+http://www.ieee.org
-+http://www.apple.com
-+http://www.sony.com
-+http://www.symantec.com
-+http://www.zdnet.com
-+http://www.fujitsu.com
-+http://www.supermicro.com
-+http://www.hotmail.com
-+http://www.ecma.com
-+http://www.bbc.co.uk
-+http://news.google.com
-+http://www.foxnews.com
-+http://www.msn.com
-+http://www.wired.com
-+http://www.sky.com
-+http://www.usatoday.com
-+http://www.cbs.com
-+http://www.nbc.com
-+http://slashdot.org
-+http://www.bloglines.com
-+http://www.techweb.com
-+http://www.newslink.org
-+http://www.un.org
-\ No newline at end of file