"php_http_env_response.c php_http_etag.c php_http_exception.c php_http_filter.c php_http_header_parser.c " +\r
"php_http_header.c php_http_info.c php_http_message.c php_http_message_body.c php_http_message_parser.c " +\r
"php_http_misc.c php_http_negotiate.c php_http_object.c php_http_options.c php_http_params.c " +\r
- "php_http_querystring.c " +\r
- "php_http_strlist.c php_http_url.c php_http_version.c",\r
+ "php_http_querystring.c php_http_url.c php_http_version.c",\r
null,\r
null);\r
AC_DEFINE("HAVE_HTTP", 1, "Have extended HTTP support");\r
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])
fi
])
-dnl ----
-dnl JSON
-dnl ----
- HTTP_HAVE_PHP_EXT([json])
-
-
dnl ----
dnl ICONV
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])
PHP_MINIT_FUNCTION(http);
PHP_MSHUTDOWN_FUNCTION(http);
-PHP_RINIT_FUNCTION(http);
PHP_RSHUTDOWN_FUNCTION(http);
PHP_MINFO_FUNCTION(http);
#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}
};
http_functions,
PHP_MINIT(http),
PHP_MSHUTDOWN(http),
- PHP_RINIT(http),
+ NULL,
PHP_RSHUTDOWN(http),
PHP_MINFO(http),
PHP_PECL_HTTP_VERSION,
return SUCCESS;
}
-PHP_RINIT_FUNCTION(http)
-{
- if (0
- || SUCCESS != PHP_RINIT_CALL(http_env)
- ) {
- return FAILURE;
- }
-
- return SUCCESS;
-}
-
PHP_RSHUTDOWN_FUNCTION(http)
{
if (0
# 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 <stddef.h>
#ifdef PHP_WIN32
# define CURL_STATICLIB
#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)
{
{
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;
}
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)
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;
}
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
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) {
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);
}
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);
}
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;
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 <unicode/uidna.h>
+# 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);
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;
}
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);
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 */
/*
?>
===DONE===
---EXPECT--
+--EXPECTF--
Test
-401
+40%d
===DONE===
$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
--SKIPIF--
<?php
include "skipif.inc";
+skip_online_test();
skip_client_test();
?>
--FILE--
$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();
$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/"));
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()) {
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();
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"));
<?php
include "skipif.inc";
skip_client_test();
+$client = new http\Client("curl");
+array_key_exists("proxyheader", $client->getAvailableOptions())
+ or die("skip need libcurl with CUTLOPT_PROXYHEADER support\n");
?>
--FILE--
<?php
$tmpfile = tempnam(sys_get_temp_dir(), "cookie.");
$request = new http\Client\Request("GET", "http://localhost");
-$request->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();
});
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();
});
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();
});
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();
$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()));
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--
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===
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());
+++ /dev/null
---TEST--
-env request body
---SKIPIF--
-<?php include "skipif.inc"; ?>
---PUT--
-Content-Type: application/x-www-form-urlencoded
-foo=bar&baz=buh
---FILE--
-<?php
-var_dump($_POST);
-?>
-DONE
---EXPECT--
-array(2) {
- ["foo"]=>
- string(3) "bar"
- ["baz"]=>
- string(3) "buh"
-}
-DONE
+++ /dev/null
---TEST--
-env request body
---SKIPIF--
-<?php include "skipif.inc"; ?>
---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--
-<?php
-var_dump($_POST);
-var_dump($_FILES);
-?>
-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
+++ /dev/null
---TEST--
-env request json
---SKIPIF--
-<?php
-include "skipif.inc";
-_ext("json");
-?>
---POST_RAW--
-Content-Type: application/json
-
-{"foo": "bar", "a": [1,2,3]}
---FILE--
-<?php
-echo "Test\n";
-print_r($_POST);
-?>
-Done
---EXPECT--
-Test
-Array
-(
- [foo] => bar
- [a] => Array
- (
- [0] => 1
- [1] => 2
- [2] => 3
- )
-
-)
-Done
-
+++ /dev/null
---TEST--
-env request json
---SKIPIF--
-<?php
-include "skipif.inc";
-_ext("json");
-?>
---PUT--
-Content-Type: application/json
-
-{"foo": "bar", "a": [1,2,3]}
---FILE--
-<?php
-echo "Test\n";
-print_r($_POST);
-?>
-Done
---EXPECT--
-Test
-Array
-(
- [foo] => bar
- [a] => Array
- (
- [0] => 1
- [1] => 2
- [2] => 3
- )
-
-)
-Done
-
$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;
<?php
echo "Test\n";
-$headers = [
+$headers = array(
"One: ","header\n",
"Two: header\n\tlines\n",
"Three",": header\n lines\n here\n",
"More: than one header\n",
"More: ", "than: ", "you: ", "expect\n",
"\n",
-];
+);
-$states = [-1=>"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),
<?php
echo "Test\n";
-$headers = [
+$headers = array(
"Na\0me: value",
"Na\nme: value",
"Name:\0value",
"Name:\nvalue",
"Name: val\0ue",
"Name: value\0",
-];
+);
foreach ($headers as $header) {
$parsed = null;
$socket = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
stream_set_blocking($socket[0], 0);
-$headers = [
+$headers = array(
"GET / HTTP/1.1\n",
"Host: localhost","\n",
"Content","-length: 3\n",
"\n",
-];
+);
while ($headers) {
$line = array_shift($headers);
include "server.inc";
function respond($client, $msg) {
- (new http\Env\Response)->setEnvRequest($msg)
+ $r = new http\Env\Response;
+ $r->setEnvRequest($msg)
->setHeader("X-Req", $msg->getRequestUrl())
->send($client);
}
-<?php
+<?php
-function serve(callable $cb) {
- foreach (range(8000, 9000) as $port) {
+$php = getenv('TEST_PHP_EXECUTABLE');
+if ($php) {
+ define('PHP_BIN', $php);
+} else if (defined('PHP_BINARY')) {
+ define('PHP_BIN', PHP_BINARY);
+} else {
+ // PHP-5.3
+ define("PHP_BIN", PHP_BINDIR.DIRECTORY_SEPARATOR."php");
+}
+
+function serve($cb) {
+ /* stream_socket_server() automatically sets SO_REUSEADDR,
+ * which is, well, bad if the tests are run in parallel
+ */
+ $offset = rand(0,2000);
+ foreach (range(8000+$offset, 9000+$offset) as $port) {
if (($server = @stream_socket_server("tcp://localhost:$port"))) {
fprintf(STDERR, "%s\n", $port);
do {
- $R = [$server]; $W = []; $E = [];
+ $R = array($server); $W = array(); $E = array();
$select = stream_select($R, $E, $E, 0, 10000);
if ($select && ($client = stream_socket_accept($server, 1))) {
if (getenv("PHP_HTTP_TEST_SSL")) {
}
}
-function server($handler, callable $cb) {
- proc(PHP_BINARY, [__DIR__."/$handler"], $cb);
+function server($handler, $cb) {
+ $args = explode(' ', getenv('TEST_PHP_ARGS'));
+ $args[] = __DIR__."/$handler";
+ foreach ($args as $k => $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];
}
-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)) {
echo "Test\n";
-function trap(callable $cb) {
+function trap($cb) {
try {
$cb();
} catch (Exception $e) {
}
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);
}
--- /dev/null
+--TEST--
+querystring offset set
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+
+echo "Test\n";
+
+$qs = new http\QueryString("foo=bar&bar=baz");
+echo $qs,"\n";
+$qs["foo"] = "baz";
+echo $qs,"\n";
+?>
+===DONE===
+--EXPECT--
+Test
+foo=bar&bar=baz
+bar=baz&foo=baz
+===DONE===
}
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);