X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http.c;h=76629d32265fe5733d33a73037c6d1923d98992a;hp=364710d5191e2f2d14bc8d85fe01d307a950ba8d;hb=refs%2Fheads%2Fv1.7.x;hpb=ed599c827d2e799b749b913cad2b9f05ab724375 diff --git a/http.c b/http.c index 364710d..76629d3 100644 --- a/http.c +++ b/http.c @@ -6,7 +6,7 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2007, Michael Wallner | + | Copyright (c) 2004-2010, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -14,6 +14,7 @@ #define HTTP_WANT_SAPI #define HTTP_WANT_CURL +#define HTTP_WANT_EVENT #define HTTP_WANT_ZLIB #define HTTP_WANT_MAGIC #include "php_http.h" @@ -23,45 +24,29 @@ #include "zend_extensions.h" #include "php_http_api.h" -#include "php_http_send_api.h" -#include "php_http_cookie_api.h" #include "php_http_cache_api.h" -#include "php_http_send_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" -#ifdef HTTP_HAVE_CURL -# include "php_http_request_api.h" -# include "php_http_request_pool_api.h" -# include "php_http_request_datashare_api.h" -# ifdef HTTP_HAVE_PERSISTENT_HANDLES -# include "php_http_persistent_handle_api.h" -# endif -#endif -#ifdef HTTP_HAVE_ZLIB -# include "php_http_encoding_api.h" -#endif +#include "php_http_request_pool_api.h" +#include "php_http_send_api.h" #include "php_http_url_api.h" -#ifdef ZEND_ENGINE_2 -# include "php_http_filter_api.h" -# include "php_http_util_object.h" -# include "php_http_message_object.h" -# include "php_http_querystring_object.h" -# ifndef WONKY -# include "php_http_response_object.h" -# endif -# ifdef HTTP_HAVE_CURL -# include "php_http_request_object.h" -# include "php_http_requestpool_object.h" -# include "php_http_requestdatashare_object.h" -# endif -# ifdef HTTP_HAVE_ZLIB -# include "php_http_deflatestream_object.h" -# include "php_http_inflatestream_object.h" -# endif -# include "php_http_exception_object.h" -#endif - +#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(); @@ -81,6 +66,7 @@ zend_function_entry http_functions[] = { 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) @@ -104,12 +90,10 @@ zend_function_entry http_functions[] = { PHP_FE(http_get_request_body, NULL) PHP_FE(http_get_request_body_stream, NULL) PHP_FE(http_match_request_header, NULL) -#ifdef HTTP_HAVE_CURL -# ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_FE(http_persistent_handles_count, NULL) PHP_FE(http_persistent_handles_clean, NULL) PHP_FE(http_persistent_handles_ident, NULL) -# endif +#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) @@ -158,6 +142,9 @@ static zend_module_dep http_module_deps[] = { # ifdef HTTP_HAVE_ICONV ZEND_MOD_REQUIRED("iconv") # endif +# ifdef HTTP_HAVE_EVENT + ZEND_MOD_CONFLICTS("event") +#endif {NULL, NULL, NULL, 0} }; #endif @@ -178,7 +165,7 @@ zend_module_entry http_module_entry = { PHP_RINIT(http), PHP_RSHUTDOWN(http), PHP_MINFO(http), - PHP_EXT_HTTP_VERSION, + PHP_HTTP_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -218,16 +205,26 @@ static inline void _http_globals_free(zend_http_globals *G TSRMLS_DC) 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 *, int) */ -#define http_check_allowed_methods(m, l) _http_check_allowed_methods((m), (l) TSRMLS_CC) -static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_DC) +/* {{{ 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 (length && SG(request_info).request_method) { + if (*methods && SG(request_info).request_method) { if (SUCCESS != http_check_method_ex(SG(request_info).request_method, methods)) { - char *header = emalloc(length + sizeof("Allow: ")); - sprintf(header, "Allow: %s", methods); + char *header; + spprintf(&header, 0, "Allow: %s", methods); http_exit(405, header); } } @@ -237,16 +234,16 @@ static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_ /* {{{ PHP_INI */ PHP_INI_MH(http_update_allowed_methods) { - http_check_allowed_methods(new_value, new_value_length); + 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); } -#ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_INI_MH(http_update_persistent_handle_ident) { - HTTP_G->persistent.handles.ident.h = zend_get_hash_value(new_value, HTTP_G->persistent.handles.ident.l = new_value_length+1); + 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); } -#endif #ifndef ZEND_ENGINE_2 # define OnUpdateLong OnUpdateInt @@ -260,7 +257,7 @@ PHP_INI_BEGIN() 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.ini) + 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) @@ -273,9 +270,8 @@ PHP_INI_BEGIN() 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 -#ifdef HTTP_HAVE_PERSISTENT_HANDLES + 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) -#endif 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) @@ -288,54 +284,50 @@ PHP_INI_END() PHP_MINIT_FUNCTION(http) { http_module_number = module_number; - - ZEND_INIT_MODULE_GLOBALS(http, http_globals_init_once, NULL) - + ZEND_INIT_MODULE_GLOBALS(http, http_globals_init_once, NULL); REGISTER_INI_ENTRIES(); - if ( (SUCCESS != PHP_MINIT_CALL(http_support)) || - (SUCCESS != PHP_MINIT_CALL(http_cookie)) || - (SUCCESS != PHP_MINIT_CALL(http_send)) || - (SUCCESS != PHP_MINIT_CALL(http_url)) || + 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 -# ifdef HTTP_HAVE_PERSISTENT_HANDLES - (SUCCESS != PHP_MINIT_CALL(http_persistent_handle)) || - (SUCCESS != PHP_MINIT_CALL(http_request_pool)) || -# endif - (SUCCESS != PHP_MINIT_CALL(http_request)) || + || SUCCESS != PHP_MINIT_CALL(http_request) # ifdef ZEND_ENGINE_2 - (SUCCESS != PHP_MINIT_CALL(http_request_datashare)) || # endif -#endif /* HTTP_HAVE_CURL */ -#ifdef HTTP_HAVE_ZLIB - (SUCCESS != PHP_MINIT_CALL(http_encoding)) || #endif - (SUCCESS != PHP_MINIT_CALL(http_request_method))) { - return FAILURE; - } - + || 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 - if ( (SUCCESS != PHP_MINIT_CALL(http_filter)) || - (SUCCESS != PHP_MINIT_CALL(http_util_object)) || - (SUCCESS != PHP_MINIT_CALL(http_message_object)) || - (SUCCESS != PHP_MINIT_CALL(http_querystring_object))|| -# ifndef WONKY - (SUCCESS != PHP_MINIT_CALL(http_response_object)) || -# endif /* WONKY */ -# ifdef HTTP_HAVE_CURL - (SUCCESS != PHP_MINIT_CALL(http_request_object)) || - (SUCCESS != PHP_MINIT_CALL(http_requestpool_object))|| - (SUCCESS != PHP_MINIT_CALL(http_requestdatashare_object))|| -# endif /* HTTP_HAVE_CURL */ + || 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 /* HTTP_HAVE_ZLIB */ - (SUCCESS != PHP_MINIT_CALL(http_exception_object))) { + || 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; } -#endif /* ZEND_ENGINE_2 */ - + return SUCCESS; } /* }}} */ @@ -344,19 +336,20 @@ PHP_MINIT_FUNCTION(http) PHP_MSHUTDOWN_FUNCTION(http) { UNREGISTER_INI_ENTRIES(); + + if (0 #ifdef HTTP_HAVE_CURL - if ( + || SUCCESS != PHP_MSHUTDOWN_CALL(http_request) # ifdef ZEND_ENGINE_2 - (SUCCESS != PHP_MSHUTDOWN_CALL(http_request_datashare)) || -# endif - (SUCCESS != PHP_MSHUTDOWN_CALL(http_request)) -# ifdef HTTP_HAVE_PERSISTENT_HANDLES - || (SUCCESS != PHP_MSHUTDOWN_CALL(http_persistent_handle)) + || 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; } -#endif + return SUCCESS; } /* }}} */ @@ -365,19 +358,24 @@ PHP_MSHUTDOWN_FUNCTION(http) PHP_RINIT_FUNCTION(http) { http_globals_init(HTTP_G); - - if (HTTP_G->request.methods.allowed) { - http_check_allowed_methods(HTTP_G->request.methods.allowed, - strlen(HTTP_G->request.methods.allowed)); + + if (HTTP_G->request.methods.allowed && *HTTP_G->request.methods.allowed) { + http_check_allowed_methods(HTTP_G->request.methods.allowed); } - - if ( (SUCCESS != PHP_RINIT_CALL(http_request_method)) -#ifdef HTTP_HAVE_ZLIB - || (SUCCESS != PHP_RINIT_CALL(http_encoding)) + + if (0 +#ifdef HTTP_HAVE_ZLIB + || SUCCESS != PHP_RINIT_CALL(http_encoding) #endif -#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) - || (SUCCESS != PHP_RINIT_CALL(http_request_datashare)) +#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; } @@ -391,14 +389,17 @@ PHP_RSHUTDOWN_FUNCTION(http) { STATUS status = SUCCESS; - if ( (SUCCESS != PHP_RSHUTDOWN_CALL(http_request_method)) + if (0 #ifdef HTTP_HAVE_ZLIB - || (SUCCESS != PHP_RSHUTDOWN_CALL(http_encoding)) + || SUCCESS != PHP_RSHUTDOWN_CALL(http_encoding) #endif -#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) - || (SUCCESS != PHP_RSHUTDOWN_CALL(http_request_datashare)) +#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; } @@ -412,8 +413,8 @@ PHP_MINFO_FUNCTION(http) { php_info_print_table_start(); { - php_info_print_table_row(2, "HTTP Support", "enabled"); - php_info_print_table_row(2, "Extension Version", PHP_EXT_HTTP_VERSION); + 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" @@ -443,46 +444,6 @@ PHP_MINFO_FUNCTION(http) "http.chunked_decode, http.chunked_encode, http.deflate, http.inflate" #endif ); -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - { - phpstr s; - HashTable *ht; - HashPosition pos1, pos2; - HashKey key1 = initHashKey(0), key2 = initHashKey(0); - zval **val1, **val2; - - if ((ht = http_persistent_handle_statall()) && zend_hash_num_elements(ht)) { - phpstr_init(&s); - - FOREACH_HASH_KEYVAL(pos1, ht, key1, val1) { - phpstr_append(&s, key1.str, key1.len-1); - phpstr_appends(&s, " ("); - if (zend_hash_num_elements(Z_ARRVAL_PP(val1))) { - FOREACH_KEYVAL(pos2, *val1, key2, val2) { - phpstr_append(&s, key2.str, key2.len-1); - phpstr_appendf(&s, ":%ld, ", Z_LVAL_PP(val2)); - } - PHPSTR_LEN(&s) -= 2; - } else { - phpstr_appends(&s, "0"); - } - phpstr_appends(&s, "), "); - } - zend_hash_destroy(ht); - FREE_HASHTABLE(ht); - - PHPSTR_LEN(&s) -= 2; /* get rid of last ", " */ - phpstr_fix(&s); - - php_info_print_table_row(2, "Persistent Handles", PHPSTR_VAL(&s)); - phpstr_dtor(&s); - } else { - php_info_print_table_row(2, "Persistent Handles", "none"); - } - } -#else - php_info_print_table_row(2, "Persistent Handles", "disabled"); -#endif } php_info_print_table_end(); @@ -495,6 +456,11 @@ PHP_MINFO_FUNCTION(http) #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 @@ -509,33 +475,62 @@ PHP_MINFO_FUNCTION(http) php_info_print_table_end(); php_info_print_table_start(); - php_info_print_table_colspan_header(2, "Request Methods"); + php_info_print_table_colspan_header(4, "Persistent Handles"); + php_info_print_table_header(4, "Provider", "Ident", "Used", "Free"); { - int i; - phpstr *custom_request_methods = phpstr_new(); - phpstr *known_request_methods = phpstr_from_string(HTTP_KNOWN_METHODS, lenof(HTTP_KNOWN_METHODS)); - http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries; - - for (i = 0; i < HTTP_G->request.methods.custom.count; ++i) { - if (ptr[i]) { - phpstr_appendf(custom_request_methods, "%s, ", ptr[i]->name); + 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"); } - - phpstr_append(known_request_methods, PHPSTR_VAL(custom_request_methods), PHPSTR_LEN(custom_request_methods)); - phpstr_fix(known_request_methods); - phpstr_fix(custom_request_methods); - - php_info_print_table_row(2, "Known", PHPSTR_VAL(known_request_methods)); - php_info_print_table_row(2, "Custom", - PHPSTR_LEN(custom_request_methods) ? PHPSTR_VAL(custom_request_methods) : "none registered"); - php_info_print_table_row(2, "Allowed", strlen(HTTP_G->request.methods.allowed) ? HTTP_G->request.methods.allowed : "(ANY)"); + 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; - phpstr_free(&known_request_methods); - phpstr_free(&custom_request_methods); + 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(); } /* }}} */