PHP-5.3 zend_hash API compatibility fix
[m6w6/ext-http] / http_api.c
index b77dd19b182c7fe02f1433fdeabd5a1d89c98066..b54da54d2f0149395760dfa5746bcb2f989c9cff 100644 (file)
@@ -6,7 +6,7 @@
     | modification, are permitted provided that the conditions mentioned |
     | in the accompanying LICENSE file are met.                          |
     +--------------------------------------------------------------------+
-    | Copyright (c) 2004-2006, Michael Wallner <mike@php.net>            |
+    | Copyright (c) 2004-2007, Michael Wallner <mike@php.net>            |
     +--------------------------------------------------------------------+
 */
 
@@ -17,6 +17,7 @@
 
 #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"
@@ -32,6 +33,7 @@ PHP_MINIT_FUNCTION(http_support)
        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);
@@ -50,6 +52,9 @@ PHP_HTTP_API long _http_support(long feature)
 #      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;
@@ -90,6 +95,13 @@ char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool x
 }
 /* }}} */
 
+/* {{{ 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, ...)
 {
@@ -97,7 +109,7 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...)
        
        va_start(args, format);
 #ifdef ZEND_ENGINE_2
-       if ((type == E_THROW) || (PG(error_handling) == EH_THROW)) {
+       if ((type == E_THROW) || (GLOBAL_ERROR_HANDLING == EH_THROW)) {
                char *message;
                zend_class_entry *ce = http_exception_get_for_code(code);
                
@@ -105,7 +117,7 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...)
                        vspprintf(&message, 0, format, args);
                        zend_throw_exception(ce, message, code TSRMLS_CC);
                        efree(message);
-               } http_catch(PG(exception_class) ? PG(exception_class) : HTTP_EX_DEF_CE);
+               } http_catch(GLOBAL_EXCEPTION_CLASS ? GLOBAL_EXCEPTION_CLASS : HTTP_EX_DEF_CE);
        } else
 #endif
        php_verror(NULL, "", type, format, args TSRMLS_CC);
@@ -173,6 +185,26 @@ zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_
        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 *) */
@@ -265,17 +297,32 @@ STATUS _http_check_method_ex(const char *method, const char *methods)
 /* }}} */
 
 /* {{{ zval *http_get_server_var_ex(char *, size_t) */
-PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC)
+PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_len, zend_bool check TSRMLS_DC)
 {
-       zval **hsv;
-       zval **var;
+       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), (char *) key, key_size, (void *) &var))) {
+       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))) {
@@ -376,9 +423,13 @@ PHP_HTTP_API void _http_parse_params_default_callback(void *arg, const char *key
                if (vallen) {
                        MAKE_STD_ZVAL(entry);
                        array_init(entry);
-                       kdup = estrndup(key, keylen);
-                       add_assoc_stringl_ex(entry, kdup, keylen + 1, (char *) val, vallen, 1);
-                       efree(kdup);
+                       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);
@@ -400,7 +451,9 @@ PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_par
        char *s, *c, *key = NULL, *val = NULL;
        
        for(c = s = estrdup(param);;) {
+       continued:
 #if 0
+       {
                char *tk = NULL, *tv = NULL;
                
                if (key) {
@@ -432,8 +485,8 @@ PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_par
                                ), *c?*c:'0', tk, tv
                );
                STR_FREE(tk); STR_FREE(tv);
+       }
 #endif
-       continued:
                switch (st) {
                        case ST_QUOTE:
                        quote:
@@ -575,7 +628,15 @@ failure:
                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) {
-               --c;
+               if (st == ST_KEY) {
+                       if (key) {
+                               keylen = c - key;
+                       } else {
+                               key = c;
+                       }
+               } else {
+                       --c;
+               }
                st = ST_ADD;
                goto continued;
        }
@@ -585,7 +646,7 @@ failure:
 /* }}} */
 
 /* {{{ array_join */
-int apply_array_append_func(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
+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;
@@ -623,7 +684,7 @@ int apply_array_append_func(void *pDest, int num_args, va_list args, zend_hash_k
        return ZEND_HASH_APPLY_KEEP;
 }
 
-int apply_array_merge_func(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
+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;