X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=77b11348c0a0bfc484d3120de9dcb2b1a08ab12b;hp=f8f93e161b3364b772fcf0896bfc1f01382d0d34;hb=a88a9ab5ca6e1aa2d2510c7ff3dda58d528602e5;hpb=864a85259b0369033e49666603eed6661b01606c diff --git a/http_api.c b/http_api.c index f8f93e1..77b1134 100644 --- a/http_api.c +++ b/http_api.c @@ -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 | + | Copyright (c) 2004-2007, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -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; } @@ -584,6 +645,70 @@ failure: } /* }}} */ +/* {{{ array_join */ +int apply_array_append_func(void *pDest, 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) { + if (Z_TYPE_PP(data) != IS_ARRAY) { + convert_to_array(*data); + } + add_next_index_zval(*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, 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