--- /dev/null
+[submodule "travis-pecl"]
+ path = travis/pecl
+ url = https://github.com/m6w6/travis-pecl.git
+ branch = master
-language: php
+# autogenerated file; do not edit
+language: c
-php:
- - 5.3
- - 5.4
+addons:
+ apt:
+ packages:
+ - php5-cli
+ - php-pear
+ - libcurl4-openssl-dev
+ - zlib1g-dev
+ - libidn11-dev
+ - libevent-dev
-before_script: phpize
+env:
+ - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.4 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.5 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=5.6 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes
-script: ./configure && make && NO_INTERACTION=1 REPORT_EXIT_STATUS=1 TEST_PHP_DETAILED=1 make test
+before_script:
+ - make -f travis/pecl/Makefile php
+ - make -f travis/pecl/Makefile pecl PECL=raphf
+ - make -f travis/pecl/Makefile pecl PECL=propro
+script:
+ - make -f travis/pecl/Makefile ext PECL=http
+ - make -f travis/pecl/Makefile test
+
+after_script:
+ - test -e tests/helper/server.log && cat tests/helper/server.log
+
+sudo: false
--- /dev/null
+# pecl/http v2
+
+[![Build Status](https://travis-ci.org/m6w6/ext-http.svg?branch=master)](https://travis-ci.org/m6w6/ext-http)
+
+## About:
+
+Extended HTTP support. Again.
+
+* Introduces the http namespace.
+* PHP stream based message bodies.
+* Encapsulated env request/response.
+* Modular client support.
+
+## Installation:
+
+This extension is hosted at [PECL](http://pecl.php.net) and can be installed with [PEAR](http://pear.php.net)'s pecl command:
+
+ # pecl install pecl_http
+
+## Dependencies:
+
+pecl/http depends on a number of system libraries and PHP extensions for special features.
+
+#### Required system libraries:
+
+The following system libraries are required to build this extension:
+
+##### zlib
+Provides gzip/zlib/deflate encoding.
+Minimum version: 1.2.0.4
+Install on Debian: `apt-get install zlib1g-dev`
+
+
+#### Optional system libraries:
+
+The following system libraries are optional and provide additional features:
+
+##### libidn
+Provides IDNA support in URLs.
+Minimum version: none
+Install on Debian: `apt-get install libidn11-dev`
+
+##### libidn2
+Provides IDNA support in URLs (fallback if libidn is not available).
+Minimum version: none
+Install on Debian: `apt-get install libidn2-0-dev`
+
+##### libicu
+Provides IDNA support in URLs (fallback if libidn is not available).
+Minimum version: none
+Install on Debian: `apt-get install libicu-dev`
+
+##### libcurl
+Provides HTTP request functionality.
+Minimum version: 7.18.2
+Install on Debian: `apt-get install libcurl4-openssl-dev`
+Note: There are usually different styles of SSL support for libcurl available, so you can replace 'openssl' in the above command f.e. with 'nss' or 'gnutls'.
+
+##### libevent
+Eventloop support for the HTTP client.
+Minimum version: none
+Install on Debian: `apt-get install libevent-dev`
+
+### PHP extensions:
+
+This extension unconditionally depends on the pre-loaded presence of the following PHP extensions:
+
+* [raphf](https://github.com/m6w6/ext-raphf)
+* [propro](https://github.com/m6w6/ext-propro)
+* spl
+
+
+If configured ```--with-http-shared-deps``` (default) it depends on the pre-loaded presence of the following extensions, as long as they were available at build time:
+
+* hash
+* iconv
+* json (only until < 2.4.0)
+
+Please ensure that all extension on which pecl/http depends, are loaded before it, e.g in your `php.ini`:
+
+ ; obligatory deps
+ extension = raphf.so
+ extension = propro.so
+
+ ; if shared deps were enabled
+ extension = hash.so
+ extension = iconv.so
+ extension = json.so
+
+ ; finally load pecl/http
+ extension = http.so
+
+## Conflicts:
+
+pecl/http-v2 conflicts with the following extensions:
+
+* http-v1
+* event (only until <= 2.0.3)
+
+## INI Directives:
+
+* http.etag.mode = "crc32b"
+ Default hash method for dynamic response payloads to generate an ETag.
+
+## Stream Filters:
+
+The http extension registers the ```http.*``` namespace for its stream filters. Provided stream filters are:
+
+* http.chunked_decode
+ Decode a stream encoded with chunked transfer encoding.
+* http.chunked_encode
+ Encode a stream with chunked transfer encoding.
+* http.inflate
+ Decode a stream encoded with deflate/zlib/gzip encoding.
+* http.deflate
+ Encode a stream with deflate/zlib/gzip encoding.
+
+
+## Documentation:
+
+Documentation is available at https://mdref.m6w6.name/http
fi
])
+ dnl
+ dnl HTTP_CURL_SSL_LIB_CHECK(ssllib[, code-if-yes[, code-if-not])
+ dnl
+ AC_DEFUN([HTTP_CURL_SSL_LIB_CHECK], [
+ AC_MSG_CHECKING([for $1 support in libcurl])
+ AC_TRY_RUN([
+ #include <curl/curl.h>
+ int main(int argc, char *argv[]) {
+ curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
+ if (data && data->ssl_version && *data->ssl_version) {
+ const char *ptr = data->ssl_version;
+ while(*ptr == ' ') ++ptr;
+ return strncasecmp(ptr, "$1", sizeof("$1")-1);
+ }
+ return 1;
+ }
+ ], [
+ AC_MSG_RESULT([yes])
+ $2
+ ], [
+ AC_MSG_RESULT([no])
+ $3
+ ], [
+ AC_MSG_RESULT([no])
+ $3
+ ])
+ ])
+
dnl ----
dnl STDC
AC_MSG_RESULT([yes])
AC_DEFINE([PHP_HTTP_HAVE_SSL], [1], [ ])
- AC_MSG_CHECKING([for openssl support in libcurl])
- AC_TRY_RUN([
- #include <curl/curl.h>
- int main(int argc, char *argv[]) {
- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
- if (data && data->ssl_version && *data->ssl_version) {
- const char *ptr = data->ssl_version;
- while(*ptr == ' ') ++ptr;
- return strncasecmp(ptr, "OpenSSL", sizeof("OpenSSL")-1);
- }
- return 1;
- }
- ], [
- AC_MSG_RESULT([yes])
+ HTTP_CURL_SSL_LIB_CHECK(OpenSSL, [
AC_CHECK_HEADER([openssl/ssl.h], [
AC_CHECK_HEADER([openssl/crypto.h], [
AC_DEFINE([PHP_HTTP_HAVE_OPENSSL], [1], [ ])
CURL_SSL_LIBS="ssl crypto"
])
])
- ], [
- AC_MSG_RESULT([no])
- ], [
- AC_MSG_RESULT([no])
])
-
- AC_MSG_CHECKING([for gnutls support in libcurl])
- AC_TRY_RUN([
- #include <curl/curl.h>
- int main(int argc, char *argv[]) {
- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
- if (data && data->ssl_version && *data->ssl_version) {
- const char *ptr = data->ssl_version;
- while(*ptr == ' ') ++ptr;
- return strncasecmp(ptr, "GnuTLS", sizeof("GnuTLS")-1);
- }
- return 1;
- }
- ], [
- AC_MSG_RESULT([yes])
+ HTTP_CURL_SSL_LIB_CHECK(GnuTLS, [
AC_CHECK_HEADER([gnutls.h], [
AC_CHECK_HEADER([gcrypt.h], [
AC_DEFINE([PHP_HTTP_HAVE_GNUTLS], [1], [ ])
CURL_SSL_LIBS="gnutls gcrypt"
])
])
- ], [
- AC_MSG_RESULT([no])
- ], [
- AC_MSG_RESULT([no])
+ ])
+ HTTP_CURL_SSL_LIB_CHECK(NSS, [
+ AC_DEFINE([PHP_HTTP_HAVE_NSS], [1], [ ])
+ ])
+ HTTP_CURL_SSL_LIB_CHECK(SecureTransport, [
+ AC_DEFINE([PHP_HTTP_HAVE_DARWINSSL], [1], [ ])
+ ])
+ HTTP_CURL_SSL_LIB_CHECK(GSKit, [
+ AC_DEFINE([PHP_HTTP_HAVE_GSKIT], [1], [ ])
])
else
+ dnl no CURL_SSL
AC_MSG_RESULT([no])
fi
--- /dev/null
+#!/usr/bin/env php
+# autogenerated file; do not edit
+language: c
+
+addons:
+ apt:
+ packages:
+ - php5-cli
+ - php-pear
+ - libcurl4-openssl-dev
+ - zlib1g-dev
+ - libidn11-dev
+ - libevent-dev
+
+env:
+<?php
+
+$gen = include "./travis/pecl/gen-matrix.php";
+$env = $gen([
+ "PHP" => ["5.4", "5.5", "5.6"],
+ "enable_debug",
+ "enable_maintainer_zts",
+ "enable_json",
+ "enable_hash" => ["yes"],
+ "enable_iconv" => ["yes"]
+]);
+foreach ($env as $e) {
+ printf(" - %s\n", $e);
+}
+
+?>
+
+before_script:
+ - make -f travis/pecl/Makefile php
+ - make -f travis/pecl/Makefile pecl PECL=raphf
+ - make -f travis/pecl/Makefile pecl PECL=propro
+
+script:
+ - make -f travis/pecl/Makefile ext PECL=http
+ - make -f travis/pecl/Makefile test
+
+after_script:
+ - test -e tests/helper/server.log && cat tests/helper/server.log
+
+sudo: false
case CURLSSLBACKEND_QSOSSL:
backend = "qsossl";
break;
-#endif
+#else
case CURLSSLBACKEND_GSKIT:
backend = "gskit";
break;
+#endif
case CURLSSLBACKEND_POLARSSL:
backend = "polarssl";
break;
}
#endif
-#if PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)
+#if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT))
{
int i;
zval ci_array, subarray;
opt->setter = php_http_curle_option_set_proxyheader;
}
#endif
+#if PHP_HTTP_CURL_VERSION(7,43,0)
+ if ((opt = php_http_option_register(registry, ZEND_STRL("proxy_service_name"), CURLOPT_PROXY_SERVICE_NAME, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ }
+#endif
#if PHP_HTTP_CURL_VERSION(7,40,0)
if ((opt = php_http_option_register(registry, ZEND_STRL("unix_socket_path"), CURLOPT_UNIX_SOCKET_PATH, IS_STRING))) {
if ((opt = php_http_option_register(registry, ZEND_STRL("httpauthtype"), CURLOPT_HTTPAUTH, IS_LONG))) {
Z_LVAL(opt->defval) = CURLAUTH_ANYSAFE;
}
+#if PHP_HTTP_CURL_VERSION(7,43,0)
+ if ((opt = php_http_option_register(registry, ZEND_STRL("service_name"), CURLOPT_SERVICE_NAME, IS_STRING))) {
+ opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
+ }
+#endif
/* redirects */
if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) {
}
# endif
#endif
-#if PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)
- php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL);
+#if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT))
+ if ((opt = php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) {
+ ZVAL_FALSE(&opt->defval);
+ }
#endif
#if PHP_HTTP_CURL_VERSION(7,36,0)
if ((opt = php_http_option_register(registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) {
if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) {
opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
}
+#endif
+#if PHP_HTTP_CURL_VERSION(7,42,0) && (defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_DARWINSSL))
+ php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL);
#endif
}
}
zval *this_ptr = getThis(); \
zval qs_tmp, *qs = zend_read_property(Z_OBJCE_P(this_ptr), this_ptr, ZEND_STRL(prop), 0, &qs_tmp); \
\
+ ZVAL_NULL(&rv); \
array_init(&mn); \
Z_TRY_ADDREF_P(qs); \
add_next_index_zval(&mn, qs); \
const char *colon, *eol_str = NULL;
int eol_len = 0;
+ /* fix buffer here, so eol_str pointer doesn't become obsolete afterwards */
+ php_http_buffer_fix(buffer);
+
if (buffer->data == (eol_str = php_http_locate_bin_eol(buffer->data, buffer->used, &eol_len))) {
/* end of headers */
php_http_buffer_cut(buffer, 0, eol_len);
php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_DONE);
- } else if (php_http_info_parse(&parser->info, php_http_buffer_fix(buffer)->data)) {
+ } else if (php_http_info_parse(&parser->info, buffer->data)) {
/* new message starting with request/response line */
if (callback_func) {
callback_func(callback_arg, &headers, &parser->info);
php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
} else if (eol_str || (flags & PHP_HTTP_HEADER_PARSER_CLEANUP)) {
/* neither reqeust/response line nor 'header:' string, or injected new line or NUL etc. */
- php_http_buffer_fix(buffer);
php_http_header_parser_error(strspn(buffer->data, PHP_HTTP_HEADER_NAME_CHARS), buffer->data, buffer->used, eol_str);
return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
} else {
#include <ext/spl/spl_array.h>
#ifdef PHP_HTTP_HAVE_ICONV
+# ifndef HAVE_ICONV
+# define HAVE_ICONV 1
+# endif
# undef PHP_ATOM_INC
# include <ext/iconv/php_iconv.h>
#endif
state->buffer[state->offset++] = *state->ptr;
break;
- case ']':
- case '[':
+ /* RFC1738 unsafe */
+ case '{': case '}':
+ case '<': case '>':
+ case '[': case ']':
+ case '|': case '\\': case '^': case '`': case '"': case ' ':
if (state->flags & PHP_HTTP_URL_PARSE_TOPCT) {
state->buffer[state->offset++] = '%';
state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) >> 4];
state->buffer[state->offset++] = *state->ptr;
break;
+ /* RFC1738 unsafe */
+ case '{': case '}':
+ case '<': case '>':
+ case '[': case ']':
+ case '|': case '\\': case '^': case '`': case '"': case ' ':
+ if (state->flags & PHP_HTTP_URL_PARSE_TOPCT) {
+ state->buffer[state->offset++] = '%';
+ state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) >> 4];
+ state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) & 0xf];
+ break;
+ }
+ /* no break */
+
case '?': case '/':
case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case ';': case '=': /* sub-delims */
skip_client_test();
$client = new http\Client("curl");
array_key_exists("proxyheader", $client->getAvailableOptions())
- or die("skip need libcurl with CUTLOPT_PROXYHEADER support\n");
+ or die("skip need libcurl with CURLOPT_PROXYHEADER support\n");
?>
--FILE--
<?php
--- /dev/null
+--TEST--
+url - unsafe characters
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+echo "Test\n";
+
+echo (new http\Url("?__utma=1152894289.1017686999.9107388726.1439222726.1494721726.1&__utmb=115739289.1.10.1437388726&__utmc=115883619&__utmx=-&__utmz=115111289.14310476.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)&__utmv=-&__utmk=112678937"))->query;
+echo "\n";
+echo (new http\Url("?id={\$id}"))->query;
+echo "\n";
+
+?>
+===DONE===
+--EXPECT--
+Test
+__utma=1152894289.1017686999.9107388726.1439222726.1494721726.1&__utmb=115739289.1.10.1437388726&__utmc=115883619&__utmx=-&__utmz=115111289.14310476.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)&__utmv=-&__utmk=112678937
+id={$id}
+===DONE===
--- /dev/null
+--TEST--
+crash with querystring and exception from error handler
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--GET--
+q[]=1&r[]=2
+--FILE--
+<?php
+echo "Test\n";
+
+set_error_handler(function($c,$e) { throw new Exception($e); });
+
+try {
+ $q = http\QueryString::getGlobalInstance();
+ var_dump($q->get("q","s"));
+} catch (\Exception $e) {
+ echo $e->getMessage(),"\n";
+}
+try {
+ $r = new http\Env\Request;
+ var_dump($r->getQuery("r", "s"));
+} catch (\Exception $e) {
+ echo $e->getMessage(),"\n";
+}
+
+?>
+===DONE===
+--EXPECT--
+Test
+Array to string conversion
+Array to string conversion
+===DONE===
}
serve(function($client) {
+ $R = array(STDIN); $W = $E = array();
+ if (!stream_select($R, $W, $E, 10, 0)) {
+ logger("Client %d timed out", (int) $client);
+ return;
+ }
$count = trim(fgets(STDIN));
-
+ logger("Expecting %d messages from client %d", $count, (int) $client);
/* the peek message */
respond($client, new http\Message($client, false));
-
+ logger("Handled the peek request of client %d", (int) $client);
/* pipelined messages */
$req = array();
for ($i=0; $i < $count; ++ $i) {
$req[] = new http\Message($client, false);
+ logger("Read request no. %d from client %d", $i+1, (int) $client);
}
- foreach ($req as $msg) {
+ foreach ($req as $i => $msg) {
respond($client, $msg);
+ logger("Sent response no. %d to client %d", $i+1, (int) $client);
}
});
<?php
+ini_set("log_errors", true);
+ini_set("error_log", __DIR__."/server.log");
+
+function logger() {
+ if (!ini_get("date.timezone")) {
+ date_default_timezone_set(@date_default_timezone_get());
+ }
+ error_log(sprintf("%s(%s): %s",
+ basename(getenv("SCRIPT_FILENAME"), ".php"),
+ basename(current(get_included_files()), ".inc"),
+ call_user_func_array("sprintf", func_get_args())
+ ));
+}
+
$php = getenv('TEST_PHP_EXECUTABLE');
if ($php) {
define('PHP_BIN', $php);
*/
$offset = rand(0,2000);
foreach (range(8000+$offset, 9000+$offset) as $port) {
+ logger("serve: Trying port %d", $port);
if (($server = @stream_socket_server("tcp://localhost:$port"))) {
fprintf(STDERR, "%s\n", $port);
+ logger("serve: Using port %d", $port);
do {
$R = array($server); $W = array(); $E = array();
- $select = stream_select($R, $E, $E, 0, 10000);
+ $select = stream_select($R, $E, $E, 10, 0);
if ($select && ($client = stream_socket_accept($server, 1))) {
+ logger("serve: Accept client %d", (int) $client);
if (getenv("PHP_HTTP_TEST_SSL")) {
stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER);
}
try {
while (!feof($client)) {
+ logger("serve: Handle client %d", (int) $client);
$cb($client);
}
+ logger("serve: EOF on client %d", (int) $client);
} catch (Exception $ex) {
+ logger("serve: Exception on client %d: %s", (int) $client, $ex->getMessage());
/* ignore disconnect */
if ($ex->getMessage() !== "Empty message received from stream") {
fprintf(STDERR, "%s\n", $ex);
break;
}
}
- } while ($select !== false);
+ } while ($select);
return;
}
}
fpassthru($stderr);
fpassthru($stdout);
}
-}
\ No newline at end of file
+}
$m = new HttpEnvRequest();
+// travis' env headers have another order, wtf?
+$h = $m->getHeaders();
+ksort($h);
+$m->setHeaders($h);
+
var_dump($m);
echo "Message->toString\n";
string(3) "1.1"
["headers":protected]=>
array(4) {
- ["X-Test"]=>
- string(4) "test"
["Content-Length"]=>
string(1) "3"
["Content-Type"]=>
string(14) "test/something"
["Cookie"]=>
string(7) "foo=bar"
+ ["X-Test"]=>
+ string(4) "test"
}
["parentMessage":protected]=>
NULL
}
Message->toString
POST / HTTP/1.1%a
-X-Test: test%a
Content-Length: 3%a
Content-Type: test/something%a
Cookie: foo=bar%a
+X-Test: test%a
%a
b=c
Body->toString
--- /dev/null
+Subproject commit 0815aa6d8727870e6bf8409700925abfaaf2b723