From: Michael Wallner Date: Thu, 12 Mar 2015 08:30:46 +0000 (+0100) Subject: Merge branch 'master' into phpng X-Git-Tag: RELEASE_3_0_0_RC1~54 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=e438aa9ce944f8c8f175554d9aa66d152a47f780;hp=0918074fdd8dc347370e8298bd13ba4c78224ba8 Merge branch 'master' into phpng --- diff --git a/config.w32 b/config.w32 index b84101f..13c24ab 100644 --- a/config.w32 +++ b/config.w32 @@ -53,8 +53,7 @@ if (PHP_HTTP != "no") { "php_http_env_response.c php_http_etag.c php_http_exception.c php_http_filter.c php_http_header_parser.c " + "php_http_header.c php_http_info.c php_http_message.c php_http_message_body.c php_http_message_parser.c " + "php_http_misc.c php_http_negotiate.c php_http_object.c php_http_options.c php_http_params.c " + - "php_http_querystring.c " + - "php_http_strlist.c php_http_url.c php_http_version.c", + "php_http_querystring.c php_http_url.c php_http_version.c", null, null); AC_DEFINE("HAVE_HTTP", 1, "Have extended HTTP support"); diff --git a/config9.m4 b/config9.m4 index 8a10118..bd5ba2f 100644 --- a/config9.m4 +++ b/config9.m4 @@ -122,6 +122,11 @@ dnl ---- done if test "x$IDNA_DIR" = "x"; then AC_MSG_RESULT([not found]) + case $host_os in + darwin*) + AC_CHECK_HEADERS(unicode/uidna.h) + PHP_CHECK_FUNC(uidna_IDNToASCII, icucore);; + esac else AC_MSG_RESULT([found in $IDNA_DIR]) AC_DEFINE([PHP_HTTP_HAVE_IDN], [1], [Have libidn support]) @@ -505,12 +510,6 @@ dnl ---- fi ]) -dnl ---- -dnl JSON -dnl ---- - HTTP_HAVE_PHP_EXT([json]) - - dnl ---- dnl ICONV dnl ---- @@ -555,11 +554,10 @@ dnl ---- dnl shared extension deps HTTP_SHARED_DEP([hash]) HTTP_SHARED_DEP([iconv]) - HTTP_SHARED_DEP([json]) dnl extension deps PHP_ADD_EXTENSION_DEP([http], [raphf], true) - PHP_ADD_EXTENSION_DEP([http], [propo], true) + PHP_ADD_EXTENSION_DEP([http], [propro], true) PHP_SUBST([HTTP_SHARED_LIBADD]) diff --git a/php_http.c b/php_http.c index 98df843..d430e1f 100644 --- a/php_http.c +++ b/php_http.c @@ -44,7 +44,6 @@ zend_function_entry http_functions[] = { PHP_MINIT_FUNCTION(http); PHP_MSHUTDOWN_FUNCTION(http); -PHP_RINIT_FUNCTION(http); PHP_RSHUTDOWN_FUNCTION(http); PHP_MINFO_FUNCTION(http); @@ -57,9 +56,6 @@ static zend_module_dep http_module_deps[] = { #endif #ifdef PHP_HTTP_HAVE_ICONV ZEND_MOD_REQUIRED("iconv") -#endif -#ifdef PHP_HTTP_HAVE_JSON - ZEND_MOD_REQUIRED("json") #endif {NULL, NULL, NULL, 0} }; @@ -72,7 +68,7 @@ zend_module_entry http_module_entry = { http_functions, PHP_MINIT(http), PHP_MSHUTDOWN(http), - PHP_RINIT(http), + NULL, PHP_RSHUTDOWN(http), PHP_MINFO(http), PHP_PECL_HTTP_VERSION, @@ -178,17 +174,6 @@ PHP_MSHUTDOWN_FUNCTION(http) return SUCCESS; } -PHP_RINIT_FUNCTION(http) -{ - if (0 - || SUCCESS != PHP_RINIT_CALL(http_env) - ) { - return FAILURE; - } - - return SUCCESS; -} - PHP_RSHUTDOWN_FUNCTION(http) { if (0 diff --git a/php_http_api.h b/php_http_api.h index 68fdac8..2313413 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -49,9 +49,7 @@ # define PHP_HTTP_HAVE_HASH #endif -#if (defined(HAVE_JSON) || defined(PHP_HTTP_HAVE_EXT_JSON)) && (PHP_HTTP_SHARED_DEPS || !defined(COMPILE_DL_JSON)) -# define PHP_HTTP_HAVE_JSON -#endif +#include #ifdef PHP_WIN32 # define CURL_STATICLIB diff --git a/php_http_env.c b/php_http_env.c index 0ede201..f5c72d6 100644 --- a/php_http_env.c +++ b/php_http_env.c @@ -13,60 +13,6 @@ #include "php_http_api.h" #include "php_variables.h" -PHP_RINIT_FUNCTION(http_env) -{ - /* populate form data on non-POST requests */ - if (SG(request_info).request_method && strcasecmp(SG(request_info).request_method, "POST") && SG(request_info).content_type && *SG(request_info).content_type) { - uint ct_len = strlen(SG(request_info).content_type); - char *ct_str = estrndup(SG(request_info).content_type, ct_len); - php_http_params_opts_t opts; - HashTable params; - - php_http_params_opts_default_get(&opts); - opts.input.str = ct_str; - opts.input.len = ct_len; - - SG(request_info).content_type_dup = ct_str; - - ZEND_INIT_SYMTABLE(¶ms); - if (php_http_params_parse(¶ms, &opts)) { - zend_string *key_str; - zend_ulong key_num; - - if (HASH_KEY_IS_STRING == zend_hash_get_current_key(¶ms, &key_str, &key_num)) { - sapi_post_entry *post_entry = NULL; - - if ((post_entry = zend_hash_find_ptr(&SG(known_post_content_types), key_str))) { - SG(request_info).post_entry = post_entry; - - if (post_entry->post_reader) { - post_entry->post_reader(); - } - - if (sapi_module.default_post_reader) { - sapi_module.default_post_reader(); - } - - sapi_handle_post(&PG(http_globals)[TRACK_VARS_POST]); - - /* - * the rfc1867 handler is an awkward buddy - * FIXME: this leaks because php_auto_globals_create_files() - * as well as the rfc1867_handler call - * array_init(&PG(http_globals)[TRACK_VARS_FILES]) - */ - Z_TRY_ADDREF(PG(http_globals)[TRACK_VARS_FILES]); - zend_hash_str_update(&EG(symbol_table), "_FILES", lenof("_FILES"), &PG(http_globals)[TRACK_VARS_FILES]); - } - } - zend_hash_destroy(¶ms); - } - } - - PTR_SET(SG(request_info).content_type_dup, NULL); - - return SUCCESS; -} PHP_RSHUTDOWN_FUNCTION(http_env) { @@ -485,6 +431,7 @@ ZEND_RESULT_CODE php_http_env_set_response_header(long http_code, const char *he { sapi_header_line h = {estrndup(header_str, header_len), header_len, http_code}; ZEND_RESULT_CODE ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, (void *) &h); + efree(h.line); return ret; } @@ -848,53 +795,6 @@ static zend_function_entry php_http_env_methods[] = { EMPTY_FUNCTION_ENTRY }; -#ifdef PHP_HTTP_HAVE_JSON -#include "ext/json/php_json.h" - -static SAPI_POST_HANDLER_FUNC(php_http_json_post_handler) -{ - zval *zarg = arg; - zend_string *json = NULL; - - if (SG(request_info).request_body) { - /* FG(stream_wrappers) not initialized yet, so we cannot use php://input */ - php_stream_rewind(SG(request_info).request_body); - json = php_stream_copy_to_mem(SG(request_info).request_body, PHP_STREAM_COPY_ALL, 0); - } - - if (json) { - if (json->len) { - zval tmp; - - ZVAL_NULL(&tmp); - php_json_decode(&tmp, json->val, json->len, 1, PG(max_input_nesting_level)); - - if (Z_TYPE(tmp) == IS_ARRAY) { - array_copy(Z_ARRVAL(tmp), Z_ARRVAL_P(zarg)); - } - zval_ptr_dtor(&tmp); - } - zend_string_release(json); - } -} - -static void php_http_env_register_json_handler(void) -{ - sapi_post_entry entry = {NULL, 0, NULL, NULL}; - - entry.post_reader = sapi_read_standard_form_data; - entry.post_handler = php_http_json_post_handler; - - entry.content_type = "text/json"; - entry.content_type_len = lenof("text/json"); - sapi_register_post_entry(&entry); - - entry.content_type = "application/json"; - entry.content_type_len = lenof("application/json"); - sapi_register_post_entry(&entry); -} -#endif - zend_class_entry *php_http_env_class_entry; PHP_MINIT_FUNCTION(http_env) @@ -904,10 +804,6 @@ PHP_MINIT_FUNCTION(http_env) INIT_NS_CLASS_ENTRY(ce, "http", "Env", php_http_env_methods); php_http_env_class_entry = zend_register_internal_class(&ce); -#ifdef PHP_HTTP_HAVE_JSON - php_http_env_register_json_handler(); -#endif - return SUCCESS; } diff --git a/php_http_env.h b/php_http_env.h index 1cb302d..273ba16 100644 --- a/php_http_env.h +++ b/php_http_env.h @@ -75,9 +75,9 @@ static inline zend_bool php_http_env_got_server_var(const char *v) return NULL != php_http_env_get_server_var(v, strlen(v), 1); } + PHP_HTTP_API zend_class_entry *php_http_env_class_entry; PHP_MINIT_FUNCTION(http_env); -PHP_RINIT_FUNCTION(http_env); PHP_RSHUTDOWN_FUNCTION(http_env); #endif diff --git a/php_http_header_parser.c b/php_http_header_parser.c index cf30c84..f4dcf95 100644 --- a/php_http_header_parser.c +++ b/php_http_header_parser.c @@ -284,7 +284,7 @@ php_http_header_parser_state_t php_http_header_parser_parse(php_http_header_pars php_http_header_parser_state_t php_http_header_parser_parse_stream(php_http_header_parser_t *parser, php_http_buffer_t *buf, php_stream *s, unsigned flags, HashTable *headers, php_http_info_callback_t callback_func, void *callback_arg) { - php_http_message_parser_state_t state = PHP_HTTP_MESSAGE_PARSER_STATE_START; + php_http_header_parser_state_t state = PHP_HTTP_HEADER_PARSER_STATE_START; TSRMLS_FETCH_FROM_CTX(parser->ts); if (!buf->data) { diff --git a/php_http_querystring.c b/php_http_querystring.c index bd04f50..83ce01b 100644 --- a/php_http_querystring.c +++ b/php_http_querystring.c @@ -592,16 +592,21 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, offsetSet) { zend_string *offset; - zval *value, param; + zval *value, param, znull; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sz", &offset, &value)) { return; } - array_init(¶m); + array_init_size(¶m, 1); + /* unset first */ + ZVAL_NULL(&znull); + zend_symtable_update(Z_ARRVAL(param), offset, &znull); + php_http_querystring_set(getThis(), ¶m, QS_MERGE); + /* then update, else QS_MERGE would merge sub-arrrays */ Z_TRY_ADDREF_P(value); zend_symtable_update(Z_ARRVAL(param), offset, value); - php_http_querystring_set(getThis(), ¶m, 0); + php_http_querystring_set(getThis(), ¶m, QS_MERGE); zval_ptr_dtor(¶m); } diff --git a/php_http_url.c b/php_http_url.c index 6c70bc3..5a267d8 100644 --- a/php_http_url.c +++ b/php_http_url.c @@ -673,8 +673,9 @@ static size_t parse_mb_loc(unsigned *wc, const char *ptr, const char *end) wchar_t wchar; size_t consumed = 0; #if defined(HAVE_MBRTOWC) - mbstate_t ps = {0}; + mbstate_t ps; + memset(&ps, 0, sizeof(ps)); consumed = mbrtowc(&wchar, ptr, end - ptr, &ps); #elif defined(HAVE_MBTOWC) consumed = mbtowc(&wchar, ptr, end - ptr); @@ -756,9 +757,15 @@ static size_t parse_mb(struct parse_state *state, parse_mb_what_t what, const ch } if (!silent) { - php_error_docref(NULL, E_WARNING, - "Failed to parse %s; unexpected byte 0x%02x at pos %u in '%s'", - parse_what[what], (unsigned char) *ptr, (unsigned) (ptr - begin), begin); + if (consumed) { + php_error_docref(NULL, E_WARNING, + "Failed to parse %s; unexpected multibyte sequence 0x%x at pos %u in '%s'", + parse_what[what], wchar, (unsigned) (ptr - begin), begin); + } else { + php_error_docref(NULL, E_WARNING, + "Failed to parse %s; unexpected byte 0x%02x at pos %u in '%s'", + parse_what[what], (unsigned char) *ptr, (unsigned) (ptr - begin), begin); + } } return 0; @@ -828,12 +835,176 @@ static ZEND_RESULT_CODE parse_userinfo(struct parse_state *state, const char *pt return SUCCESS; } +#if defined(PHP_WIN32) || defined(HAVE_UIDNA_IDNTOASCII) +typedef size_t (*parse_mb_func)(unsigned *wc, const char *ptr, const char *end); +static ZEND_RESULT_CODE to_utf16(parse_mb_func fn, const char *u8, uint16_t **u16, size_t *len) +{ + size_t offset = 0, u8_len = strlen(u8); + + *u16 = ecalloc(4 * sizeof(uint16_t), u8_len + 1); + *len = 0; + + while (offset < u8_len) { + unsigned wc; + uint16_t buf[2], *ptr = buf; + size_t consumed = fn(&wc, &u8[offset], &u8[u8_len]); + + if (!consumed) { + efree(*u16); + php_error_docref(NULL, E_WARNING, "Failed to parse UTF-8 at pos %zu of '%s'", offset, u8); + return FAILURE; + } else { + offset += consumed; + } + + switch (wctoutf16(buf, wc)) { + case 2: + (*u16)[(*len)++] = *ptr++; + /* no break */ + case 1: + (*u16)[(*len)++] = *ptr++; + break; + case 0: + default: + efree(*u16); + php_error_docref(NULL, E_WARNING, "Failed to convert UTF-32 'U+%X' to UTF-16", wc); + return FAILURE; + } + } + + return SUCCESS; +} +#endif + +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +#ifdef PHP_HTTP_HAVE_IDN +static ZEND_RESULT_CODE parse_idn(struct parse_state *state, size_t prev_len) +{ + char *idn = NULL; + int rv = -1; + + if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { + rv = idna_to_ascii_8z(state->url.host, &idn, IDNA_ALLOW_UNASSIGNED|IDNA_USE_STD3_ASCII_RULES); + } +# ifdef PHP_HTTP_HAVE_WCHAR + else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { + rv = idna_to_ascii_lz(state->url.host, &idn, IDNA_ALLOW_UNASSIGNED|IDNA_USE_STD3_ASCII_RULES); + } +# endif + if (rv != IDNA_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; %s", idna_strerror(rv)); + return FAILURE; + } else { + size_t idnlen = strlen(idn); + memcpy(state->url.host, idn, idnlen + 1); + free(idn); + state->offset += idnlen - prev_len; + return SUCCESS; + } +} +#endif + +#ifdef HAVE_UIDNA_IDNTOASCII +# if HAVE_UNICODE_UIDNA_H +# include +# else +typedef uint16_t UChar; +typedef enum { U_ZERO_ERROR = 0 } UErrorCode; +int32_t uidna_IDNToASCII(const UChar *src, int32_t srcLength, UChar *dest, int32_t destCapacity, int32_t options, void *parseError, UErrorCode *status); +# endif +static ZEND_RESULT_CODE parse_uidn(struct parse_state *state) +{ + char *host_ptr; + uint16_t *uhost_str, ahost_str[MAXHOSTNAMELEN], *ahost_ptr; + size_t uhost_len, ahost_len; + UErrorCode error = U_ZERO_ERROR; + TSRMLS_FETCH_FROM_CTX(state->ts); + + if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { + if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len)) { + return FAILURE; + } +#ifdef PHP_HTTP_HAVE_WCHAR + } else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { + if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len)) { + return FAILURE; + } +#endif + } else { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; codepage not specified"); + return FAILURE; + } + + ahost_len = uidna_IDNToASCII(uhost_str, uhost_len, ahost_str, MAXHOSTNAMELEN, 3, NULL, &error); + efree(uhost_str); + + if (error != U_ZERO_ERROR) { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; ICU error %d", error); + return FAILURE; + } + + host_ptr = state->url.host; + ahost_ptr = ahost_str; + PHP_HTTP_DUFF(ahost_len, *host_ptr++ = *ahost_ptr++); + + *host_ptr = '\0'; + state->offset += host_ptr - state->url.host; + + return SUCCESS; +} +#endif + +#if 0 && defined(PHP_WIN32) +static ZEND_RESULT_CODE parse_widn(struct parse_state *state) +{ + char *host_ptr; + uint16_t *uhost_str, ahost_str[MAXHOSTNAMELEN], *ahost_ptr; + size_t uhost_len; + + if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { + if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len)) { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); + return FAILURE; + } +#ifdef PHP_HTTP_HAVE_WCHAR + } else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { + if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len)) { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); + return FAILURE; + } +#endif + } else { + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); + return FAILURE; + } + + if (!IdnToAscii(IDN_ALLOW_UNASSIGNED|IDN_USE_STD3_ASCII_RULES, uhost_str, uhost_len, ahost_str, MAXHOSTNAMELEN)) { + efree(uhost_str); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); + return FAILURE; + } + + efree(uhost_str); + host_ptr = state->url.host; + ahost_ptr = ahost_str; + PHP_HTTP_DUFF(wcslen(ahost_str), *host_ptr++ = *ahost_ptr++); + efree(ahost_str); + + *host_ptr = '\0'; + state->offset += host_ptr - state->url.host; + + return SUCCESS; +} +#endif + static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *ptr) { size_t mb, len; const char *end = state->ptr, *tmp = ptr, *port = NULL; - #ifdef HAVE_INET_PTON if (*ptr == '[') { char *error = NULL, *tmp = memchr(ptr, ']', end - ptr); @@ -941,30 +1112,17 @@ static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *pt state->buffer[state->offset++] = 0; } -#ifdef PHP_HTTP_HAVE_IDN if (state->flags & PHP_HTTP_URL_PARSE_TOIDN) { - char *idn = NULL; - int rv = -1; - - if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { - rv = idna_to_ascii_8z(state->url.host, &idn, IDNA_ALLOW_UNASSIGNED|IDNA_USE_STD3_ASCII_RULES); - } -# ifdef PHP_HTTP_HAVE_WCHAR - else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { - rv = idna_to_ascii_lz(state->url.host, &idn, IDNA_ALLOW_UNASSIGNED|IDNA_USE_STD3_ASCII_RULES); - } -# endif - if (rv != IDNA_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to parse IDN; %s", idna_strerror(rv)); - return FAILURE; - } else { - size_t idnlen = strlen(idn); - memcpy(state->url.host, idn, idnlen + 1); - free(idn); - state->offset += idnlen - len; - } - } +#ifdef PHP_HTTP_HAVE_IDN + return parse_idn(state, len); +#endif +#ifdef HAVE_UIDNA_IDNTOASCII + return parse_uidn(state); #endif +#if 0 && defined(PHP_WIN32) + return parse_widn(state); +#endif + } return SUCCESS; } @@ -1498,7 +1656,7 @@ PHP_MINIT_FUNCTION(http_url) zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBLOC"), PHP_HTTP_URL_PARSE_MBLOC); #endif zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBUTF8"), PHP_HTTP_URL_PARSE_MBUTF8); -#ifdef PHP_HTTP_HAVE_IDN +#if defined(PHP_HTTP_HAVE_IDN) || defined(HAVE_UIDNA_IDNTOASCII) zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOIDN"), PHP_HTTP_URL_PARSE_TOIDN); #endif zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOPCT"), PHP_HTTP_URL_PARSE_TOPCT); diff --git a/php_http_utf8.h b/php_http_utf8.h index 2503f06..f900803 100644 --- a/php_http_utf8.h +++ b/php_http_utf8.h @@ -625,6 +625,39 @@ static inline zend_bool isualnum(unsigned ch) return isualpha(ch); } +static inline size_t wctoutf16(unsigned short u16[2], unsigned wc) +{ + if (wc > 0x10ffff || (wc >= 0xd800 && wc <= 0xdfff)) { + return 0; + } + + if (wc <= 0xffff) { + u16[0] = (unsigned short) wc; + return 1; + } + + wc -= 0x10000; + u16[0] = (unsigned short) ((wc >> 10) + 0xd800); + u16[1] = (unsigned short) ((wc & 0x3ff) + 0xdc00); + return 2; +} + +static inline size_t utf16towc(unsigned *wc, unsigned short *u16_str, size_t u16_len) +{ + if (u16_len < 1) { + return 0; + } + if (u16_str[0] - 0xd800 >= 0x800) { + *wc = u16_str[0]; + return 1; + } + if (u16_len < 2 || (u16_str[0] & 0xfffffc00) != 0xd800 || (u16_str[1] & 0xfffffc00) != 0xdc00) { + return 0; + } + *wc = (u16_str[0] << 10) + u16_str[1] - 0x35fdc00; + return 2; +} + #endif /* PHP_HTTP_UTF8_H */ /* diff --git a/tests/bug66388.phpt b/tests/bug66388.phpt index 9f9c95e..e4cbf2a 100644 --- a/tests/bug66388.phpt +++ b/tests/bug66388.phpt @@ -27,7 +27,7 @@ echo $client->send()->getResponse()->getResponseCode(); ?> ===DONE=== ---EXPECT-- +--EXPECTF-- Test -401 +40%d ===DONE=== diff --git a/tests/bug66891.phpt b/tests/bug66891.phpt index 0fd84f8..30f9d7e 100644 --- a/tests/bug66891.phpt +++ b/tests/bug66891.phpt @@ -12,7 +12,7 @@ header("WWW-Authenticate: none"); $r = new http\Env\Response; $r->setResponseCode(200); $r->send(); -var_dump(http_response_code()); +var_dump(http\Env::getResponseCode()); ?> --EXPECT-- int(200) \ No newline at end of file diff --git a/tests/client003.phpt b/tests/client003.phpt index a6b1a4c..bca3302 100644 --- a/tests/client003.phpt +++ b/tests/client003.phpt @@ -3,6 +3,7 @@ client once & wait --SKIPIF-- --FILE-- diff --git a/tests/client008.phpt b/tests/client008.phpt index f8b8774..98fc8f8 100644 --- a/tests/client008.phpt +++ b/tests/client008.phpt @@ -18,7 +18,7 @@ server("pipeline.inc", function($port, $stdin) { $request = new http\Client\Request("GET", "http://localhost:$port"); $client = new http\Client(); - $client->configure(["pipelining" => true, "use_eventloop" => true]); + $client->configure(array("pipelining" => true, "use_eventloop" => true)); $client->enqueue($request); $client->send(); diff --git a/tests/client015.phpt b/tests/client015.phpt index 70b5f43..f378653 100644 --- a/tests/client015.phpt +++ b/tests/client015.phpt @@ -16,8 +16,8 @@ server("proxy.inc", function($port) { $client1 = new http\Client; $client2 = new http\Client; - $client1->configure(["use_eventloop" => true]); - $client2->configure(["use_eventloop" => true]); + $client1->configure(array("use_eventloop" => true)); + $client2->configure(array("use_eventloop" => true)); $client1->enqueue(new http\Client\Request("GET", "http://localhost:$port/")); $client2->enqueue(new http\Client\Request("GET", "http://localhost:$port/")); diff --git a/tests/client016.phpt b/tests/client016.phpt index 58f97c1..d2aef07 100644 --- a/tests/client016.phpt +++ b/tests/client016.phpt @@ -17,7 +17,7 @@ server("proxy.inc", function($port) { foreach (http\Client::getAvailableDrivers() as $driver) { $client = new http\Client($driver); - $client->configure(["use_eventloop" => true]); + $client->configure(array("use_eventloop" => true)); $client->enqueue($request); while ($client->once()) { diff --git a/tests/client017.phpt b/tests/client017.phpt index ea54146..a505028 100644 --- a/tests/client017.phpt +++ b/tests/client017.phpt @@ -12,7 +12,7 @@ skip_client_test(); echo "Test\n"; $client = new http\Client; -$client->setOptions(["compress" => true]); +$client->setOptions(array("compress" => true)); $client->enqueue(new http\Client\Request("GET", "http://dev.iworks.at/ext-http/.print_request.php")); $client->send(); diff --git a/tests/client018.phpt b/tests/client018.phpt index 7acb911..c3ca9f9 100644 --- a/tests/client018.phpt +++ b/tests/client018.phpt @@ -17,7 +17,7 @@ server("pipeline.inc", function($port, $stdin, $stdout, $stderr) { fputs($stdin, "3\n"); $client = new http\Client(null); - $client->configure(["pipelining" => true, "max_host_connections" => 0]); + $client->configure(array("pipelining" => true, "max_host_connections" => 0)); /* this is just to let curl know the server may be capable of pipelining */ $client->enqueue(new http\Client\Request("GET", "http://localhost:$port")); diff --git a/tests/client019.phpt b/tests/client019.phpt index e60e5aa..c41a260 100644 --- a/tests/client019.phpt +++ b/tests/client019.phpt @@ -4,6 +4,9 @@ client proxy - send proxy headers for a proxy request getAvailableOptions()) + or die("skip need libcurl with CUTLOPT_PROXYHEADER support\n"); ?> --FILE-- setOptions(["cookiestore" => $tmpfile]); +$request->setOptions(array("cookiestore" => $tmpfile)); server("cookie.inc", function($port) use($request) { - $request->setOptions(["port" => $port]); + $request->setOptions(array("port" => $port)); $client = new http\Client; echo $client->requeue($request)->send()->getResponse(); echo $client->requeue($request)->send()->getResponse(); @@ -25,7 +25,7 @@ server("cookie.inc", function($port) use($request) { }); server("cookie.inc", function($port) use($request) { - $request->setOptions(["port" => $port]); + $request->setOptions(array("port" => $port)); $client = new http\Client; echo $client->requeue($request)->send()->getResponse(); echo $client->requeue($request)->send()->getResponse(); @@ -33,7 +33,7 @@ server("cookie.inc", function($port) use($request) { }); server("cookie.inc", function($port) use($request) { - $request->setOptions(["port" => $port, "cookiesession" => true]); + $request->setOptions(array("port" => $port, "cookiesession" => true)); $client = new http\Client; echo $client->requeue($request)->send()->getResponse(); echo $client->requeue($request)->send()->getResponse(); @@ -41,7 +41,7 @@ server("cookie.inc", function($port) use($request) { }); server("cookie.inc", function($port) use($request) { - $request->setOptions(["port" => $port, "cookiesession" => false]); + $request->setOptions(array("port" => $port, "cookiesession" => false)); $client = new http\Client; echo $client->requeue($request)->send()->getResponse(); echo $client->requeue($request)->send()->getResponse(); diff --git a/tests/client023.phpt b/tests/client023.phpt index b09c2e2..77ea7ce 100644 --- a/tests/client023.phpt +++ b/tests/client023.phpt @@ -22,11 +22,11 @@ foreach ($avail as $k => $v) { $oo = $opt[$k]; foreach ($v as $kk => $vv) { if (isset($vv) && $oo[$kk] !== $vv) { - var_dump([$kk => [$vv, $oo[$kk]]]); + var_dump(array($kk => array($vv, $oo[$kk]))); } } } else if (isset($v) && $opt[$k] !== $v) { - var_dump([$k => [$v, $opt[$k]]]); + var_dump(array($k => array($v, $opt[$k]))); } } var_dump($client === $client->configure($client->getAvailableConfiguration())); diff --git a/tests/client025.phpt b/tests/client025.phpt index 18c5095..3c4793e 100644 --- a/tests/client025.phpt +++ b/tests/client025.phpt @@ -14,11 +14,11 @@ echo "Test\n"; server("proxy.inc", function($port) { $client = new http\Client; $request = new http\Client\Request("PUT", "http://localhost:$port"); - $request->setOptions(["resume" => 1, "expect_100_timeout" => 0]); + $request->setOptions(array("resume" => 1, "expect_100_timeout" => 0)); $request->getBody()->append("123"); echo $client->enqueue($request)->send()->getResponse(); }); - +// Content-length is 2 instead of 3 in older libcurls ?> ===DONE=== --EXPECTF-- @@ -34,8 +34,8 @@ Content-Range: bytes 1-2/3 User-Agent: %s Host: localhost:%d Accept: */* -Content-Length: 3 +Content-Length: %d Expect: 100-continue -X-Original-Content-Length: 3 +X-Original-Content-Length: %d 23===DONE=== diff --git a/tests/client026.phpt b/tests/client026.phpt index d89e98e..1bafdc1 100644 --- a/tests/client026.phpt +++ b/tests/client026.phpt @@ -19,7 +19,7 @@ server("proxy.inc", function($port) { for ($i = 0, $data = str_repeat("a",1024); $i < 128*1024; ++$i) { $request->getBody()->append($data); } - $request->setOptions(["timeout" => 10, "expect_100_timeout" => 0]); + $request->setOptions(array("timeout" => 10, "expect_100_timeout" => 0)); $client->enqueue($request); $client->send(); var_dump($client->getResponse()->getHeaders()); diff --git a/tests/envrequestbody002.phpt b/tests/envrequestbody002.phpt deleted file mode 100644 index 69c5988..0000000 --- a/tests/envrequestbody002.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -env request body ---SKIPIF-- - ---PUT-- -Content-Type: application/x-www-form-urlencoded -foo=bar&baz=buh ---FILE-- - -DONE ---EXPECT-- -array(2) { - ["foo"]=> - string(3) "bar" - ["baz"]=> - string(3) "buh" -} -DONE diff --git a/tests/envrequestbody003.phpt b/tests/envrequestbody003.phpt deleted file mode 100644 index c2bde83..0000000 --- a/tests/envrequestbody003.phpt +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -env request body ---SKIPIF-- - ---PUT-- -Content-Type: multipart/form-data;boundary=123 ---123 -Content-Disposition: form-data; name="foo" - -bar ---123 -Content-Disposition: form-data; name="baz" - -buh ---123 -Content-Disposition: form-data; name="up"; filename="up.txt" - -foo=bar&baz=buh ---123-- ---FILE-- - -DONE ---EXPECTF-- -array(2) { - ["foo"]=> - string(3) "bar" - ["baz"]=> - string(3) "buh" -} -array(1) { - ["up"]=> - array(5) { - ["name"]=> - string(6) "up.txt" - ["type"]=> - string(0) "" - ["tmp_name"]=> - string(%d) "%s" - ["error"]=> - int(0) - ["size"]=> - int(15) - } -} -DONE diff --git a/tests/envrequestjson001.phpt b/tests/envrequestjson001.phpt deleted file mode 100644 index 3dfd9a8..0000000 --- a/tests/envrequestjson001.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -env request json ---SKIPIF-- - ---POST_RAW-- -Content-Type: application/json - -{"foo": "bar", "a": [1,2,3]} ---FILE-- - -Done ---EXPECT-- -Test -Array -( - [foo] => bar - [a] => Array - ( - [0] => 1 - [1] => 2 - [2] => 3 - ) - -) -Done - diff --git a/tests/envrequestjson002.phpt b/tests/envrequestjson002.phpt deleted file mode 100644 index 4c404c0..0000000 --- a/tests/envrequestjson002.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -env request json ---SKIPIF-- - ---PUT-- -Content-Type: application/json - -{"foo": "bar", "a": [1,2,3]} ---FILE-- - -Done ---EXPECT-- -Test -Array -( - [foo] => bar - [a] => Array - ( - [0] => 1 - [1] => 2 - [2] => 3 - ) - -) -Done - diff --git a/tests/envresponse017.phpt b/tests/envresponse017.phpt index ffa40cb..4c832f2 100644 --- a/tests/envresponse017.phpt +++ b/tests/envresponse017.phpt @@ -10,7 +10,7 @@ echo "Test\n"; $req = new http\Env\Request; $req->setRequestMethod("CONNECT"); -$req->setRequestUrl(["host"=>"www.example.com", "port"=>80]); +$req->setRequestUrl(array("host"=>"www.example.com", "port"=>80)); echo $req; diff --git a/tests/headerparser001.phpt b/tests/headerparser001.phpt index 0a1eb37..cdd55e4 100644 --- a/tests/headerparser001.phpt +++ b/tests/headerparser001.phpt @@ -8,16 +8,16 @@ include "skipif.inc"; "FAILURE",0=>"START","KEY","VALUE","VALUE_EX","HEADER_DONE","DONE"]; +$states = array(-1=>"FAILURE",0=>"START","KEY","VALUE","VALUE_EX","HEADER_DONE","DONE"); $parser = new http\Header\Parser; do { $state = $parser->parse($part = array_shift($headers), diff --git a/tests/headerparser002.phpt b/tests/headerparser002.phpt index c5a02f1..67e6681 100644 --- a/tests/headerparser002.phpt +++ b/tests/headerparser002.phpt @@ -8,14 +8,14 @@ include "skipif.inc"; setEnvRequest($msg) + $r = new http\Env\Response; + $r->setEnvRequest($msg) ->setHeader("X-Req", $msg->getRequestUrl()) ->send($client); } diff --git a/tests/helper/server.inc b/tests/helper/server.inc index 0605adc..506e083 100644 --- a/tests/helper/server.inc +++ b/tests/helper/server.inc @@ -1,11 +1,25 @@ - $v) { + if (!$v) unset($args[$k]); + } + proc(PHP_BIN, $args, $cb); } -function nghttpd(callable $cb) { - $spec = [["pipe","r"], ["pipe","w"], ["pipe","w"]]; - foreach (range(8000, 9000) as $port) { +function nghttpd($cb) { + $spec = array(array("pipe","r"), array("pipe","w"), array("pipe","w")); + $offset = rand(0,2000); + foreach (range(8000+$offset, 9000+$offset) as $port) { $comm = "exec nghttpd -d html $port http2.key http2.crt"; if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) { $stdin = $pipes[0]; @@ -65,17 +85,17 @@ function nghttpd(callable $cb) { } -function proc($bin, $args, callable $cb) { - $spec = [["pipe","r"], ["pipe","w"], ["pipe","w"]]; +function proc($bin, $args, $cb) { + $spec = array(array("pipe","r"), array("pipe","w"), array("pipe","w")); $comm = escapeshellcmd($bin) . " ". implode(" ", array_map("escapeshellarg", $args)); if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) { $stdin = $pipes[0]; $stdout = $pipes[1]; $stderr = $pipes[2]; - + do { $port = trim(fgets($stderr)); - $R = [$stderr]; $W = []; $E = []; + $R = array($stderr); $W = array(); $E = array(); } while (is_numeric($port) && stream_select($R, $W, $E, 0, 10000)); if (is_numeric($port)) { diff --git a/tests/info002.phpt b/tests/info002.phpt index 72690e4..093dcd1 100644 --- a/tests/info002.phpt +++ b/tests/info002.phpt @@ -9,7 +9,7 @@ include "skipif.inc"; echo "Test\n"; -function trap(callable $cb) { +function trap($cb) { try { $cb(); } catch (Exception $e) { diff --git a/tests/messageparser001.phpt b/tests/messageparser001.phpt index d2d22a5..1167c64 100644 --- a/tests/messageparser001.phpt +++ b/tests/messageparser001.phpt @@ -26,7 +26,7 @@ foreach (glob(__DIR__."/data/message_*.txt") as $file) { } if (!$string) { - $s = ["START", "HEADER", "HEADER_DONE", "BODY", "BODY_DUMB", "BODY_LENGTH", "BODY_CHUNK", "BODY_DONE", "UPDATE_CL", "DONE"]; + $s = array("START", "HEADER", "HEADER_DONE", "BODY", "BODY_DUMB", "BODY_LENGTH", "BODY_CHUNK", "BODY_DONE", "UPDATE_CL", "DONE"); printf("Unexpected state: %s (%s)\n", $s[$parser->getState()], $file); } diff --git a/tests/querystring003.phpt b/tests/querystring003.phpt new file mode 100644 index 0000000..caa1745 --- /dev/null +++ b/tests/querystring003.phpt @@ -0,0 +1,22 @@ +--TEST-- +querystring offset set +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +Test +foo=bar&bar=baz +bar=baz&foo=baz +===DONE=== diff --git a/tests/skipif.inc b/tests/skipif.inc index cceeaf0..4ab631e 100644 --- a/tests/skipif.inc +++ b/tests/skipif.inc @@ -21,9 +21,11 @@ function skip_client_test($message = "skip need a client driver\n") { } function skip_http2_test($message = "skip need http2 support (nghttpd in PATH)\n") { - foreach (explode(":", $_ENV["PATH"]) as $path) { - if (is_executable($path . "/nghttpd")) { - return; + if (defined("http\\Client\\Curl\\HTTP_VERSION_2_0")) { + foreach (explode(":", $_ENV["PATH"]) as $path) { + if (is_executable($path . "/nghttpd")) { + return; + } } } die($message);