*~
*.phar
!travis/*.phar
+bench/
vendor/
/php_http_api.h
/php_http_buffer.h
/php_http_cookie.h
/php_http_curl.h
/php_http_encoding.h
+/php_http_encoding_zlib.h
+/php_http_encoding_brotli.h
/php_http_env.h
/php_http_env_request.h
/php_http_env_response.h
/php_http_utf8.h
/php_http_version.h
/tests/helper/server.log
-*.gcov
+*gcov
+*lcov
# autogenerated file; do not edit
language: c
-sudo: required
+sudo: false
dist: trusty
addons:
- libicu-dev
- libevent-dev
+compiler:
+ - gcc
+ - clang
+
+cache:
+ directories:
+ - $HOME/cache
+before_cache:
+ - find $HOME/cache -name '*.gcda' -o -name '*.gcno' -delete
+
env:
- - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=no
- - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=no enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
- - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libicu_dir=yes
-# once with gcov
- - CFLAGS="-O0 -g --coverage" CXXFLAGS="-O0 -g --coverage" PHP=master enable_json=yes enable_hash=yes enable_iconv=yes
+ - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.3 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.2 with_http_libicu_dir=no with_http_libidn_dir=no with_http_libidn2_dir=no with_http_libcurl_dir=no with_http_libevent_dir=no
+ - PHP=7.2 enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.2 enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.2 enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - PHP=7.2 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli
+ - CFLAGS='-O0 -g --coverage' CXXFLAGS='-O0 -g --coverage' PHP=7.2 enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli with_http_libicu_dir=yes with_http_libidn_dir=no with_http_libidn2_dir=no
+ - CFLAGS='-O0 -g --coverage' CXXFLAGS='-O0 -g --coverage' PHP=7.2 enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli with_http_libidn_dir=yes with_http_libicu_dir=no with_http_libidn2_dir=no
+ - CFLAGS='-O0 -g --coverage' CXXFLAGS='-O0 -g --coverage' PHP=7.2 enable_json=yes enable_hash=yes enable_iconv=yes with_http_libbrotli_dir=/home/travis/brotli with_http_libidn2_dir=yes with_http_libicu_dir=no with_http_libidn_dir=no
-before_script:
- - make -f travis/pecl/Makefile php
- - make -f travis/pecl/Makefile pecl PECL=raphf:raphf:2.0.0
- - make -f travis/pecl/Makefile pecl PECL=propro:propro:2.0.1
- - make -f travis/pecl/Makefile ext PECL=http
+install:
+ - ./travis/brotli.sh v1.0.2
+ - |
+ if test "$PHP" = master; then \
+ make -f travis/pecl/Makefile reconf; \
+ make -f travis/pecl/Makefile pecl-rm pecl-clean PECL=ext-raphf.git:raphf:master; \
+ make -f travis/pecl/Makefile pecl-rm pecl-clean PECL=ext-propro.git:propro:master; \
+ fi
+ - make -f travis/pecl/Makefile php || make -f travis/pecl/Makefile clean php
+ - make -f travis/pecl/Makefile pecl PECL=ext-raphf.git:raphf:master
+ - make -f travis/pecl/Makefile pecl PECL=ext-propro.git:propro:master
script:
+ - make -f travis/pecl/Makefile ext PECL=http
- make -f travis/pecl/Makefile test
- - make -f travis/pecl/Makefile cppcheck
+after_script:
+ - make -f travis/pecl/Makefile cppcheck
after_failure:
- test -e tests/helper/server.log && cat tests/helper/server.log
after_success:
--- /dev/null
+
+AC_DEFUN([PECL_CHECK_LIBBROTLI], [
+ PECL_CHECK_LIBBROTLI_COMMON([$1], [$2])
+ PECL_CHECK_DONE(libbrotlicommon, [$PECL_VAR([HAVE_LIBBROTLI_COMMON])])
+ PECL_CHECK_LIBBROTLI_DEC([$1], [$2])
+ PECL_CHECK_DONE(libbrotlidec, [$PECL_VAR([HAVE_LIBBROTLI_DEC])])
+ PECL_CHECK_LIBBROTLI_ENC([$1], [$2])
+ PECL_CHECK_DONE(libbrotlienc, [$PECL_VAR([HAVE_LIBBROTLI_ENC])])
+
+ if $PECL_VAR([HAVE_LIBBROTLI_COMMON]) \
+ && $PECL_VAR([HAVE_LIBBROTLI_DEC]) \
+ && $PECL_VAR([HAVE_LIBBROTLI_ENC]); then
+ PECL_VAR([HAVE_LIBBROTLI])=true
+ else
+ PECL_VAR([HAVE_LIBBROTLI])=false
+ fi
+])
+
+AC_DEFUN([PECL_CHECK_LIBBROTLI_COMMON], [
+ PECL_CHECK_PKGCONFIG(libbrotlicommon, [$1])
+
+ PECL_HAVE_VERSION(libbrotlicommon, ifelse($2,,1.0,$2), [
+ PECL_VAR([HAVE_LIBBROTLI_COMMON])=true
+ ], [
+ PECL_VAR([HAVE_LIBBROTLI_COMMON])=false
+ ])
+])
+
+AC_DEFUN([PECL_CHECK_LIBBROTLI_DEC], [
+ PECL_CHECK_PKGCONFIG(libbrotlidec, [$1])
+
+ PECL_HAVE_VERSION(libbrotlidec, ifelse($2,,1.0,$2), [
+ PECL_VAR([HAVE_LIBBROTLI_DEC])=true
+ ], [
+ PECL_VAR([HAVE_LIBBROTLI_DEC])=false
+ ])
+])
+
+AC_DEFUN([PECL_CHECK_LIBBROTLI_ENC], [
+ PECL_CHECK_PKGCONFIG(libbrotlienc, [$1])
+
+ PECL_HAVE_VERSION(libbrotlienc, ifelse($2,,1.0,$2), [
+ PECL_VAR([HAVE_LIBBROTLI_ENC])=true
+ ], [
+ PECL_VAR([HAVE_LIBBROTLI_ENC])=false
+ ])
+])
AC_DEFUN([PECL_CHECK_LIBEVENT], [
PECL_CHECK_PKGCONFIG(libevent, [$1])
- PECL_HAVE_VERSION(libevent, 2.0, [
- PECL_DEFINE([HAVE_LIBEVENT2])
- ])
- ifelse([$2],,,[PECL_HAVE_VERSION(libevent, [$2])])
- AC_CHECK_FUNC(event_base_new,,[
- AC_DEFINE([event_base_new], [event_init], [missing event_base_new() in libevent1])
- ])
- AC_CHECK_FUNC(event_assign,,[
- AC_DEFINE([event_assign(e, b, s, a, cb, d)], [do {\
- event_set(e, s, a, cb, d); \
- event_base_set(b, e);\
- } while(0)], [missing event_assign() in libevent1])
- ])
+ if test -n "$PECL_CHECKED_VERSION(libevent)"; then
+ PECL_HAVE_VERSION(libevent, 2.0, [
+ PECL_DEFINE([HAVE_LIBEVENT2])
+ ], [ ])
+ ifelse([$2],,,[PECL_HAVE_VERSION(libevent, [$2])])
+ AC_CHECK_FUNC(event_base_new,,[
+ AC_DEFINE([event_base_new], [event_init], [missing event_base_new() in libevent1])
+ ])
+ AC_CHECK_FUNC(event_assign,,[
+ AC_DEFINE([event_assign(e, b, s, a, cb, d)], [do {\
+ event_set(e, s, a, cb, d); \
+ event_base_set(b, e);\
+ } while(0)], [missing event_assign() in libevent1])
+ ])
+ fi
])
\ No newline at end of file
aversion=_PECL_TR_VERSION([$PECL_CHECKED_VERSION([$1])])
mversion=_PECL_TR_VERSION([$2])
AC_MSG_CHECKING([whether $1 version $PECL_CHECKED_VERSION([$1]) >= $2])
- if test "$aversion" -lt "$mversion"; then
+ if test -z "$aversion" || test "$aversion" -lt "$mversion"; then
ifelse($4,,AC_MSG_ERROR([no]), [
AC_MSG_RESULT([no])
$4
dnl
AC_DEFUN([PECL_CHECK_PKGCONFIG], [dnl
AC_REQUIRE([PECL_PROG_PKGCONFIG])dnl
- ifelse($2,,,PKG_CONFIG_PATH="$2/lib/pkgconfig:$PKG_CONFIG_PATH")
+ ifelse($2,,, [
+ PECL_SAVE_VAR(pkgconfig_path)="$PKG_CONFIG_PATH"
+ if test -d "$2"; then
+ export PKG_CONFIG_PATH="$2/lib/pkgconfig:$PKG_CONFIG_PATH"
+ fi
+ ])
PECL_CHECK_CONFIG([$1], [$PKG_CONFIG $1], [--modversion], [--cflags-only-I], [--libs-only-L], [--libs-only-l])
+ ifelse($2,,, [
+ PKG_CONFIG_PATH="$PECL_SAVE_VAR(pkgconfig_path)"
+ ])
])
dnl
dnl PECL_CHECK_DONE(name, success[, incline, libline])
m4_foreach(dir, [., ext/http], [
sinclude(dir/autoconf/pecl/pecl.m4)
sinclude(dir/autoconf/pecl/zlib.m4)
+ sinclude(dir/autoconf/pecl/libbrotli.m4)
sinclude(dir/autoconf/pecl/libcurl.m4)
sinclude(dir/autoconf/pecl/libevent.m4)
])
[ --with-http-zlib-dir[=DIR] HTTP: where to find zlib], $PHP_HTTP, no)
PECL_CHECK_ZLIB([$PHP_HTTP_ZLIB_DIR], [1.2.0.4])
PECL_CHECK_DONE(zlib, $PECL_VAR([HAVE_ZLIB]))
+
+ dnl BROTLI
+ PHP_ARG_WITH([http-libbrotli-dir], [whether/where to check for libbrotli],
+ [ --with-http-libbrotli-dir[=DIR] HTTP: where to find libbrotli], $PHP_HTTP, no)
+ PECL_CHECK_LIBBROTLI([$PHP_HTTP_LIBBROTLI_DIR], [1.0])
+ PECL_CHECK_DONE(libbrotli, $PECL_VAR([HAVE_LIBBROTLI]))
dnl CURL
PHP_ARG_WITH([http-libcurl-dir], [whether/where to check for libcurl],
<email>mike@php.net</email>
<active>yes</active>
</lead>
- <date>2017-04-04</date>
+ <date>2018-07-19</date>
<version>
- <release>3.1.1dev</release>
- <api>3.1.0</api>
+ <release>3.2.1dev</release>
+ <api>3.2.0</api>
</version>
<stability>
<release>stable</release>
</stability>
<license uri="http://copyfree.org/content/standard/licenses/2bsd/license.txt">BSD-2-Clause</license>
<notes><![CDATA[
-* Fix gh-issue #65: http\Client::enqueue(): Could not enqueue request: The easy handle is already added to a multi handle (@rcanavan, Mike)
+*
]]></notes>
<contents>
<dir name="/">
<dir name="autoconf">
<dir name="pecl">
<file role="src" name="pecl.m4"/>
+ <file role="src" name="libbrotli.m4"/>
<file role="src" name="libcurl.m4"/>
<file role="src" name="libevent.m4"/>
<file role="src" name="zlib.m4"/>
<file role="src" name="php_http_curl.h"/>
<file role="src" name="php_http_encoding.c"/>
<file role="src" name="php_http_encoding.h"/>
+ <file role="src" name="php_http_encoding_zlib.c"/>
+ <file role="src" name="php_http_encoding_zlib.h"/>
+ <file role="src" name="php_http_encoding_brotli.c"/>
+ <file role="src" name="php_http_encoding_brotli.h"/>
<file role="src" name="php_http_env.c"/>
<file role="src" name="php_http_env.h"/>
<file role="src" name="php_http_env_request.c"/>
<file role="test" name="encstream007.phpt"/>
<file role="test" name="encstream008.phpt"/>
<file role="test" name="encstream009.phpt"/>
+ <file role="test" name="encstream015.phpt"/>
+ <file role="test" name="encstream016.phpt"/>
+ <file role="test" name="encstream017.phpt"/>
+ <file role="test" name="encstream018.phpt"/>
+ <file role="test" name="encstream019.phpt"/>
<file role="test" name="envrequestbody001.phpt"/>
<file role="test" name="envrequestcookie001.phpt"/>
<file role="test" name="envrequestfiles001.phpt"/>
<file role="test" name="envresponseheader001.phpt"/>
<file role="test" name="envresponseranges001.phpt"/>
<file role="test" name="etag001.phpt"/>
+ <file role="test" name="filterbrotli.phpt"/>
<file role="test" name="filterchunked.phpt"/>
<file role="test" name="filterzlib.phpt"/>
<file role="test" name="gh-issue6.phpt"/>
<file role="test" name="gh-issue47.phpt"/>
<file role="test" name="gh-issue48.phpt"/>
<file role="test" name="gh-issue50.phpt"/>
+ <file role="test" name="gh-issue63.phpt"/>
<file role="test" name="header001.phpt"/>
<file role="test" name="header002.phpt"/>
<file role="test" name="header003.phpt"/>
<file role="test" name="phpinfo.phpt"/>
<file role="test" name="propertyproxy001.phpt"/>
<file role="test" name="querystring001.phpt"/>
+ <file role="test" name="querystring001_a.phpt"/>
<file role="test" name="querystring002.phpt"/>
<file role="test" name="querystring003.phpt"/>
<file role="test" name="serialize001.phpt"/>
#ifndef PHP_EXT_HTTP_H
#define PHP_EXT_HTTP_H
-#define PHP_PECL_HTTP_VERSION "3.1.1dev"
+#define PHP_PECL_HTTP_VERSION "3.2.1dev"
extern zend_module_entry http_module_entry;
#define phpext_http_ptr &http_module_entry
./configure
make clean
-
+
$COVERITY_BIN --dir $COVERITY_BUILD_DIR/cov-int make -j8
+echo >&2
+echo -n "Submit results to scan.coverity.com? (y/N) " >&2
+read submit
+echo >&2
+
+if test "$submit" != "y"; then
+ exit
+fi
+
pushd $COVERITY_BUILD_DIR
tar -czf cov-int{.tgz,}
popd
function file_re($file, $pattern, $all = true) {
static $path;
-
+
$path or $path = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1].'/include/curl/' : "/usr/local/include/curl/";
-
+
if ($content = file_get_contents($path . $file)) {
if ($all) {
if (preg_match_all($pattern, $content, $matches, PREG_SET_ORDER)) {
'PRIMARY_PORT' => 'PHP_HTTP_CURL_VERSION(7,21,0)',
'LOCAL_PORT' => 'PHP_HTTP_CURL_VERSION(7,21,0)',
'LOCAL_IP' => 'PHP_HTTP_CURL_VERSION(7,21,0)',
- 'HTTP_VERSION' => 'PHP_HTTP_CURL_VERSION(7,50,0)'
+ 'HTTP_VERSION' => 'PHP_HTTP_CURL_VERSION(7,50,0)',
+ 'PROXY_SSL_VERIFYRESULT' => 'PHP_HTTP_CURL_VERSION(7,52,0)',
+ 'PROTOCOL' => 'PHP_HTTP_CURL_VERSION(7,52,0)',
+ 'SCHEME' => 'PHP_HTTP_CURL_VERSION(7,52,0)',
);
$exclude = array(
'ACTIVESOCKET',
);
$templates = array(
-'STRING' =>
+'STRING' =>
' if (CURLE_OK == curl_easy_getinfo(ch, %s, &c)) {
ZVAL_STRING(&tmp, STR_PTR(c));
zend_hash_str_update(info, "%s", lenof("%2$s"), &tmp);
}
',
-'DOUBLE' =>
+'DOUBLE' =>
' if (CURLE_OK == curl_easy_getinfo(ch, %s, &d)) {
ZVAL_DOUBLE(&tmp, d);
zend_hash_str_update(info, "%s", lenof("%2$s"), &tmp);
}
',
-'LONG' =>
+'LONG' =>
' if (CURLE_OK == curl_easy_getinfo(ch, %s, &l)) {
ZVAL_LONG(&tmp, l);
zend_hash_str_update(info, "%s", lenof("%2$s"), &tmp);
if (isset($ifdefs[$short])) printf("#endif\n");
}
-file_put_contents("src/php_http_client_curl.c",
+file_put_contents("src/php_http_client_curl.c",
preg_replace('/(\/\* BEGIN::CURLINFO \*\/\n).*(\n\s*\/\* END::CURLINFO \*\/)/s', '$1'. ob_get_contents() .'$2',
file_get_contents("src/php_http_client_curl.c")));
--- /dev/null
+#!/usr/bin/env php
+<?php
+
+error_reporting(E_ALL);
+set_error_handler(function($c, $e, $f, $l) {
+ throw new Exception("$e in $f on line $l");
+});
+
+$i18n = $argc >= 2 ? $argv[1] : "/usr/share/i18n/locales/i18n";
+
+$f = fopen($i18n, "r");
+$c = false;
+$a = false;
+
+ob_start(null, 0xfffff);
+
+while (!feof($f)) {
+ $line = fgets($f);
+ if (!$c && $line !== "LC_CTYPE\n") {
+ continue;
+ }
+ $c = true;
+ if ($line === "END LC_CTYPE\n") {
+ break;
+ }
+ switch($line{0}) {
+ case "%":
+ break;
+ case "\n":
+ if ($a) {
+ break 2;
+ }
+ break;
+ case " ":
+ if ($a) {
+ foreach (explode(";", trim($line, "\n/ ;")) as $ranges) {
+ $range = explode("..", $ranges);
+ $step = 0;
+ $end = 0;
+ switch (count($range)) {
+ case 3:
+ list($sstart, $sstep, $send) = $range;
+ sscanf($sstart, "<U%X>", $start);
+ sscanf($sstep, "(%d)", $step);
+ sscanf($send, "<U%X>", $end);
+
+ break;
+ case 2:
+ list($sstart, $send) = $range;
+ $step = 1;
+ sscanf($sstart, "<U%X>", $start);
+ sscanf($send, "<U%X>", $end);
+ break;
+ case 1:
+ list($sstart) = $range;
+ sscanf($sstart, "<U%X>", $start);
+ break;
+ }
+ $r[]=[$start,$end,$step];
+ }
+ }
+ break;
+ default:
+ if ($a) {
+ break 2;
+ } elseif ($line === "alpha /\n") {
+ $a = true;
+ }
+ break;
+ }
+}
+function sp($sp, $ch = " ") { return str_repeat($ch, $sp); }
+$sp = 1;
+foreach ($r as list($start, $end, $step)) {
+ if ($end) {
+ if ($step > 1) {
+ die("\nUNEXPECTED: step>1\n");
+ printf("\tfor (i=0x%08X; i <= 0x%08X; i+= %d) { if (i == ch) return 1; }\n", $start, $end, $step);
+ } else {
+ //printf(" if (ch >= 0x%08X && ch <= 0x%08X) return 1;\n", $start, $end);
+ printf("%sif (ch >= 0x%08X) {\n", sp($sp), $start);
+ printf("%sif (ch <= 0x%08X) return 1;\n", sp(++$sp), $end);
+ }
+ } else {
+ printf("%sif (ch == 0x%08X) return 1;\n", sp($sp), $start);
+ }
+}
+printf(" %s\n", sp($sp-1, "}"));
+
+file_put_contents("php_http_utf8.h",
+ preg_replace('/(\/\* BEGIN::UTF8SWITCH \*\/\n).*(\n\s*\/\* END::UTF8SWITCH \*\/)/s', '$1'. ob_get_contents() .'$2',
+ file_get_contents("php_http_utf8.h")));
#!/usr/bin/env php
<?php
-function m($m) {
+function m($m, $c = null) {
$n = "";
+ if ($c && $c->isInterface()) {
+ $m ^= ReflectionMethod::IS_ABSTRACT;
+ }
foreach (Reflection::getModifierNames($m) as $mn) {
$n .= $mn . " ";
}
foreach ($c->getMethods() as $m) {
if ($m->getDeclaringClass()->getName() == $c->getName()) {
- fprintf($out, "\t\t%sfunction %s(", m($m->getModifiers()),
+ fprintf($out, "\t\t%sfunction %s(", m($m->getModifiers(), $c),
$m->getName());
$ps = array();
foreach ($m->getParameters() as $p) {
--- /dev/null
+#!/usr/bin/env php
+<?php
+
+error_reporting(E_ALL);
+set_error_handler(function($c, $e, $f, $l) {
+ throw new Exception("$e in $f on line $l");
+});
+
+$i18n = $argc >= 2 ? $argv[1] : "/usr/share/i18n/locales/i18n";
+
+$b = 10;
+$m = 0xfffff000 >> $b;
+$b2 = 8;
+$x = $m >> $b2;
+
+$f = fopen($i18n, "r");
+$c = false;
+$a = false;
+
+$ranges = $lables = $gotos = [];
+
+ob_start(null, 0xfffff);
+
+while (!feof($f)) {
+ $line = fgets($f);
+ if (!$c && $line !== "LC_CTYPE\n") {
+ continue;
+ }
+ $c = true;
+ if ($line === "END LC_CTYPE\n") {
+ break;
+ }
+ switch($line{0}) {
+ case "%":
+ break;
+ case "\n":
+ if ($a) {
+ break 2;
+ }
+ break;
+ case " ":
+ if ($a) {
+ foreach (explode(";", trim($line, "\n/ ;")) as $list) {
+ $range = explode("..", $list);
+ $step = 0;
+ $end = 0;
+ switch (count($range)) {
+ case 3:
+ list($sstart, $sstep, $send) = $range;
+ sscanf($sstart, "<U%X>", $start);
+ sscanf($sstep, "(%d)", $step);
+ sscanf($send, "<U%X>", $end);
+
+ break;
+ case 2:
+ list($sstart, $send) = $range;
+ $step = 1;
+ sscanf($sstart, "<U%X>", $start);
+ sscanf($send, "<U%X>", $end);
+ break;
+ case 1:
+ list($sstart) = $range;
+ sscanf($sstart, "<U%X>", $start);
+ break;
+ }
+ $sw = $start >> $b;
+ $sw2 = ($start & $m) >> $b2;
+ if (isset($ranges[$sw][$sw2])) {
+ //$ranges[$sw][$sw2] = array_filter($ranges[$sw][$sw2]);
+ }
+ $ranges[$sw][$sw2][]=[$start,$end,$step];
+ if ($end) {
+ $goto = $start;
+ }
+ while (($start += $step) <= $end) {
+ $ssw = $start >> $b;
+ $ssw2 = ($start & $m) >> $b2;
+ if (!isset($ranges[$ssw][$ssw2]) || null !== end($ranges[$ssw][$ssw2])) {
+ $ranges[$ssw][$ssw2][]=null;
+ }
+ if ($ssw != $sw || $ssw2 != $sw2) {
+ $gotos[$ssw][$ssw2] = $goto;
+ $labels[$sw][$sw2] = $goto;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ if ($a) {
+ break 2;
+ } elseif ($line === "alpha /\n") {
+ $a = true;
+ }
+ break;
+ }
+}
+
+function sp($sp, $ch = " ") { return str_repeat($ch, $sp); }
+
+printf("switch (ch >> %d) {\n", $b);
+foreach ($ranges as $sw => $sws) {
+ printf("case 0x%08X:\n", $sw);
+ printf(" switch((ch & 0x%08X) >> %d) {\n", $m, $b2);
+ foreach ($sws as $sw2 => $specs) {
+ printf(" case 0x%08X:\n", $sw2);
+ $sp = 2;
+ $start = null;
+ foreach ($specs as $index => $spec) {
+ if ($spec) {
+ list($start, $end, $step) = $spec;
+ if (isset($labels[$sw][$sw2])) {
+ $label = $labels[$sw][$sw2];
+ if ((!$end && $label == $start) || ($end && $label >= $start && $label <= $end)) {
+ printf("%sc_%08X:;\n", sp($sp), $label);
+ }
+ }
+ if ($end) {
+ if ($step > 1) {
+ die("\nUNEXPECTED: step>1\n");
+ printf("\tfor (i=0x%08X; i <= 0x%08X; i+= %d) { if (i == ch) return 1; }\n", $start, $end, $step);
+ } else {
+ printf("%sif (ch >= 0x%08X) {\n", sp($sp), $start);
+ printf("%sif (ch <= 0x%08X) return 1;\n", sp(++$sp), $end);
+ }
+ } else {
+ printf("%sif (ch == 0x%08X) return 1;\n", sp($sp), $start);
+ }
+ } else {
+ if (isset($gotos[$sw][$sw2]) && !$start) {
+ if (isset($specs[$index + 1])) {
+ list($next) = $specs[$index + 1];
+ printf("%sif (ch < 0x%08X)\n ", sp($sp), $next);
+ }
+ $goto = $gotos[$sw][$sw2];
+ printf("%sgoto c_%08X;\n", sp($sp), $goto);
+ $start = $goto;
+ }
+ }
+ }
+ if ($sp > 2) {
+ printf(" %s\n", sp($sp-2, "}"));
+ }
+ printf(" break;\n");
+ }
+ printf(" }\n break;\n");
+}
+printf("}\n");
+
+file_put_contents("php_http_utf8.h",
+ preg_replace('/(\/\* BEGIN::UTF8SWITCH \*\/\n).*(\n\s*\/\* END::UTF8SWITCH \*\/)/s', '$1'. ob_get_contents() .'$2',
+ file_get_contents("php_http_utf8.h")));
#!/usr/bin/env php
# autogenerated file; do not edit
language: c
-sudo: required
+sudo: false
dist: trusty
addons:
- libicu-dev
- libevent-dev
+compiler:
+ - gcc
+ - clang
+
+cache:
+ directories:
+ - $HOME/cache
+before_cache:
+ - find $HOME/cache -name '*.gcda' -o -name '*.gcno' -delete
+
env:
<?php
$gen = include "./travis/pecl/gen-matrix.php";
+$cur = "7.2";
$env = $gen([
- "PHP" => ["7.0", "7.1", "master"],
+// most useful for all additional versions except current
+ "PHP" => ["7.0", "7.1", "7.3", "master"],
+ "enable_debug" => "yes",
+ "enable_maintainer_zts" => "yes",
+ "enable_json" => "yes",
+ "enable_hash" => "yes",
+ "enable_iconv" => "yes",
+ "with_http_libbrotli_dir" => "/home/travis/brotli"
+], [
+// everything disabled for current
+ "PHP" => $cur,
+ "with_http_libicu_dir" => "no",
+ "with_http_libidn_dir" => "no",
+ "with_http_libidn2_dir" => "no",
+ "with_http_libcurl_dir" => "no",
+ "with_http_libevent_dir" => "no",
+], [
+// everything enabled for current, switching on debug/zts
+ "PHP" => $cur,
"enable_debug",
"enable_maintainer_zts",
- "enable_json",
- "enable_hash" => ["yes"],
- "enable_iconv" => ["yes"],
- "with_http_libicu_dir",
+ "enable_json" => "yes",
+ "enable_hash" => "yes",
+ "enable_iconv" => "yes",
+ "with_http_libbrotli_dir" => "/home/travis/brotli",
+], [
+// once everything enabled for current, with coverage
+ "CFLAGS" => "'-O0 -g --coverage'",
+ "CXXFLAGS" => "'-O0 -g --coverage'",
+ "PHP" => $cur,
+ "enable_json" => "yes",
+ "enable_hash" => "yes",
+ "enable_iconv" => "yes",
+ "with_http_libbrotli_dir" => "/home/travis/brotli",
+ [
+ "with_http_libicu_dir",
+ "with_http_libidn_dir",
+ "with_http_libidn2_dir",
+ ],
]);
-foreach ($env as $e) {
- printf(" - %s\n", $e);
+foreach ($env as $grp) {
+ foreach ($grp as $e) {
+ printf(" - %s\n", $e);
+ }
}
?>
-# once with gcov
- - CFLAGS="-O0 -g --coverage" CXXFLAGS="-O0 -g --coverage" PHP=master enable_json=yes enable_hash=yes enable_iconv=yes
-before_script:
- - make -f travis/pecl/Makefile php
- - make -f travis/pecl/Makefile pecl PECL=raphf:raphf:2.0.0
- - make -f travis/pecl/Makefile pecl PECL=propro:propro:2.0.1
- - make -f travis/pecl/Makefile ext PECL=http
+install:
+ - ./travis/brotli.sh v1.0.2
+ - |
+ if test "$PHP" = master; then \
+ make -f travis/pecl/Makefile reconf; \
+ make -f travis/pecl/Makefile pecl-rm pecl-clean PECL=ext-raphf.git:raphf:master; \
+ make -f travis/pecl/Makefile pecl-rm pecl-clean PECL=ext-propro.git:propro:master; \
+ fi
+ - make -f travis/pecl/Makefile php || make -f travis/pecl/Makefile clean php
+ - make -f travis/pecl/Makefile pecl PECL=ext-raphf.git:raphf:master
+ - make -f travis/pecl/Makefile pecl PECL=ext-propro.git:propro:master
script:
+ - make -f travis/pecl/Makefile ext PECL=http
- make -f travis/pecl/Makefile test
- - make -f travis/pecl/Makefile cppcheck
+after_script:
+ - make -f travis/pecl/Makefile cppcheck
after_failure:
- test -e tests/helper/server.log && cat tests/helper/server.log
after_success:
$f = fopen($i18n, "r");
$c = false;
$a = false;
+$r = [];
+$n = [];
ob_start(null, 0xffff);
while (!feof($f)) {
sscanf($sstart, "<U%X>", $start);
break;
}
- print "\t{";
- if ($start >= 0xffff) {
- printf("0x%08X, ", $start);
- if ($end) {
- printf("0x%08X, ", $end);
- } else {
- print(" 0, ");
+ if ($end) {
+ if ($step != 1) {
+ die("UNEXPECTED step=$step\n");
}
+ $r[] = [$start, $end];
} else {
- printf(" 0x%04X, ", $start);
- if ($end) {
- printf(" 0x%04X, ", $end);
- } else {
- print(" 0, ");
- }
+ $n[] = $start;
}
- printf("%d},\n", $step);
}
}
break;
}
}
+$maxstep = 0;
+printf("static const utf8_range_t utf8_ranges[] = {\n\t{");
+foreach ($r as $i => list($start, $end)) {
+ if ($i) if ($i%3) {
+ printf(", {");
+ } else {
+ printf(",\n\t{");
+ }
+
+ printf("0x%08X, 0x%08X}", $start, $end);
+}
+printf("\n};\n\n");
+printf("static const unsigned utf8_chars[] = {\n\t");
+foreach ($n as $i => $u) {
+ if ($i) if (($i%6)) {
+ printf(", ");
+ } else {
+ printf(",\n\t");
+ }
+ printf("0x%08X", $u);
+}
+printf("\n};\n");
+
file_put_contents("php_http_utf8.h",
preg_replace('/(\/\* BEGIN::UTF8TABLE \*\/\n).*(\n\s*\/\* END::UTF8TABLE \*\/)/s', '$1'. ob_get_contents() .'$2',
file_get_contents("php_http_utf8.h")));
#if PHP_HTTP_HAVE_LIBICU
# include <unicode/uversion.h>
#endif
-#if PHP_HTTP_HAVE_LIBIDN2
-# include <idn2.h>
-#endif
#if PHP_HTTP_HAVE_LIBIDN
# include <idna.h>
#endif
+#if PHP_HTTP_HAVE_LIBIDN2
+# include <idn2.h>
+#endif
#if PHP_HTTP_HAVE_LIBIDNKIT2 || PHP_HTTP_HAVE_LIBIDNKIT
#include "idn/version.h"
#endif
|| SUCCESS != PHP_MINIT_CALL(http_exception)
|| SUCCESS != PHP_MINIT_CALL(http_cookie)
|| SUCCESS != PHP_MINIT_CALL(http_encoding)
+ || SUCCESS != PHP_MINIT_CALL(http_encoding_zlib)
+#if PHP_HTTP_HAVE_LIBBROTLI
+ || SUCCESS != PHP_MINIT_CALL(http_encoding_brotli)
+#endif
|| SUCCESS != PHP_MINIT_CALL(http_filter)
|| SUCCESS != PHP_MINIT_CALL(http_header)
|| SUCCESS != PHP_MINIT_CALL(http_header_parser)
#ifndef PHP_HTTP_API_H
#define PHP_HTTP_API_H
+#ifdef __COVERITY_GCC_VERSION_AT_LEAST
+# define _Float128 float
+# define _Float64 float
+# define _Float32 float
+# define _Float64x float
+# define _Float32x float
+#endif
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_http.h"
#include "php_http_cookie.h"
#include "php_http_encoding.h"
+#include "php_http_encoding_zlib.h"
+#include "php_http_encoding_brotli.h"
#include "php_http_info.h"
#include "php_http_message.h"
#include "php_http_env.h"
+--------------------------------------------------------------------+
*/
-#include "php.h"
+#include "php_http_api.h"
#include "php_http_buffer.h"
PHP_HTTP_BUFFER_API php_http_buffer_t *php_http_buffer_init_ex(
{
int free_buf = !!buf;
- if ((buf = php_http_buffer_init(buf))) {
+ if (EXPECTED(buf = php_http_buffer_init(buf))) {
if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_append(buf, str, len)) {
if (free_buf) {
pefree(buf, buf->pmem);
if (buf->free < len) {
size_t size = override_size ? override_size : buf->size;
- while ((size + buf->free) < len) {
+ while (UNEXPECTED((size + buf->free) < len)) {
size <<= 1;
}
) {
return PHP_HTTP_BUFFER_NOMEM;
}
- memcpy(buf->data + buf->used, append, append_len);
- buf->used += append_len;
- buf->free -= append_len;
+ if (append_len) {
+ memcpy(buf->data + buf->used, append, append_len);
+ buf->used += append_len;
+ buf->free -= append_len;
+ }
return append_len;
}
char **into, size_t *len)
{
char *copy = ecalloc(1, buf->used + 1);
- memcpy(copy, buf->data, buf->used);
+ if (buf->data) {
+ memcpy(copy, buf->data, buf->used);
+ }
if (into) {
*into = copy;
}
php_http_buffer_t *str;
size_t passed;
- if (!*s) {
+ if (UNEXPECTED(!*s)) {
*s = php_http_buffer_init_ex(NULL, chunk_size,
chunk_size ? PHP_HTTP_BUFFER_INIT_PREALLOC : 0);
}
#ifndef PTR_FREE
# define PTR_FREE(PTR) \
{ \
- if (PTR) { \
+ if (EXPECTED(PTR)) { \
efree(PTR); \
} \
}
zend_fcall_info_cache fcc = empty_fcall_info_cache;
php_http_client_object_t *obj;
php_http_message_object_t *msg_obj;
- php_http_client_enqueue_t q;
+ php_http_client_enqueue_t q = {0};
php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O|f", &request, php_http_get_client_request_class_entry(), &fci, &fcc), invalid_arg, return);
return;
}
+ /* set early for progress callback */
+ q.opaque = msg_obj;
+
+ if (obj->client->callback.progress.func) {
+ php_http_client_progress_state_t progress = {0};
+
+ progress.info = "prepare";
+ obj->client->callback.progress.func(obj->client->callback.progress.arg, obj->client, &q, &progress);
+ }
+
+ Z_ADDREF_P(request);
q.request = msg_obj->message;
q.options = combined_options(getThis(), request);
q.dtor = msg_queue_dtor;
if (fci.size) {
Z_TRY_ADDREF(fci.function_name);
if (fci.object) {
- ++GC_REFCOUNT(fci.object);
+ GC_ADDREF(fci.object);
}
}
- Z_ADDREF_P(request);
-
php_http_expect(SUCCESS == php_http_client_enqueue(obj->client, &q), runtime,
msg_queue_dtor(&q);
return;
if (fci.size) {
Z_TRY_ADDREF(fci.function_name);
if (fci.object) {
- ++GC_REFCOUNT(fci.object);
+ GC_ADDREF(fci.object);
}
}
}
static zend_function_entry php_http_client_methods[] = {
- PHP_ME(HttpClient, __construct, ai_HttpClient_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpClient, __construct, ai_HttpClient_construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpClient, reset, ai_HttpClient_reset, ZEND_ACC_PUBLIC)
PHP_ME(HttpClient, enqueue, ai_HttpClient_enqueue, ZEND_ACC_PUBLIC)
PHP_ME(HttpClient, dequeue, ai_HttpClient_dequeue, ZEND_ACC_PUBLIC)
switch (type) {
case CURLINFO_TEXT:
if (data[0] == '-') {
+ goto text;
} else if (php_memnstr(data, ZEND_STRL("Adding handle:"), data + length)) {
h->progress.info = "setup";
} else if (php_memnstr(data, ZEND_STRL("addHandle"), data + length)) {
h->progress.info = "connected";
} else if (php_memnstr(data, ZEND_STRL("blacklisted"), data + length)) {
h->progress.info = "blacklist check";
+ } else if (php_memnstr(data, ZEND_STRL("TLS"), data + length)) {
+ h->progress.info = "ssl negotiation";
} else if (php_memnstr(data, ZEND_STRL("SSL"), data + length)) {
h->progress.info = "ssl negotiation";
+ } else if (php_memnstr(data, ZEND_STRL("certificate"), data + length)) {
+ h->progress.info = "ssl negotiation";
+ } else if (php_memnstr(data, ZEND_STRL("ALPN"), data + length)) {
+ h->progress.info = "alpn";
+ } else if (php_memnstr(data, ZEND_STRL("NPN"), data + length)) {
+ h->progress.info = "npn";
} else if (php_memnstr(data, ZEND_STRL("upload"), data + length)) {
h->progress.info = "uploaded";
} else if (php_memnstr(data, ZEND_STRL("left intact"), data + length)) {
} else if (php_memnstr(data, ZEND_STRL("Operation timed out"), data + length)) {
h->progress.info = "timeout";
} else {
+ text:;
#if 0
h->progress.info = data;
data[length - 1] = '\0';
zend_hash_str_update(info, "http_version", lenof("http_version"), &tmp);
}
#endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROXY_SSL_VERIFYRESULT, &l)) {
+ ZVAL_LONG(&tmp, l);
+ zend_hash_str_update(info, "proxy_ssl_verifyresult", lenof("proxy_ssl_verifyresult"), &tmp);
+ }
+#endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROTOCOL, &l)) {
+ ZVAL_LONG(&tmp, l);
+ zend_hash_str_update(info, "protocol", lenof("protocol"), &tmp);
+ }
+#endif
+#if PHP_HTTP_CURL_VERSION(7,52,0)
+ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SCHEME, &c)) {
+ ZVAL_STRING(&tmp, STR_PTR(c));
+ zend_hash_str_update(info, "scheme", lenof("scheme"), &tmp);
+ }
+#endif
/* END::CURLINFO */
zval ti_array, subarray;
struct curl_tlssessioninfo *ti;
+#if PHP_HTTP_CURL_VERSION(7,48,0)
+ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SSL_PTR, &ti)) {
+#else
if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SESSION, &ti)) {
+#endif
char *backend;
ZVAL_NULL(&subarray);
backend = "openssl";
#if PHP_HTTP_HAVE_LIBCURL_OPENSSL
{
+#if PHP_HTTP_CURL_VERSION(7,48,0)
+ SSL *ssl = ti->internals;
+ SSL_CTX *ctx = ssl ? SSL_get_SSL_CTX(ssl) : NULL;
+#else
SSL_CTX *ctx = ti->internals;
+#endif
array_init(&subarray);
- add_assoc_long_ex(&subarray, ZEND_STRL("number"), SSL_CTX_sess_number(ctx));
- add_assoc_long_ex(&subarray, ZEND_STRL("connect"), SSL_CTX_sess_connect(ctx));
- add_assoc_long_ex(&subarray, ZEND_STRL("connect_good"), SSL_CTX_sess_connect_good(ctx));
- add_assoc_long_ex(&subarray, ZEND_STRL("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx));
- add_assoc_long_ex(&subarray, ZEND_STRL("hits"), SSL_CTX_sess_hits(ctx));
- add_assoc_long_ex(&subarray, ZEND_STRL("cache_full"), SSL_CTX_sess_cache_full(ctx));
+ if (ctx) {
+ add_assoc_long_ex(&subarray, ZEND_STRL("number"), SSL_CTX_sess_number(ctx));
+ add_assoc_long_ex(&subarray, ZEND_STRL("connect"), SSL_CTX_sess_connect(ctx));
+ add_assoc_long_ex(&subarray, ZEND_STRL("connect_good"), SSL_CTX_sess_connect_good(ctx));
+ add_assoc_long_ex(&subarray, ZEND_STRL("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx));
+ add_assoc_long_ex(&subarray, ZEND_STRL("hits"), SSL_CTX_sess_hits(ctx));
+ add_assoc_long_ex(&subarray, ZEND_STRL("cache_full"), SSL_CTX_sess_cache_full(ctx));
+ }
}
#endif
break;
char *desc;
array_init(&subarray);
- if ((desc = gnutls_session_get_desc(sess))) {
- add_assoc_string_ex(&subarray, ZEND_STRL("desc"), desc);
- gnutls_free(desc);
+ if (sess) {
+ if ((desc = gnutls_session_get_desc(sess))) {
+ add_assoc_string_ex(&subarray, ZEND_STRL("desc"), desc);
+ gnutls_free(desc);
+ }
+ add_assoc_bool_ex(&subarray, ZEND_STRL("resumed"), gnutls_session_is_resumed(sess));
}
- add_assoc_bool_ex(&subarray, ZEND_STRL("resumed"), gnutls_session_is_resumed(sess));
}
#endif
break;
php_http_client_curl_user_context_t *context;
} php_http_client_curl_user_ev_t;
-static void php_http_client_curl_user_handler(INTERNAL_FUNCTION_PARAMETERS)
+static ZEND_NAMED_FUNCTION(php_http_client_curl_user_handler)
{
zval *zstream = NULL, *zclient = NULL;
php_stream *stream = NULL;
}
static zend_function_entry php_http_client_request_methods[] = {
- PHP_ME(HttpClientRequest, __construct, ai_HttpClientRequest___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpClientRequest, __construct, ai_HttpClientRequest___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpClientRequest, setContentType, ai_HttpClientRequest_setContentType, ZEND_ACC_PUBLIC)
PHP_ME(HttpClientRequest, getContentType, ai_HttpClientRequest_getContentType, ZEND_ACC_PUBLIC)
PHP_ME(HttpClientRequest, setQuery, ai_HttpClientRequest_setQuery, ZEND_ACC_PUBLIC)
#include "php_http_api.h"
-#include <zlib.h>
-
static inline int eol_match(char **line, int *eol_len)
{
char *ptr = *line;
return e_ptr;
}
-static inline int php_http_inflate_rounds(z_stream *Z, int flush, char **buf, size_t *len)
-{
- int status = 0, round = 0;
- php_http_buffer_t buffer;
-
- *buf = NULL;
- *len = 0;
-
- php_http_buffer_init_ex(&buffer, Z->avail_in, PHP_HTTP_BUFFER_INIT_PREALLOC);
-
- do {
- if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize_ex(&buffer, buffer.size, 0, 1)) {
- status = Z_MEM_ERROR;
- } else {
- Z->avail_out = buffer.free;
- Z->next_out = (Bytef *) buffer.data + buffer.used;
-#if 0
- fprintf(stderr, "\n%3d: %3d PRIOR: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
-#endif
- status = inflate(Z, flush);
- php_http_buffer_account(&buffer, buffer.free - Z->avail_out);
-#if 0
- fprintf(stderr, "%3d: %3d AFTER: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
-#endif
- PHP_HTTP_INFLATE_BUFFER_SIZE_ALIGN(buffer.size);
- }
- } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < PHP_HTTP_INFLATE_ROUNDS);
-
- if (status == Z_OK || status == Z_STREAM_END) {
- php_http_buffer_shrink(&buffer);
- php_http_buffer_fix(&buffer);
- *buf = buffer.data;
- *len = buffer.used;
- } else {
- php_http_buffer_dtor(&buffer);
- }
-
- return status;
-}
-
-ZEND_RESULT_CODE php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
-{
- int status, level, wbits, strategy;
- z_stream Z;
-
- PHP_HTTP_DEFLATE_LEVEL_SET(flags, level);
- PHP_HTTP_DEFLATE_WBITS_SET(flags, wbits);
- PHP_HTTP_DEFLATE_STRATEGY_SET(flags, strategy);
-
- memset(&Z, 0, sizeof(z_stream));
- *encoded = NULL;
- *encoded_len = 0;
-
- status = deflateInit2(&Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy);
- if (Z_OK == status) {
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
- *encoded = emalloc(*encoded_len);
-
- Z.next_in = (Bytef *) data;
- Z.next_out = (Bytef *) *encoded;
- Z.avail_in = data_len;
- Z.avail_out = *encoded_len;
-
- status = deflate(&Z, Z_FINISH);
- deflateEnd(&Z);
-
- if (Z_STREAM_END == status) {
- /* size buffer down to actual length */
- *encoded = erealloc(*encoded, Z.total_out + 1);
- (*encoded)[*encoded_len = Z.total_out] = '\0';
- return SUCCESS;
- } else {
- PTR_SET(*encoded, NULL);
- *encoded_len = 0;
- }
- }
-
- php_error_docref(NULL, E_WARNING, "Could not deflate data: %s", zError(status));
- return FAILURE;
-}
-
-ZEND_RESULT_CODE php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len)
-{
- z_stream Z;
- int status, wbits = PHP_HTTP_WINDOW_BITS_ANY;
-
- memset(&Z, 0, sizeof(z_stream));
-
-retry_raw_inflate:
- status = inflateInit2(&Z, wbits);
- if (Z_OK == status) {
- Z.next_in = (Bytef *) data;
- Z.avail_in = data_len + 1; /* include the terminating NULL, see #61287 */
-
- switch (status = php_http_inflate_rounds(&Z, Z_NO_FLUSH, decoded, decoded_len)) {
- case Z_STREAM_END:
- inflateEnd(&Z);
- return SUCCESS;
-
- case Z_OK:
- status = Z_DATA_ERROR;
- break;
-
- case Z_DATA_ERROR:
- /* raw deflated data? */
- if (PHP_HTTP_WINDOW_BITS_ANY == wbits) {
- inflateEnd(&Z);
- wbits = PHP_HTTP_WINDOW_BITS_RAW;
- goto retry_raw_inflate;
- }
- break;
- }
- inflateEnd(&Z);
-
- if (*decoded_len && *decoded) {
- efree(*decoded);
- }
- }
-
- php_error_docref(NULL, E_WARNING, "Could not inflate data: %s", zError(status));
- return FAILURE;
-}
-
php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_encoding_stream_t *s, php_http_encoding_stream_ops_t *ops, unsigned flags)
{
int freeme;
s->flags = flags;
- if ((s->ops = ops)) {
+ if (EXPECTED(s->ops = ops)) {
php_http_encoding_stream_t *ss = s->ops->init(s);
- if (ss) {
+ if (EXPECTED(ss)) {
return ss;
}
} else {
{
php_http_encoding_stream_t *ss;
- if ((*s)->ops->dtor) {
+ if (EXPECTED((*s)->ops->dtor)) {
(*s)->ops->dtor(*s);
}
- if ((ss = (*s)->ops->init(*s))) {
+
+ if (EXPECTED(ss = (*s)->ops->init(*s))) {
+ ss->flags &= ~PHP_HTTP_ENCODING_STREAM_DIRTY;
*s = ss;
return SUCCESS;
}
ZEND_RESULT_CODE php_http_encoding_stream_update(php_http_encoding_stream_t *s, const char *in_str, size_t in_len, char **out_str, size_t *out_len)
{
- if (!s->ops->update) {
- return FAILURE;
+ ZEND_RESULT_CODE rc = FAILURE;
+
+ if (EXPECTED(s->ops->update)) {
+ rc = s->ops->update(s, in_str, in_len, out_str, out_len);
}
- return s->ops->update(s, in_str, in_len, out_str, out_len);
+
+ s->flags |= PHP_HTTP_ENCODING_STREAM_DIRTY;
+
+ return rc;
}
ZEND_RESULT_CODE php_http_encoding_stream_flush(php_http_encoding_stream_t *s, char **out_str, size_t *out_len)
zend_bool php_http_encoding_stream_done(php_http_encoding_stream_t *s)
{
if (!s->ops->done) {
- return 0;
+ return !(s->flags & PHP_HTTP_ENCODING_STREAM_DIRTY);
}
return s->ops->done(s);
}
if (!s->ops->finish) {
*out_str = NULL;
*out_len = 0;
+
+ s->flags &= ~PHP_HTTP_ENCODING_STREAM_DIRTY;
+
return SUCCESS;
}
return s->ops->finish(s, out_str, out_len);
void php_http_encoding_stream_dtor(php_http_encoding_stream_t *s)
{
- if (s->ops->dtor) {
+ if (EXPECTED(s->ops->dtor)) {
s->ops->dtor(s);
}
}
void php_http_encoding_stream_free(php_http_encoding_stream_t **s)
{
- if (*s) {
- if ((*s)->ops->dtor) {
+ if (EXPECTED(*s)) {
+ if (EXPECTED((*s)->ops->dtor)) {
(*s)->ops->dtor(*s);
}
pefree(*s, ((*s)->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
unsigned zeroed:1;
};
-static php_http_encoding_stream_t *deflate_init(php_http_encoding_stream_t *s)
-{
- int status, level, wbits, strategy, p = (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT);
- z_streamp ctx = pecalloc(1, sizeof(z_stream), p);
-
- PHP_HTTP_DEFLATE_LEVEL_SET(s->flags, level);
- PHP_HTTP_DEFLATE_WBITS_SET(s->flags, wbits);
- PHP_HTTP_DEFLATE_STRATEGY_SET(s->flags, strategy);
-
- if (Z_OK == (status = deflateInit2(ctx, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy))) {
- if ((ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
- s->ctx = ctx;
- return s;
- }
- deflateEnd(ctx);
- status = Z_MEM_ERROR;
- }
- pefree(ctx, p);
- php_error_docref(NULL, E_WARNING, "Failed to initialize deflate encoding stream: %s", zError(status));
- return NULL;
-}
-
-static php_http_encoding_stream_t *inflate_init(php_http_encoding_stream_t *s)
-{
- int status, wbits, p = (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT);
- z_streamp ctx = pecalloc(1, sizeof(z_stream), p);
-
- PHP_HTTP_INFLATE_WBITS_SET(s->flags, wbits);
-
- if (Z_OK == (status = inflateInit2(ctx, wbits))) {
- if ((ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
- s->ctx = ctx;
- return s;
- }
- inflateEnd(ctx);
- status = Z_MEM_ERROR;
- }
- pefree(ctx, p);
- php_error_docref(NULL, E_WARNING, "Failed to initialize inflate stream: %s", zError(status));
- return NULL;
-}
-
static php_http_encoding_stream_t *dechunk_init(php_http_encoding_stream_t *s)
{
struct dechunk_ctx *ctx = pecalloc(1, sizeof(*ctx), (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
return s;
}
-static php_http_encoding_stream_t *deflate_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to)
-{
- int status, p = to->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT;
- z_streamp from_ctx = from->ctx, to_ctx = pecalloc(1, sizeof(*to_ctx), p);
-
- if (Z_OK == (status = deflateCopy(to_ctx, from_ctx))) {
- if ((to_ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
- php_http_buffer_append(to_ctx->opaque, PHP_HTTP_BUFFER(from_ctx->opaque)->data, PHP_HTTP_BUFFER(from_ctx->opaque)->used);
- to->ctx = to_ctx;
- return to;
- }
- deflateEnd(to_ctx);
- status = Z_MEM_ERROR;
- }
- php_error_docref(NULL, E_WARNING, "Failed to copy deflate encoding stream: %s", zError(status));
- return NULL;
-}
-
-static php_http_encoding_stream_t *inflate_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to)
-{
- int status, p = from->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT;
- z_streamp from_ctx = from->ctx, to_ctx = pecalloc(1, sizeof(*to_ctx), p);
-
- if (Z_OK == (status = inflateCopy(to_ctx, from_ctx))) {
- if ((to_ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
- php_http_buffer_append(to_ctx->opaque, PHP_HTTP_BUFFER(from_ctx->opaque)->data, PHP_HTTP_BUFFER(from_ctx->opaque)->used);
- to->ctx = to_ctx;
- return to;
- }
- inflateEnd(to_ctx);
- status = Z_MEM_ERROR;
- }
- php_error_docref(NULL, E_WARNING, "Failed to copy inflate encoding stream: %s", zError(status));
- return NULL;
-}
-
static php_http_encoding_stream_t *dechunk_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to)
{
int p = from->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT;
return NULL;
}
-static ZEND_RESULT_CODE deflate_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
-{
- int status;
- z_streamp ctx = s->ctx;
-
- /* append input to our buffer */
- php_http_buffer_append(PHP_HTTP_BUFFER(ctx->opaque), data, data_len);
-
- ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
- ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
-
- /* deflate */
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
- *encoded = emalloc(*encoded_len);
- ctx->avail_out = *encoded_len;
- ctx->next_out = (Bytef *) *encoded;
-
- switch (status = deflate(ctx, PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags))) {
- case Z_OK:
- case Z_STREAM_END:
- /* cut processed chunk off the buffer */
- if (ctx->avail_in) {
- php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
- } else {
- php_http_buffer_reset(PHP_HTTP_BUFFER(ctx->opaque));
- }
-
- /* size buffer down to actual size */
- *encoded_len -= ctx->avail_out;
- *encoded = erealloc(*encoded, *encoded_len + 1);
- (*encoded)[*encoded_len] = '\0';
- return SUCCESS;
- }
-
- PTR_SET(*encoded, NULL);
- *encoded_len = 0;
- php_error_docref(NULL, E_WARNING, "Failed to update deflate stream: %s", zError(status));
- return FAILURE;
-}
-
-static ZEND_RESULT_CODE inflate_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len)
-{
- int status;
- z_streamp ctx = s->ctx;
-
- /* append input to buffer */
- php_http_buffer_append(PHP_HTTP_BUFFER(ctx->opaque), data, data_len);
-
-retry_raw_inflate:
- ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
- ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
-
- switch (status = php_http_inflate_rounds(ctx, PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags), decoded, decoded_len)) {
- case Z_OK:
- case Z_STREAM_END:
- /* cut off */
- if (ctx->avail_in) {
- php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
- } else {
- php_http_buffer_reset(PHP_HTTP_BUFFER(ctx->opaque));
- }
- return SUCCESS;
-
- case Z_DATA_ERROR:
- /* raw deflated data ? */
- if (!(s->flags & PHP_HTTP_INFLATE_TYPE_RAW) && !ctx->total_out) {
- inflateEnd(ctx);
- s->flags |= PHP_HTTP_INFLATE_TYPE_RAW;
- inflateInit2(ctx, PHP_HTTP_WINDOW_BITS_RAW);
- goto retry_raw_inflate;
- }
- break;
- }
-
- php_error_docref(NULL, E_WARNING, "Failed to update inflate stream: %s", zError(status));
- return FAILURE;
-}
-
static ZEND_RESULT_CODE dechunk_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len)
{
php_http_buffer_t tmp;
return SUCCESS;
}
-static ZEND_RESULT_CODE deflate_flush(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
-{
- int status;
- z_streamp ctx = s->ctx;
-
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE;
- *encoded = emalloc(*encoded_len);
-
- ctx->avail_in = 0;
- ctx->next_in = NULL;
- ctx->avail_out = *encoded_len;
- ctx->next_out = (Bytef *) *encoded;
-
- switch (status = deflate(ctx, Z_FULL_FLUSH)) {
- case Z_OK:
- case Z_STREAM_END:
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE - ctx->avail_out;
- *encoded = erealloc(*encoded, *encoded_len + 1);
- (*encoded)[*encoded_len] = '\0';
- return SUCCESS;
- }
-
- PTR_SET(*encoded, NULL);
- *encoded_len = 0;
- php_error_docref(NULL, E_WARNING, "Failed to flush deflate stream: %s", zError(status));
- return FAILURE;
-}
-
static ZEND_RESULT_CODE dechunk_flush(php_http_encoding_stream_t *s, char **decoded, size_t *decoded_len)
{
struct dechunk_ctx *ctx = s->ctx;
return SUCCESS;
}
-static ZEND_RESULT_CODE deflate_finish(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
-{
- int status;
- z_streamp ctx = s->ctx;
-
- *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE;
- *encoded = emalloc(*encoded_len);
-
- /* deflate remaining input */
- ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
- ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
-
- ctx->avail_out = *encoded_len;
- ctx->next_out = (Bytef *) *encoded;
-
- do {
- status = deflate(ctx, Z_FINISH);
- } while (Z_OK == status);
-
- if (Z_STREAM_END == status) {
- /* cut processed input off */
- php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
-
- /* size down */
- *encoded_len -= ctx->avail_out;
- *encoded = erealloc(*encoded, *encoded_len + 1);
- (*encoded)[*encoded_len] = '\0';
- return SUCCESS;
- }
-
- PTR_SET(*encoded, NULL);
- *encoded_len = 0;
- php_error_docref(NULL, E_WARNING, "Failed to finish deflate stream: %s", zError(status));
- return FAILURE;
-}
-
-static ZEND_RESULT_CODE inflate_finish(php_http_encoding_stream_t *s, char **decoded, size_t *decoded_len)
-{
- int status;
- z_streamp ctx = s->ctx;
-
- if (!PHP_HTTP_BUFFER(ctx->opaque)->used) {
- *decoded = NULL;
- *decoded_len = 0;
- return SUCCESS;
- }
-
- *decoded_len = (PHP_HTTP_BUFFER(ctx->opaque)->used + 1) * PHP_HTTP_INFLATE_ROUNDS;
- *decoded = emalloc(*decoded_len);
-
- /* inflate remaining input */
- ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
- ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
-
- ctx->avail_out = *decoded_len;
- ctx->next_out = (Bytef *) *decoded;
-
- if (Z_STREAM_END == (status = inflate(ctx, Z_FINISH))) {
- /* cut processed input off */
- php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
-
- /* size down */
- *decoded_len -= ctx->avail_out;
- *decoded = erealloc(*decoded, *decoded_len + 1);
- (*decoded)[*decoded_len] = '\0';
- return SUCCESS;
- }
-
- PTR_SET(*decoded, NULL);
- *decoded_len = 0;
- php_error_docref(NULL, E_WARNING, "Failed to finish inflate stream: %s", zError(status));
- return FAILURE;
-}
-
-static zend_bool deflate_done(php_http_encoding_stream_t *s)
-{
- z_streamp ctx = s->ctx;
- return !ctx->avail_in && !PHP_HTTP_BUFFER(ctx->opaque)->used;
-}
-static zend_bool inflate_done(php_http_encoding_stream_t *s)
-{
- z_streamp ctx = s->ctx;
- return !ctx->avail_in && !PHP_HTTP_BUFFER(ctx->opaque)->used;
-}
static zend_bool dechunk_done(php_http_encoding_stream_t *s)
{
return ((struct dechunk_ctx *) s->ctx)->zeroed;
}
-static void deflate_dtor(php_http_encoding_stream_t *s)
-{
- if (s->ctx) {
- z_streamp ctx = s->ctx;
-
- if (ctx->opaque) {
- php_http_buffer_free((php_http_buffer_t **) &ctx->opaque);
- }
- deflateEnd(ctx);
- pefree(ctx, (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
- s->ctx = NULL;
- }
-}
-
-static void inflate_dtor(php_http_encoding_stream_t *s)
-{
- if (s->ctx) {
- z_streamp ctx = s->ctx;
-
- if (ctx->opaque) {
- php_http_buffer_free((php_http_buffer_t **) &ctx->opaque);
- }
- inflateEnd(ctx);
- pefree(ctx, (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
- s->ctx = NULL;
- }
-}
-
static void dechunk_dtor(php_http_encoding_stream_t *s)
{
if (s->ctx) {
}
}
-static php_http_encoding_stream_ops_t php_http_encoding_deflate_ops = {
- deflate_init,
- deflate_copy,
- deflate_update,
- deflate_flush,
- deflate_done,
- deflate_finish,
- deflate_dtor
-};
-
-php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void)
-{
- return &php_http_encoding_deflate_ops;
-}
-
-static php_http_encoding_stream_ops_t php_http_encoding_inflate_ops = {
- inflate_init,
- inflate_copy,
- inflate_update,
- NULL,
- inflate_done,
- inflate_finish,
- inflate_dtor
-};
-
-php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void)
-{
- return &php_http_encoding_inflate_ops;
-}
-
static php_http_encoding_stream_ops_t php_http_encoding_dechunk_ops = {
dechunk_init,
dechunk_copy,
zend_object *php_http_encoding_stream_object_clone(zval *object)
{
- php_http_encoding_stream_object_t *new_obj = NULL, *old_obj = PHP_HTTP_OBJ(NULL, object);
+ php_http_encoding_stream_object_t *new_obj, *old_obj = PHP_HTTP_OBJ(NULL, object);
php_http_encoding_stream_t *cpy = php_http_encoding_stream_copy(old_obj->stream, NULL);
+ if (!cpy) {
+ return NULL;
+ }
+
new_obj = php_http_encoding_stream_object_new_ex(old_obj->zo.ce, cpy);
zend_objects_clone_members(&new_obj->zo, &old_obj->zo);
{
return php_http_encoding_stream_class_entry;
}
-static zend_class_entry *php_http_deflate_stream_class_entry;
-zend_class_entry *php_http_get_deflate_stream_class_entry(void)
-{
- return php_http_deflate_stream_class_entry;
-}
-static zend_class_entry *php_http_inflate_stream_class_entry;
-zend_class_entry *php_http_get_inflate_stream_class_entry(void)
-{
- return php_http_inflate_stream_class_entry;
-}
+
static zend_class_entry *php_http_dechunk_stream_class_entry;
zend_class_entry *php_http_get_dechunk_stream_class_entry(void)
{
obj = PHP_HTTP_OBJ(NULL, getThis());
- if (obj->stream) {
+ if (UNEXPECTED(obj->stream)) {
php_http_throw(bad_method_call, "http\\Encoding\\Stream cannot be initialized twice", NULL);
return;
}
- if (instanceof_function(obj->zo.ce, php_http_deflate_stream_class_entry)) {
- ops = &php_http_encoding_deflate_ops;
- } else if (instanceof_function(obj->zo.ce, php_http_inflate_stream_class_entry)) {
- ops = &php_http_encoding_inflate_ops;
+ if (instanceof_function(obj->zo.ce, php_http_get_deflate_stream_class_entry())) {
+ ops = php_http_encoding_stream_get_deflate_ops();
+ } else if (instanceof_function(obj->zo.ce, php_http_get_inflate_stream_class_entry())) {
+ ops = php_http_encoding_stream_get_inflate_ops();
} else if (instanceof_function(obj->zo.ce, php_http_dechunk_stream_class_entry)) {
ops = &php_http_encoding_dechunk_ops;
+#if PHP_HTTP_HAVE_LIBBROTLI
+ } else if (instanceof_function(obj->zo.ce, php_http_get_enbrotli_stream_class_entry())) {
+ ops = php_http_encoding_stream_get_enbrotli_ops();
+ } else if (instanceof_function(obj->zo.ce, php_http_get_debrotli_stream_class_entry())) {
+ ops = php_http_encoding_stream_get_debrotli_ops();
+#endif
} else {
php_http_throw(runtime, "Unknown http\\Encoding\\Stream class '%s'", obj->zo.ce->name->val);
return;
size_t data_len;
char *data_str;
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len)) {
+ if (EXPECTED(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data_str, &data_len))) {
php_http_encoding_stream_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
- if (obj->stream) {
+ if (EXPECTED(obj->stream)) {
char *encoded_str = NULL;
size_t encoded_len;
- if (SUCCESS == php_http_encoding_stream_update(obj->stream, data_str, data_len, &encoded_str, &encoded_len)) {
- if (encoded_str) {
+ if (EXPECTED(SUCCESS == php_http_encoding_stream_update(obj->stream, data_str, data_len, &encoded_str, &encoded_len))) {
+ if (EXPECTED(encoded_str)) {
RETURN_STR(php_http_cs2zs(encoded_str, encoded_len));
} else {
RETURN_EMPTY_STRING();
ZEND_END_ARG_INFO();
static PHP_METHOD(HttpEncodingStream, flush)
{
- if (SUCCESS == zend_parse_parameters_none()) {
+ if (EXPECTED(SUCCESS == zend_parse_parameters_none())) {
php_http_encoding_stream_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
- if (obj->stream) {
+ if (EXPECTED(obj->stream)) {
char *encoded_str = NULL;
size_t encoded_len;
- if (SUCCESS == php_http_encoding_stream_flush(obj->stream, &encoded_str, &encoded_len)) {
+ if (EXPECTED(SUCCESS == php_http_encoding_stream_flush(obj->stream, &encoded_str, &encoded_len))) {
if (encoded_str) {
RETURN_STR(php_http_cs2zs(encoded_str, encoded_len));
} else {
ZEND_END_ARG_INFO();
static PHP_METHOD(HttpEncodingStream, done)
{
- if (SUCCESS == zend_parse_parameters_none()) {
+ if (EXPECTED(SUCCESS == zend_parse_parameters_none())) {
php_http_encoding_stream_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
- if (obj->stream) {
+ if (EXPECTED(obj->stream)) {
RETURN_BOOL(php_http_encoding_stream_done(obj->stream));
}
}
ZEND_END_ARG_INFO();
static PHP_METHOD(HttpEncodingStream, finish)
{
- if (SUCCESS == zend_parse_parameters_none()) {
+ if (EXPECTED(SUCCESS == zend_parse_parameters_none())) {
php_http_encoding_stream_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
- if (obj->stream) {
+ if (EXPECTED(obj->stream)) {
char *encoded_str = NULL;
size_t encoded_len;
- if (SUCCESS == php_http_encoding_stream_finish(obj->stream, &encoded_str, &encoded_len)) {
- if (SUCCESS == php_http_encoding_stream_reset(&obj->stream)) {
+ if (EXPECTED(SUCCESS == php_http_encoding_stream_finish(obj->stream, &encoded_str, &encoded_len))) {
+ if (EXPECTED(SUCCESS == php_http_encoding_stream_reset(&obj->stream))) {
if (encoded_str) {
RETURN_STR(php_http_cs2zs(encoded_str, encoded_len));
} else {
}
static zend_function_entry php_http_encoding_stream_methods[] = {
- PHP_ME(HttpEncodingStream, __construct, ai_HttpEncodingStream___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpEncodingStream, __construct, ai_HttpEncodingStream___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpEncodingStream, update, ai_HttpEncodingStream_update, ZEND_ACC_PUBLIC)
PHP_ME(HttpEncodingStream, flush, ai_HttpEncodingStream_flush, ZEND_ACC_PUBLIC)
PHP_ME(HttpEncodingStream, done, ai_HttpEncodingStream_done, ZEND_ACC_PUBLIC)
EMPTY_FUNCTION_ENTRY
};
-ZEND_BEGIN_ARG_INFO_EX(ai_HttpDeflateStream_encode, 0, 0, 1)
- ZEND_ARG_INFO(0, data)
- ZEND_ARG_INFO(0, flags)
-ZEND_END_ARG_INFO();
-static PHP_METHOD(HttpDeflateStream, encode)
-{
- char *str;
- size_t len;
- zend_long flags = 0;
-
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &len, &flags)) {
- char *enc_str = NULL;
- size_t enc_len;
-
- if (SUCCESS == php_http_encoding_deflate(flags, str, len, &enc_str, &enc_len)) {
- if (enc_str) {
- RETURN_STR(php_http_cs2zs(enc_str, enc_len));
- } else {
- RETURN_EMPTY_STRING();
- }
- }
- }
- RETURN_FALSE;
-}
-
-static zend_function_entry php_http_deflate_stream_methods[] = {
- PHP_ME(HttpDeflateStream, encode, ai_HttpDeflateStream_encode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- EMPTY_FUNCTION_ENTRY
-};
-
-ZEND_BEGIN_ARG_INFO_EX(ai_HttpInflateStream_decode, 0, 0, 1)
- ZEND_ARG_INFO(0, data)
-ZEND_END_ARG_INFO();
-static PHP_METHOD(HttpInflateStream, decode)
-{
- char *str;
- size_t len;
-
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
- char *enc_str = NULL;
- size_t enc_len;
-
- if (SUCCESS == php_http_encoding_inflate(str, len, &enc_str, &enc_len)) {
- if (enc_str) {
- RETURN_STR(php_http_cs2zs(enc_str, enc_len));
- } else {
- RETURN_EMPTY_STRING();
- }
- }
- }
- RETURN_FALSE;
-}
-
-static zend_function_entry php_http_inflate_stream_methods[] = {
- PHP_ME(HttpInflateStream, decode, ai_HttpInflateStream_decode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
- EMPTY_FUNCTION_ENTRY
-};
-
ZEND_BEGIN_ARG_INFO_EX(ai_HttpDechunkStream_decode, 0, 0, 1)
ZEND_ARG_INFO(0, data)
ZEND_ARG_INFO(1, decoded_len)
size_t len;
zval *zlen = NULL;
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|z!", &str, &len, &zlen)) {
+ if (EXPECTED(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|z!", &str, &len, &zlen))) {
const char *end_ptr;
char *enc_str = NULL;
size_t enc_len;
- if ((end_ptr = php_http_encoding_dechunk(str, len, &enc_str, &enc_len))) {
+ if (EXPECTED(end_ptr = php_http_encoding_dechunk(str, len, &enc_str, &enc_len))) {
if (zlen) {
ZVAL_DEREF(zlen);
zval_dtor(zlen);
zend_declare_class_constant_long(php_http_encoding_stream_class_entry, ZEND_STRL("FLUSH_SYNC"), PHP_HTTP_ENCODING_STREAM_FLUSH_SYNC);
zend_declare_class_constant_long(php_http_encoding_stream_class_entry, ZEND_STRL("FLUSH_FULL"), PHP_HTTP_ENCODING_STREAM_FLUSH_FULL);
- memset(&ce, 0, sizeof(ce));
- INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Deflate", php_http_deflate_stream_methods);
- php_http_deflate_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_encoding_stream_class_entry);
- php_http_deflate_stream_class_entry->create_object = php_http_encoding_stream_object_new;
-
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_GZIP"), PHP_HTTP_DEFLATE_TYPE_GZIP);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_ZLIB"), PHP_HTTP_DEFLATE_TYPE_ZLIB);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_RAW"), PHP_HTTP_DEFLATE_TYPE_RAW);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_DEF"), PHP_HTTP_DEFLATE_LEVEL_DEF);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_MIN"), PHP_HTTP_DEFLATE_LEVEL_MIN);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_MAX"), PHP_HTTP_DEFLATE_LEVEL_MAX);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_DEF"), PHP_HTTP_DEFLATE_STRATEGY_DEF);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_FILT"), PHP_HTTP_DEFLATE_STRATEGY_FILT);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_HUFF"), PHP_HTTP_DEFLATE_STRATEGY_HUFF);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_RLE"), PHP_HTTP_DEFLATE_STRATEGY_RLE);
- zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_FIXED"), PHP_HTTP_DEFLATE_STRATEGY_FIXED);
-
- memset(&ce, 0, sizeof(ce));
- INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Inflate", php_http_inflate_stream_methods);
- php_http_inflate_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_encoding_stream_class_entry);
- php_http_inflate_stream_class_entry->create_object = php_http_encoding_stream_object_new;
-
memset(&ce, 0, sizeof(ce));
INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Dechunk", php_http_dechunk_stream_methods);
php_http_dechunk_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_encoding_stream_class_entry);
return SUCCESS;
}
-
/*
* Local variables:
* tab-width: 4
#ifndef PHP_HTTP_ENCODING_H
#define PHP_HTTP_ENCODING_H
-#include <zlib.h>
-
extern PHP_MINIT_FUNCTION(http_encoding);
-extern PHP_RINIT_FUNCTION(http_encoding);
-extern PHP_RSHUTDOWN_FUNCTION(http_encoding);
-
-#define PHP_HTTP_INFLATE_ROUNDS 100
-
-#define PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(S) \
- (((size_t) ((double) S * (double) 1.015)) + 10 + 8 + 4 + 1)
-#define PHP_HTTP_INFLATE_BUFFER_SIZE_GUESS(S) \
- (((S) + 1) << 3)
-#define PHP_HTTP_INFLATE_BUFFER_SIZE_ALIGN(S) \
- ((S) += (S) >> (3))
-
-#define PHP_HTTP_DEFLATE_BUFFER_SIZE 0x8000
-#define PHP_HTTP_INFLATE_BUFFER_SIZE 0x1000
-
-#define PHP_HTTP_DEFLATE_LEVEL_DEF 0x00000000
-#define PHP_HTTP_DEFLATE_LEVEL_MIN 0x00000001
-#define PHP_HTTP_DEFLATE_LEVEL_MAX 0x00000009
-#define PHP_HTTP_DEFLATE_TYPE_ZLIB 0x00000000
-#define PHP_HTTP_DEFLATE_TYPE_GZIP 0x00000010
-#define PHP_HTTP_DEFLATE_TYPE_RAW 0x00000020
-#define PHP_HTTP_DEFLATE_STRATEGY_DEF 0x00000000
-#define PHP_HTTP_DEFLATE_STRATEGY_FILT 0x00000100
-#define PHP_HTTP_DEFLATE_STRATEGY_HUFF 0x00000200
-#define PHP_HTTP_DEFLATE_STRATEGY_RLE 0x00000300
-#define PHP_HTTP_DEFLATE_STRATEGY_FIXED 0x00000400
-
-#define PHP_HTTP_DEFLATE_LEVEL_SET(flags, level) \
- switch (flags & 0xf) \
- { \
- default: \
- if ((flags & 0xf) < 10) { \
- level = flags & 0xf; \
- break; \
- } \
- case PHP_HTTP_DEFLATE_LEVEL_DEF: \
- level = Z_DEFAULT_COMPRESSION; \
- break; \
- }
-
-#define PHP_HTTP_DEFLATE_WBITS_SET(flags, wbits) \
- switch (flags & 0xf0) \
- { \
- case PHP_HTTP_DEFLATE_TYPE_GZIP: \
- wbits = PHP_HTTP_WINDOW_BITS_GZIP; \
- break; \
- case PHP_HTTP_DEFLATE_TYPE_RAW: \
- wbits = PHP_HTTP_WINDOW_BITS_RAW; \
- break; \
- default: \
- wbits = PHP_HTTP_WINDOW_BITS_ZLIB; \
- break; \
- }
-
-#define PHP_HTTP_INFLATE_WBITS_SET(flags, wbits) \
- if (flags & PHP_HTTP_INFLATE_TYPE_RAW) { \
- wbits = PHP_HTTP_WINDOW_BITS_RAW; \
-} else { \
- wbits = PHP_HTTP_WINDOW_BITS_ANY; \
-}
-
-#define PHP_HTTP_DEFLATE_STRATEGY_SET(flags, strategy) \
- switch (flags & 0xf00) \
- { \
- case PHP_HTTP_DEFLATE_STRATEGY_FILT: \
- strategy = Z_FILTERED; \
- break; \
- case PHP_HTTP_DEFLATE_STRATEGY_HUFF: \
- strategy = Z_HUFFMAN_ONLY; \
- break; \
- case PHP_HTTP_DEFLATE_STRATEGY_RLE: \
- strategy = Z_RLE; \
- break; \
- case PHP_HTTP_DEFLATE_STRATEGY_FIXED: \
- strategy = Z_FIXED; \
- break; \
- default: \
- strategy = Z_DEFAULT_STRATEGY; \
- break; \
- }
-
-#define PHP_HTTP_WINDOW_BITS_ZLIB 0x0000000f
-#define PHP_HTTP_WINDOW_BITS_GZIP 0x0000001f
-#define PHP_HTTP_WINDOW_BITS_ANY 0x0000002f
-#define PHP_HTTP_WINDOW_BITS_RAW -0x000000f
-
-#ifndef Z_FIXED
-/* Z_FIXED does not exist prior 1.2.2.2 */
-# define Z_FIXED 0
-#endif
-#define PHP_HTTP_INFLATE_TYPE_ZLIB 0x00000000
-#define PHP_HTTP_INFLATE_TYPE_GZIP 0x00000000
-#define PHP_HTTP_INFLATE_TYPE_RAW 0x00000001
+#define PHP_HTTP_ENCODING_STREAM_PERSISTENT 0x01000000
+#define PHP_HTTP_ENCODING_STREAM_DIRTY 0x02000000
#define PHP_HTTP_ENCODING_STREAM_FLUSH_NONE 0x00000000
#define PHP_HTTP_ENCODING_STREAM_FLUSH_SYNC 0x00100000
#define PHP_HTTP_ENCODING_STREAM_FLUSH_FULL 0x00200000
-#define PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG(f) \
- (((f) & PHP_HTTP_ENCODING_STREAM_FLUSH_FULL) ? Z_FULL_FLUSH : \
- (((f) & PHP_HTTP_ENCODING_STREAM_FLUSH_SYNC) ? Z_SYNC_FLUSH : Z_NO_FLUSH))
-
-#define PHP_HTTP_ENCODING_STREAM_PERSISTENT 0x01000000
+#define PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG(flags, full, sync, none) \
+ (((flags) & PHP_HTTP_ENCODING_STREAM_FLUSH_FULL) ? (full) : \
+ (((flags) & PHP_HTTP_ENCODING_STREAM_FLUSH_SYNC) ? (sync) : (none)))
typedef struct php_http_encoding_stream php_http_encoding_stream_t;
php_http_encoding_stream_ops_t *ops;
};
-PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void);
-PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void);
-PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_dechunk_ops(void);
PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_init(php_http_encoding_stream_t *s, php_http_encoding_stream_ops_t *ops, unsigned flags);
PHP_HTTP_API php_http_encoding_stream_t *php_http_encoding_stream_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to);
PHP_HTTP_API void php_http_encoding_stream_dtor(php_http_encoding_stream_t *s);
PHP_HTTP_API void php_http_encoding_stream_free(php_http_encoding_stream_t **s);
+PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_dechunk_ops(void);
PHP_HTTP_API const char *php_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len);
-PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len);
-PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len);
+PHP_HTTP_API zend_class_entry *php_http_get_dechunk_stream_class_entry(void);
typedef struct php_http_encoding_stream_object {
php_http_encoding_stream_t *stream;
zend_object *php_http_encoding_stream_object_clone(zval *object);
void php_http_encoding_stream_object_free(zend_object *object);
-PHP_HTTP_API zend_class_entry *php_http_get_deflate_stream_class_entry(void);
-PHP_HTTP_API zend_class_entry *php_http_get_inflate_stream_class_entry(void);
-PHP_HTTP_API zend_class_entry *php_http_get_dechunk_stream_class_entry(void);
-
#endif
/*
--- /dev/null
+/*
+ +--------------------------------------------------------------------+
+ | PECL :: http |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the conditions mentioned |
+ | in the accompanying LICENSE file are met. |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
+*/
+
+#include "php_http_api.h"
+
+#if PHP_HTTP_HAVE_LIBBROTLI
+
+#define PHP_HTTP_DEBROTLI_ROUNDS 100
+#define PHP_HTTP_ENBROTLI_ROUNDS 100
+
+#define PHP_HTTP_ENBROTLI_BUFFER_SIZE_GUESS(S) \
+ BrotliEncoderMaxCompressedSize(S)
+#define PHP_HTTP_DEBROTLI_BUFFER_SIZE_ALIGN(S) \
+ ((S) += (S) >> 3)
+
+#define PHP_HTTP_ENBROTLI_FLUSH_FLAG(flags) \
+ PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG((flags), BROTLI_OPERATION_FLUSH, BROTLI_OPERATION_FLUSH, BROTLI_OPERATION_PROCESS)
+
+#define PHP_HTTP_ENBROTLI_BUFFER_SIZE 0x2000
+#define PHP_HTTP_DEBROTLI_BUFFER_SIZE 0x1000
+
+#define PHP_HTTP_ENBROTLI_LEVEL_SET(flags, level) \
+ level = (((flags) & 0xf) ?: PHP_HTTP_ENBROTLI_LEVEL_DEF)
+#define PHP_HTTP_ENBROTLI_WBITS_SET(flags, wbits) \
+ wbits = ((((flags) >> 4) & 0xff) ?: (PHP_HTTP_ENBROTLI_WBITS_DEF >> 4))
+#define PHP_HTTP_ENBROTLI_MODE_SET(flags, mode) \
+ mode = (((flags) >> 12) & 0xf)
+
+
+static php_http_encoding_stream_t *enbrotli_init(php_http_encoding_stream_t *s)
+{
+ BrotliEncoderState *br;
+ int q, win, mode;
+
+ PHP_HTTP_ENBROTLI_LEVEL_SET(s->flags, q);
+ PHP_HTTP_ENBROTLI_WBITS_SET(s->flags, win);
+ PHP_HTTP_ENBROTLI_MODE_SET(s->flags, mode);
+
+ br = BrotliEncoderCreateInstance(NULL, NULL, NULL);
+ if (EXPECTED(br)) {
+ BrotliEncoderSetParameter(br, BROTLI_PARAM_QUALITY, q);
+ BrotliEncoderSetParameter(br, BROTLI_PARAM_LGWIN, win);
+ BrotliEncoderSetParameter(br, BROTLI_PARAM_MODE, mode);
+
+ s->ctx = br;
+ return s;
+ }
+
+ php_error_docref(NULL, E_WARNING, "Failed to initialize brotli encoding stream");
+ return NULL;
+}
+
+static ZEND_RESULT_CODE enbrotli_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
+{
+ php_http_buffer_t out;
+ const unsigned char *in_ptr;
+ size_t in_len;
+ BROTLI_BOOL rc;
+
+ php_http_buffer_init_ex(&out, PHP_HTTP_ENBROTLI_BUFFER_SIZE_GUESS(data_len), 0);
+
+ in_len = data_len;
+ in_ptr = (const unsigned char *) data;
+
+ while (in_len) {
+ size_t out_len = 0;
+
+ rc = BrotliEncoderCompressStream(s->ctx, PHP_HTTP_ENBROTLI_FLUSH_FLAG(s->flags), &in_len, &in_ptr, &out_len, NULL, NULL);
+
+ if (!rc) {
+ break;
+ }
+
+ if (BrotliEncoderHasMoreOutput(s->ctx)) {
+ const char *out_str = (const char *) BrotliEncoderTakeOutput(s->ctx, &out_len);
+
+ php_http_buffer_append(&out, out_str, out_len);
+ }
+ }
+
+ if (rc) {
+ if (out.used) {
+ php_http_buffer_shrink(&out);
+ php_http_buffer_fix(&out);
+ *encoded = out.data;
+ *encoded_len = out.used;
+ } else {
+ *encoded = NULL;
+ *encoded_len = 0;
+ php_http_buffer_dtor(&out);
+ }
+ return SUCCESS;
+ }
+
+ php_http_buffer_dtor(&out);
+
+ *encoded = NULL;
+ *encoded_len = 0;
+
+ php_error_docref(NULL, E_WARNING, "Failed to update brotli encoding stream");
+ return FAILURE;
+}
+
+static inline ZEND_RESULT_CODE enbrotli_flush_ex(php_http_encoding_stream_t *s, BrotliEncoderOperation op, char **encoded, size_t *encoded_len)
+{
+ php_http_buffer_t out;
+ BROTLI_BOOL rc;
+ int round = 0;
+
+ php_http_buffer_init_ex(&out, PHP_HTTP_ENBROTLI_BUFFER_SIZE, 0);
+
+ do {
+ const unsigned char *empty = NULL;
+ size_t unused = 0, out_len = 0;
+
+ rc = BrotliEncoderCompressStream(s->ctx, op, &unused, &empty, &out_len, NULL, NULL);
+
+ if (!rc) {
+ break;
+ }
+
+ if (BrotliEncoderHasMoreOutput(s->ctx)) {
+ const char *out_str = (const char *) BrotliEncoderTakeOutput(s->ctx, &out_len);
+
+ php_http_buffer_append(&out, out_str, out_len);
+ } else {
+ if (out.used) {
+ php_http_buffer_shrink(&out);
+ php_http_buffer_fix(&out);
+
+ *encoded = out.data;
+ *encoded_len = out.used;
+ } else {
+ *encoded = NULL;
+ *encoded_len = 0;
+ }
+ return SUCCESS;
+ }
+ } while (++round < PHP_HTTP_ENBROTLI_ROUNDS);
+
+ php_http_buffer_dtor(&out);
+
+ *encoded = NULL;
+ *encoded_len = 0;
+
+ php_error_docref(NULL, E_WARNING, "Failed to flush brotli encoding stream");
+ return FAILURE;
+}
+
+static ZEND_RESULT_CODE enbrotli_flush(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
+{
+ return enbrotli_flush_ex(s, BROTLI_OPERATION_FLUSH, encoded, encoded_len);
+}
+
+static ZEND_RESULT_CODE enbrotli_finish(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
+{
+ ZEND_RESULT_CODE rc;
+
+ do {
+ rc = enbrotli_flush_ex(s, BROTLI_OPERATION_FINISH, encoded, encoded_len);
+ } while (SUCCESS == rc && !BrotliEncoderIsFinished(s->ctx));
+
+ return rc;
+}
+
+static zend_bool enbrotli_done(php_http_encoding_stream_t *s)
+{
+ return !(s->flags & PHP_HTTP_ENCODING_STREAM_DIRTY)
+ || BrotliEncoderIsFinished(s->ctx);
+}
+
+static void enbrotli_dtor(php_http_encoding_stream_t *s)
+{
+ if (s->ctx) {
+ BrotliEncoderDestroyInstance(s->ctx);
+ s->ctx = NULL;
+ }
+}
+
+static php_http_encoding_stream_t *debrotli_init(php_http_encoding_stream_t *s)
+{
+ BrotliDecoderState *br;
+
+ br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
+ if (br) {
+ s->ctx = br;
+ return s;
+ }
+
+ php_error_docref(NULL, E_WARNING, "Failed to initialize brotli decoding stream");
+ return NULL;
+}
+
+static ZEND_RESULT_CODE debrotli_update(php_http_encoding_stream_t *s, const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len)
+{
+ php_http_buffer_t out;
+ BrotliDecoderResult rc;
+ const unsigned char *in_ptr;
+ size_t in_len;
+
+ in_ptr = (const unsigned char *) encoded;
+ in_len = encoded_len;
+
+ php_http_buffer_init_ex(&out, encoded_len, PHP_HTTP_BUFFER_INIT_PREALLOC);
+
+ while (in_len) {
+ size_t out_len = 0;
+
+ rc = BrotliDecoderDecompressStream(s->ctx, &in_len, &in_ptr, &out_len, NULL, NULL);
+
+ if (BROTLI_DECODER_RESULT_ERROR == rc) {
+ break;
+ }
+
+ if (BrotliDecoderHasMoreOutput(s->ctx)) {
+ const char *out_str = (const char *) BrotliDecoderTakeOutput(s->ctx, &out_len);
+
+ php_http_buffer_append(&out, out_str, out_len);
+ }
+ }
+
+ if (BROTLI_DECODER_RESULT_ERROR != rc) {
+ if (out.used) {
+ php_http_buffer_shrink(&out);
+ php_http_buffer_fix(&out);
+ *decoded = out.data;
+ *decoded_len = out.used;
+ } else {
+ php_http_buffer_dtor(&out);
+ *decoded = NULL;
+ *decoded_len = 0;
+ }
+ return SUCCESS;
+ }
+
+ php_http_buffer_dtor(&out);
+
+ php_error_docref(NULL, E_WARNING, "Could not brotli decode data: %s", BrotliDecoderErrorString(BrotliDecoderGetErrorCode(s->ctx)));
+ return FAILURE;
+}
+
+static zend_bool debrotli_done(php_http_encoding_stream_t *s)
+{
+ return !BrotliDecoderIsUsed(s->ctx) || BrotliDecoderIsFinished(s->ctx);
+}
+
+static void debrotli_dtor(php_http_encoding_stream_t *s)
+{
+ if (s->ctx) {
+ BrotliDecoderDestroyInstance(s->ctx);
+ s->ctx = NULL;
+ }
+}
+
+static php_http_encoding_stream_ops_t php_http_encoding_enbrotli_ops = {
+ enbrotli_init,
+ NULL,
+ enbrotli_update,
+ enbrotli_flush,
+ enbrotli_done,
+ enbrotli_finish,
+ enbrotli_dtor
+};
+
+php_http_encoding_stream_ops_t *php_http_encoding_stream_get_enbrotli_ops(void)
+{
+ return &php_http_encoding_enbrotli_ops;
+}
+
+static php_http_encoding_stream_ops_t php_http_encoding_debrotli_ops = {
+ debrotli_init,
+ NULL,
+ debrotli_update,
+ NULL,
+ debrotli_done,
+ NULL,
+ debrotli_dtor
+};
+
+php_http_encoding_stream_ops_t *php_http_encoding_stream_get_debrotli_ops(void)
+{
+ return &php_http_encoding_debrotli_ops;
+}
+
+ZEND_RESULT_CODE php_http_encoding_enbrotli(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
+{
+ BROTLI_BOOL rc;
+ int q, win, mode;
+
+ *encoded_len = PHP_HTTP_ENBROTLI_BUFFER_SIZE_GUESS(data_len);
+ *encoded = emalloc(*encoded_len + 1);
+
+ PHP_HTTP_ENBROTLI_LEVEL_SET(flags, q);
+ PHP_HTTP_ENBROTLI_WBITS_SET(flags, win);
+ PHP_HTTP_ENBROTLI_MODE_SET(flags, mode);
+
+ rc = BrotliEncoderCompress(q, win, mode, data_len, (const unsigned char *) data, encoded_len, (unsigned char *) *encoded);
+ if (rc) {
+ return SUCCESS;
+ }
+
+ PTR_SET(*encoded, NULL);
+ *encoded_len = 0;
+
+ php_error_docref(NULL, E_WARNING, "Could not brotli encode data");
+ return FAILURE;
+}
+
+ZEND_RESULT_CODE php_http_encoding_debrotli(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len)
+{
+ php_http_encoding_stream_t s = {0};
+ ZEND_RESULT_CODE rc = FAILURE;
+
+ if (debrotli_init(&s)) {
+ rc = debrotli_update(&s, encoded, encoded_len, decoded, decoded_len);
+ debrotli_dtor(&s);
+ }
+
+ return rc;
+}
+
+static zend_class_entry *php_http_enbrotli_stream_class_entry;
+zend_class_entry *php_http_get_enbrotli_stream_class_entry(void)
+{
+ return php_http_enbrotli_stream_class_entry;
+}
+
+static zend_class_entry *php_http_debrotli_stream_class_entry;
+zend_class_entry *php_http_get_debrotli_stream_class_entry(void)
+{
+ return php_http_debrotli_stream_class_entry;
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnbrotliStream_encode, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpEnbrotliStream, encode)
+{
+ char *str;
+ size_t len;
+ zend_long flags = PHP_HTTP_ENBROTLI_MODE_GENERIC | PHP_HTTP_ENBROTLI_WBITS_DEF | PHP_HTTP_ENBROTLI_LEVEL_DEF;
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &len, &flags)) {
+ char *enc_str = NULL;
+ size_t enc_len;
+
+ if (SUCCESS == php_http_encoding_enbrotli(flags, str, len, &enc_str, &enc_len)) {
+ if (enc_str) {
+ RETURN_STR(php_http_cs2zs(enc_str, enc_len));
+ } else {
+ RETURN_EMPTY_STRING();
+ }
+ }
+ }
+ RETURN_FALSE;
+}
+static zend_function_entry php_http_enbrotli_stream_methods[] = {
+ PHP_ME(HttpEnbrotliStream, encode, ai_HttpEnbrotliStream_encode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ EMPTY_FUNCTION_ENTRY
+};
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpDebrotliStream_decode, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpDebrotliStream, decode)
+{
+ char *str;
+ size_t len;
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
+ char *enc_str = NULL;
+ size_t enc_len;
+
+ if (SUCCESS == php_http_encoding_debrotli(str, len, &enc_str, &enc_len)) {
+ if (enc_str) {
+ RETURN_STR(php_http_cs2zs(enc_str, enc_len));
+ } else {
+ RETURN_EMPTY_STRING();
+ }
+ }
+ }
+ RETURN_FALSE;
+}
+
+static zend_function_entry php_http_debrotli_stream_methods[] = {
+ PHP_ME(HttpDebrotliStream, decode, ai_HttpDebrotliStream_decode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ EMPTY_FUNCTION_ENTRY
+};
+
+/* POS */
+const void *BrotliGetDictionary();
+const void *(*php_http_brotli_get_dictionary)();
+
+PHP_MINIT_FUNCTION(http_encoding_brotli)
+{
+ zend_class_entry ce;
+
+ /* force link to libbrotlicommon, because their libraries don't */
+ php_http_brotli_get_dictionary = BrotliGetDictionary();
+
+ memset(&ce, 0, sizeof(ce));
+ INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Enbrotli", php_http_enbrotli_stream_methods);
+ php_http_enbrotli_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_get_encoding_stream_class_entry());
+ php_http_enbrotli_stream_class_entry->create_object = php_http_encoding_stream_object_new;
+
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("LEVEL_MIN"), PHP_HTTP_ENBROTLI_LEVEL_MIN);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("LEVEL_DEF"), PHP_HTTP_ENBROTLI_LEVEL_DEF);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("LEVEL_MAX"), PHP_HTTP_ENBROTLI_LEVEL_MAX);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("WBITS_MIN"), PHP_HTTP_ENBROTLI_WBITS_MIN);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("WBITS_DEF"), PHP_HTTP_ENBROTLI_WBITS_DEF);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("WBITS_MAX"), PHP_HTTP_ENBROTLI_WBITS_MAX);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("MODE_GENERIC"), PHP_HTTP_ENBROTLI_MODE_GENERIC);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("MODE_TEXT"), PHP_HTTP_ENBROTLI_MODE_TEXT);
+ zend_declare_class_constant_long(php_http_enbrotli_stream_class_entry, ZEND_STRL("MODE_FONT"), PHP_HTTP_ENBROTLI_MODE_FONT);
+
+ memset(&ce, 0, sizeof(ce));
+ INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Debrotli", php_http_debrotli_stream_methods);
+ php_http_debrotli_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_get_encoding_stream_class_entry());
+ php_http_debrotli_stream_class_entry->create_object = php_http_encoding_stream_object_new;
+
+ return SUCCESS;
+}
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
--- /dev/null
+/*
+ +--------------------------------------------------------------------+
+ | PECL :: http |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the conditions mentioned |
+ | in the accompanying LICENSE file are met. |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
+*/
+
+#ifndef PHP_HTTP_ENCODING_BROTLI_H
+#define PHP_HTTP_ENCODING_BROTLI_H
+#if PHP_HTTP_HAVE_LIBBROTLI
+
+#include <brotli/decode.h>
+#include <brotli/encode.h>
+
+extern PHP_MINIT_FUNCTION(http_encoding_brotli);
+
+PHP_HTTP_API zend_class_entry *php_http_get_enbrotli_stream_class_entry(void);
+PHP_HTTP_API zend_class_entry *php_http_get_debrotli_stream_class_entry(void);
+
+PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_enbrotli_ops(void);
+PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_debrotli_ops(void);
+
+PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_enbrotli(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len);
+PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_debrotli(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len);
+
+#define PHP_HTTP_ENBROTLI_LEVEL_MIN 0x00000001
+#define PHP_HTTP_ENBROTLI_LEVEL_DEF 0x00000004
+#define PHP_HTTP_ENBROTLI_LEVEL_MAX 0x0000000b
+
+#define PHP_HTTP_ENBROTLI_WBITS_MIN 0x000000a0
+#define PHP_HTTP_ENBROTLI_WBITS_DEF 0x00000160
+#define PHP_HTTP_ENBROTLI_WBITS_MAX 0x00000180
+
+#define PHP_HTTP_ENBROTLI_MODE_GENERIC 0x00000000
+#define PHP_HTTP_ENBROTLI_MODE_TEXT 0x00001000
+#define PHP_HTTP_ENBROTLI_MODE_FONT 0x00002000
+
+#endif
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
--- /dev/null
+/*
+ +--------------------------------------------------------------------+
+ | PECL :: http |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the conditions mentioned |
+ | in the accompanying LICENSE file are met. |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
+*/
+
+#include "php_http_api.h"
+
+#define PHP_HTTP_INFLATE_ROUNDS 100
+#define PHP_HTTP_INFLATE_BUFFER_SIZE 0x1000
+
+#define PHP_HTTP_DEFLATE_BUFFER_SIZE 0x8000
+
+#define PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(S) \
+ (((size_t) ((double) S * (double) 1.015)) + 10 + 8 + 4 + 1)
+
+#define PHP_HTTP_INFLATE_BUFFER_SIZE_GUESS(S) \
+ (((S) + 1) << 3)
+#define PHP_HTTP_INFLATE_BUFFER_SIZE_ALIGN(S) \
+ ((S) += (S) >> (3))
+
+#define PHP_HTTP_INFLATE_FLUSH_FLAG(flags) \
+ PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG((flags), Z_FULL_FLUSH, Z_SYNC_FLUSH, Z_NO_FLUSH)
+#define PHP_HTTP_DEFLATE_FLUSH_FLAG(flags) \
+ PHP_HTTP_ENCODING_STREAM_FLUSH_FLAG((flags), Z_FULL_FLUSH, Z_SYNC_FLUSH, Z_NO_FLUSH)
+
+#define PHP_HTTP_WINDOW_BITS_ZLIB 0x0000000f
+#define PHP_HTTP_WINDOW_BITS_GZIP 0x0000001f
+#define PHP_HTTP_WINDOW_BITS_ANY 0x0000002f
+#define PHP_HTTP_WINDOW_BITS_RAW -0x000000f
+
+#define PHP_HTTP_DEFLATE_LEVEL_SET(flags, level) \
+ switch (flags & 0xf) \
+ { \
+ default: \
+ if ((flags & 0xf) < 10) { \
+ level = flags & 0xf; \
+ break; \
+ } \
+ case PHP_HTTP_DEFLATE_LEVEL_DEF: \
+ level = Z_DEFAULT_COMPRESSION; \
+ break; \
+ }
+
+#define PHP_HTTP_DEFLATE_WBITS_SET(flags, wbits) \
+ switch (flags & 0xf0) \
+ { \
+ case PHP_HTTP_DEFLATE_TYPE_GZIP: \
+ wbits = PHP_HTTP_WINDOW_BITS_GZIP; \
+ break; \
+ case PHP_HTTP_DEFLATE_TYPE_RAW: \
+ wbits = PHP_HTTP_WINDOW_BITS_RAW; \
+ break; \
+ default: \
+ wbits = PHP_HTTP_WINDOW_BITS_ZLIB; \
+ break; \
+ }
+
+#define PHP_HTTP_INFLATE_WBITS_SET(flags, wbits) \
+ if (flags & PHP_HTTP_INFLATE_TYPE_RAW) { \
+ wbits = PHP_HTTP_WINDOW_BITS_RAW; \
+ } else { \
+ wbits = PHP_HTTP_WINDOW_BITS_ANY; \
+ }
+
+#define PHP_HTTP_DEFLATE_STRATEGY_SET(flags, strategy) \
+ switch (flags & 0xf00) \
+ { \
+ case PHP_HTTP_DEFLATE_STRATEGY_FILT: \
+ strategy = Z_FILTERED; \
+ break; \
+ case PHP_HTTP_DEFLATE_STRATEGY_HUFF: \
+ strategy = Z_HUFFMAN_ONLY; \
+ break; \
+ case PHP_HTTP_DEFLATE_STRATEGY_RLE: \
+ strategy = Z_RLE; \
+ break; \
+ case PHP_HTTP_DEFLATE_STRATEGY_FIXED: \
+ strategy = Z_FIXED; \
+ break; \
+ default: \
+ strategy = Z_DEFAULT_STRATEGY; \
+ break; \
+ }
+
+ZEND_RESULT_CODE php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
+{
+ int status, level, wbits, strategy;
+ z_stream Z;
+
+ PHP_HTTP_DEFLATE_LEVEL_SET(flags, level);
+ PHP_HTTP_DEFLATE_WBITS_SET(flags, wbits);
+ PHP_HTTP_DEFLATE_STRATEGY_SET(flags, strategy);
+
+ memset(&Z, 0, sizeof(z_stream));
+ *encoded = NULL;
+ *encoded_len = 0;
+
+ status = deflateInit2(&Z, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy);
+ if (EXPECTED(Z_OK == status)) {
+ *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
+ *encoded = emalloc(*encoded_len);
+
+ Z.next_in = (Bytef *) data;
+ Z.next_out = (Bytef *) *encoded;
+ Z.avail_in = data_len;
+ Z.avail_out = *encoded_len;
+
+ status = deflate(&Z, Z_FINISH);
+ deflateEnd(&Z);
+
+ if (EXPECTED(Z_STREAM_END == status)) {
+ /* size buffer down to actual length */
+ *encoded = erealloc(*encoded, Z.total_out + 1);
+ (*encoded)[*encoded_len = Z.total_out] = '\0';
+ return SUCCESS;
+ } else {
+ PTR_SET(*encoded, NULL);
+ *encoded_len = 0;
+ }
+ }
+
+ php_error_docref(NULL, E_WARNING, "Could not deflate data: %s", zError(status));
+ return FAILURE;
+}
+
+static php_http_encoding_stream_t *deflate_init(php_http_encoding_stream_t *s)
+{
+ int status, level, wbits, strategy, p = (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT);
+ z_streamp ctx = pecalloc(1, sizeof(z_stream), p);
+
+ PHP_HTTP_DEFLATE_LEVEL_SET(s->flags, level);
+ PHP_HTTP_DEFLATE_WBITS_SET(s->flags, wbits);
+ PHP_HTTP_DEFLATE_STRATEGY_SET(s->flags, strategy);
+
+ if (EXPECTED(Z_OK == (status = deflateInit2(ctx, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, strategy)))) {
+ if (EXPECTED(ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
+ s->ctx = ctx;
+ return s;
+ }
+ deflateEnd(ctx);
+ status = Z_MEM_ERROR;
+ }
+ pefree(ctx, p);
+ php_error_docref(NULL, E_WARNING, "Failed to initialize deflate encoding stream: %s", zError(status));
+ return NULL;
+}
+
+static php_http_encoding_stream_t *deflate_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to)
+{
+ int status, p = to->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT;
+ z_streamp from_ctx = from->ctx, to_ctx = pecalloc(1, sizeof(*to_ctx), p);
+
+ if (Z_OK == (status = deflateCopy(to_ctx, from_ctx))) {
+ if ((to_ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
+ php_http_buffer_append(to_ctx->opaque, PHP_HTTP_BUFFER(from_ctx->opaque)->data, PHP_HTTP_BUFFER(from_ctx->opaque)->used);
+ to->ctx = to_ctx;
+ return to;
+ }
+ deflateEnd(to_ctx);
+ status = Z_MEM_ERROR;
+ }
+ php_error_docref(NULL, E_WARNING, "Failed to copy deflate encoding stream: %s", zError(status));
+ return NULL;
+}
+
+static ZEND_RESULT_CODE deflate_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **encoded, size_t *encoded_len)
+{
+ int status;
+ z_streamp ctx = s->ctx;
+
+ /* append input to our buffer */
+ php_http_buffer_append(PHP_HTTP_BUFFER(ctx->opaque), data, data_len);
+
+ ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
+ ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
+
+ /* deflate */
+ *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE_GUESS(data_len);
+ *encoded = emalloc(*encoded_len);
+ ctx->avail_out = *encoded_len;
+ ctx->next_out = (Bytef *) *encoded;
+
+ switch (status = deflate(ctx, PHP_HTTP_DEFLATE_FLUSH_FLAG(s->flags))) {
+ case Z_OK:
+ case Z_STREAM_END:
+ /* cut processed chunk off the buffer */
+ if (ctx->avail_in) {
+ php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
+ } else {
+ php_http_buffer_reset(PHP_HTTP_BUFFER(ctx->opaque));
+ }
+
+ /* size buffer down to actual size */
+ *encoded_len -= ctx->avail_out;
+ *encoded = erealloc(*encoded, *encoded_len + 1);
+ (*encoded)[*encoded_len] = '\0';
+ return SUCCESS;
+ }
+
+ PTR_SET(*encoded, NULL);
+ *encoded_len = 0;
+ php_error_docref(NULL, E_WARNING, "Failed to update deflate stream: %s", zError(status));
+ return FAILURE;
+}
+
+static ZEND_RESULT_CODE deflate_flush(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
+{
+ int status;
+ z_streamp ctx = s->ctx;
+
+ *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE;
+ *encoded = emalloc(*encoded_len);
+
+ ctx->avail_in = 0;
+ ctx->next_in = NULL;
+ ctx->avail_out = *encoded_len;
+ ctx->next_out = (Bytef *) *encoded;
+
+ status = deflate(ctx, Z_FULL_FLUSH);
+ if (EXPECTED(Z_OK == status || Z_STREAM_END == status)) {
+ *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE - ctx->avail_out;
+ *encoded = erealloc(*encoded, *encoded_len + 1);
+ (*encoded)[*encoded_len] = '\0';
+ return SUCCESS;
+ }
+
+ PTR_SET(*encoded, NULL);
+ *encoded_len = 0;
+ php_error_docref(NULL, E_WARNING, "Failed to flush deflate stream: %s", zError(status));
+ return FAILURE;
+}
+
+static ZEND_RESULT_CODE deflate_finish(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
+{
+ int status;
+ z_streamp ctx = s->ctx;
+
+ *encoded_len = PHP_HTTP_DEFLATE_BUFFER_SIZE;
+ *encoded = emalloc(*encoded_len);
+
+ /* deflate remaining input */
+ ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
+ ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
+
+ ctx->avail_out = *encoded_len;
+ ctx->next_out = (Bytef *) *encoded;
+
+ do {
+ status = deflate(ctx, Z_FINISH);
+ } while (Z_OK == status);
+
+ if (EXPECTED(Z_STREAM_END == status)) {
+ /* cut processed input off */
+ php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
+
+ /* size down */
+ *encoded_len -= ctx->avail_out;
+ *encoded = erealloc(*encoded, *encoded_len + 1);
+ (*encoded)[*encoded_len] = '\0';
+ return SUCCESS;
+ }
+
+ PTR_SET(*encoded, NULL);
+ *encoded_len = 0;
+ php_error_docref(NULL, E_WARNING, "Failed to finish deflate stream: %s", zError(status));
+ return FAILURE;
+}
+
+static zend_bool deflate_done(php_http_encoding_stream_t *s)
+{
+ z_streamp ctx = s->ctx;
+ return !ctx->avail_in && !PHP_HTTP_BUFFER(ctx->opaque)->used;
+}
+
+static void deflate_dtor(php_http_encoding_stream_t *s)
+{
+ if (EXPECTED(s->ctx)) {
+ z_streamp ctx = s->ctx;
+
+ if (EXPECTED(ctx->opaque)) {
+ php_http_buffer_free((php_http_buffer_t **) &ctx->opaque);
+ }
+ deflateEnd(ctx);
+ pefree(ctx, (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
+ s->ctx = NULL;
+ }
+}
+
+static inline int php_http_inflate_rounds(z_stream *Z, int flush, char **buf, size_t *len)
+{
+ int status = 0, round = 0;
+ php_http_buffer_t buffer;
+
+ *buf = NULL;
+ *len = 0;
+
+ php_http_buffer_init_ex(&buffer, Z->avail_in, PHP_HTTP_BUFFER_INIT_PREALLOC);
+
+ do {
+ if (UNEXPECTED(PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize_ex(&buffer, buffer.size, 0, 1))) {
+ status = Z_MEM_ERROR;
+ } else {
+ Z->avail_out = buffer.free;
+ Z->next_out = (Bytef *) buffer.data + buffer.used;
+#if 0
+ fprintf(stderr, "\n%3d: %3d PRIOR: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
+#endif
+ status = inflate(Z, flush);
+ php_http_buffer_account(&buffer, buffer.free - Z->avail_out);
+#if 0
+ fprintf(stderr, "%3d: %3d AFTER: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
+#endif
+ PHP_HTTP_INFLATE_BUFFER_SIZE_ALIGN(buffer.size);
+ }
+ } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < PHP_HTTP_INFLATE_ROUNDS);
+
+ if (EXPECTED(status == Z_OK || status == Z_STREAM_END)) {
+ php_http_buffer_shrink(&buffer);
+ php_http_buffer_fix(&buffer);
+ *buf = buffer.data;
+ *len = buffer.used;
+ } else {
+ php_http_buffer_dtor(&buffer);
+ }
+
+ return status;
+}
+
+ZEND_RESULT_CODE php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len)
+{
+ z_stream Z;
+ int status, wbits = PHP_HTTP_WINDOW_BITS_ANY;
+
+ memset(&Z, 0, sizeof(z_stream));
+
+retry_raw_inflate:
+ status = inflateInit2(&Z, wbits);
+ if (EXPECTED(Z_OK == status)) {
+ Z.next_in = (Bytef *) data;
+ Z.avail_in = data_len + 1; /* include the terminating NULL, see #61287 */
+
+ switch (status = php_http_inflate_rounds(&Z, Z_NO_FLUSH, decoded, decoded_len)) {
+ case Z_STREAM_END:
+ inflateEnd(&Z);
+ return SUCCESS;
+
+ case Z_OK:
+ status = Z_DATA_ERROR;
+ break;
+
+ case Z_DATA_ERROR:
+ /* raw deflated data? */
+ if (PHP_HTTP_WINDOW_BITS_ANY == wbits) {
+ inflateEnd(&Z);
+ wbits = PHP_HTTP_WINDOW_BITS_RAW;
+ goto retry_raw_inflate;
+ }
+ break;
+ }
+ inflateEnd(&Z);
+
+ if (*decoded_len && *decoded) {
+ efree(*decoded);
+ }
+ }
+
+ php_error_docref(NULL, E_WARNING, "Could not inflate data: %s", zError(status));
+ return FAILURE;
+}
+
+static php_http_encoding_stream_t *inflate_init(php_http_encoding_stream_t *s)
+{
+ int status, wbits, p = (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT);
+ z_streamp ctx = pecalloc(1, sizeof(z_stream), p);
+
+ PHP_HTTP_INFLATE_WBITS_SET(s->flags, wbits);
+
+ if (EXPECTED(Z_OK == (status = inflateInit2(ctx, wbits)))) {
+ if ((ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
+ s->ctx = ctx;
+ return s;
+ }
+ inflateEnd(ctx);
+ status = Z_MEM_ERROR;
+ }
+ pefree(ctx, p);
+ php_error_docref(NULL, E_WARNING, "Failed to initialize inflate stream: %s", zError(status));
+ return NULL;
+}
+
+static php_http_encoding_stream_t *inflate_copy(php_http_encoding_stream_t *from, php_http_encoding_stream_t *to)
+{
+ int status, p = from->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT;
+ z_streamp from_ctx = from->ctx, to_ctx = pecalloc(1, sizeof(*to_ctx), p);
+
+ if (Z_OK == (status = inflateCopy(to_ctx, from_ctx))) {
+ if ((to_ctx->opaque = php_http_buffer_init_ex(NULL, PHP_HTTP_DEFLATE_BUFFER_SIZE, p ? PHP_HTTP_BUFFER_INIT_PERSISTENT : 0))) {
+ php_http_buffer_append(to_ctx->opaque, PHP_HTTP_BUFFER(from_ctx->opaque)->data, PHP_HTTP_BUFFER(from_ctx->opaque)->used);
+ to->ctx = to_ctx;
+ return to;
+ }
+ inflateEnd(to_ctx);
+ status = Z_MEM_ERROR;
+ }
+ php_error_docref(NULL, E_WARNING, "Failed to copy inflate encoding stream: %s", zError(status));
+ return NULL;
+}
+
+static ZEND_RESULT_CODE inflate_update(php_http_encoding_stream_t *s, const char *data, size_t data_len, char **decoded, size_t *decoded_len)
+{
+ int status;
+ z_streamp ctx = s->ctx;
+
+ /* append input to buffer */
+ php_http_buffer_append(PHP_HTTP_BUFFER(ctx->opaque), data, data_len);
+
+retry_raw_inflate:
+ ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
+ ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
+
+ switch (status = php_http_inflate_rounds(ctx, PHP_HTTP_INFLATE_FLUSH_FLAG(s->flags), decoded, decoded_len)) {
+ case Z_OK:
+ case Z_STREAM_END:
+ /* cut off */
+ if (ctx->avail_in) {
+ php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
+ } else {
+ php_http_buffer_reset(PHP_HTTP_BUFFER(ctx->opaque));
+ }
+ return SUCCESS;
+
+ case Z_DATA_ERROR:
+ /* raw deflated data ? */
+ if (!(s->flags & PHP_HTTP_INFLATE_TYPE_RAW) && !ctx->total_out) {
+ inflateEnd(ctx);
+ s->flags |= PHP_HTTP_INFLATE_TYPE_RAW;
+ inflateInit2(ctx, PHP_HTTP_WINDOW_BITS_RAW);
+ goto retry_raw_inflate;
+ }
+ break;
+ }
+
+ php_error_docref(NULL, E_WARNING, "Failed to update inflate stream: %s", zError(status));
+ return FAILURE;
+}
+
+static ZEND_RESULT_CODE inflate_finish(php_http_encoding_stream_t *s, char **decoded, size_t *decoded_len)
+{
+ int status;
+ z_streamp ctx = s->ctx;
+
+ if (!PHP_HTTP_BUFFER(ctx->opaque)->used) {
+ *decoded = NULL;
+ *decoded_len = 0;
+ return SUCCESS;
+ }
+
+ *decoded_len = (PHP_HTTP_BUFFER(ctx->opaque)->used + 1) * PHP_HTTP_INFLATE_ROUNDS;
+ *decoded = emalloc(*decoded_len);
+
+ /* inflate remaining input */
+ ctx->next_in = (Bytef *) PHP_HTTP_BUFFER(ctx->opaque)->data;
+ ctx->avail_in = PHP_HTTP_BUFFER(ctx->opaque)->used;
+
+ ctx->avail_out = *decoded_len;
+ ctx->next_out = (Bytef *) *decoded;
+
+ if (Z_STREAM_END == (status = inflate(ctx, Z_FINISH))) {
+ /* cut processed input off */
+ php_http_buffer_cut(PHP_HTTP_BUFFER(ctx->opaque), 0, PHP_HTTP_BUFFER(ctx->opaque)->used - ctx->avail_in);
+
+ /* size down */
+ *decoded_len -= ctx->avail_out;
+ *decoded = erealloc(*decoded, *decoded_len + 1);
+ (*decoded)[*decoded_len] = '\0';
+ return SUCCESS;
+ }
+
+ PTR_SET(*decoded, NULL);
+ *decoded_len = 0;
+ php_error_docref(NULL, E_WARNING, "Failed to finish inflate stream: %s", zError(status));
+ return FAILURE;
+}
+
+static zend_bool inflate_done(php_http_encoding_stream_t *s)
+{
+ z_streamp ctx = s->ctx;
+ return !ctx->avail_in && !PHP_HTTP_BUFFER(ctx->opaque)->used;
+}
+
+static void inflate_dtor(php_http_encoding_stream_t *s)
+{
+ if (EXPECTED(s->ctx)) {
+ z_streamp ctx = s->ctx;
+
+ if (EXPECTED(ctx->opaque)) {
+ php_http_buffer_free((php_http_buffer_t **) &ctx->opaque);
+ }
+ inflateEnd(ctx);
+ pefree(ctx, (s->flags & PHP_HTTP_ENCODING_STREAM_PERSISTENT));
+ s->ctx = NULL;
+ }
+}
+
+static php_http_encoding_stream_ops_t php_http_encoding_deflate_ops = {
+ deflate_init,
+ deflate_copy,
+ deflate_update,
+ deflate_flush,
+ deflate_done,
+ deflate_finish,
+ deflate_dtor
+};
+
+php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void)
+{
+ return &php_http_encoding_deflate_ops;
+}
+
+static php_http_encoding_stream_ops_t php_http_encoding_inflate_ops = {
+ inflate_init,
+ inflate_copy,
+ inflate_update,
+ NULL,
+ inflate_done,
+ inflate_finish,
+ inflate_dtor
+};
+
+php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void)
+{
+ return &php_http_encoding_inflate_ops;
+}
+
+static zend_class_entry *php_http_deflate_stream_class_entry;
+zend_class_entry *php_http_get_deflate_stream_class_entry(void)
+{
+ return php_http_deflate_stream_class_entry;
+}
+
+static zend_class_entry *php_http_inflate_stream_class_entry;
+zend_class_entry *php_http_get_inflate_stream_class_entry(void)
+{
+ return php_http_inflate_stream_class_entry;
+}
+
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpDeflateStream_encode, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpDeflateStream, encode)
+{
+ char *str;
+ size_t len;
+ zend_long flags = 0;
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &len, &flags)) {
+ char *enc_str = NULL;
+ size_t enc_len;
+
+ if (SUCCESS == php_http_encoding_deflate(flags, str, len, &enc_str, &enc_len)) {
+ if (enc_str) {
+ RETURN_STR(php_http_cs2zs(enc_str, enc_len));
+ } else {
+ RETURN_EMPTY_STRING();
+ }
+ }
+ }
+ RETURN_FALSE;
+}
+
+static zend_function_entry php_http_deflate_stream_methods[] = {
+ PHP_ME(HttpDeflateStream, encode, ai_HttpDeflateStream_encode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ EMPTY_FUNCTION_ENTRY
+};
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpInflateStream_decode, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpInflateStream, decode)
+{
+ char *str;
+ size_t len;
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len)) {
+ char *enc_str = NULL;
+ size_t enc_len;
+
+ if (SUCCESS == php_http_encoding_inflate(str, len, &enc_str, &enc_len)) {
+ if (enc_str) {
+ RETURN_STR(php_http_cs2zs(enc_str, enc_len));
+ } else {
+ RETURN_EMPTY_STRING();
+ }
+ }
+ }
+ RETURN_FALSE;
+}
+
+static zend_function_entry php_http_inflate_stream_methods[] = {
+ PHP_ME(HttpInflateStream, decode, ai_HttpInflateStream_decode, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ EMPTY_FUNCTION_ENTRY
+};
+
+PHP_MINIT_FUNCTION(http_encoding_zlib)
+{
+ zend_class_entry ce;
+
+ memset(&ce, 0, sizeof(ce));
+ INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Deflate", php_http_deflate_stream_methods);
+ php_http_deflate_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_get_encoding_stream_class_entry());
+ php_http_deflate_stream_class_entry->create_object = php_http_encoding_stream_object_new;
+
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_GZIP"), PHP_HTTP_DEFLATE_TYPE_GZIP);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_ZLIB"), PHP_HTTP_DEFLATE_TYPE_ZLIB);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("TYPE_RAW"), PHP_HTTP_DEFLATE_TYPE_RAW);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_DEF"), PHP_HTTP_DEFLATE_LEVEL_DEF);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_MIN"), PHP_HTTP_DEFLATE_LEVEL_MIN);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("LEVEL_MAX"), PHP_HTTP_DEFLATE_LEVEL_MAX);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_DEF"), PHP_HTTP_DEFLATE_STRATEGY_DEF);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_FILT"), PHP_HTTP_DEFLATE_STRATEGY_FILT);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_HUFF"), PHP_HTTP_DEFLATE_STRATEGY_HUFF);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_RLE"), PHP_HTTP_DEFLATE_STRATEGY_RLE);
+ zend_declare_class_constant_long(php_http_deflate_stream_class_entry, ZEND_STRL("STRATEGY_FIXED"), PHP_HTTP_DEFLATE_STRATEGY_FIXED);
+
+ memset(&ce, 0, sizeof(ce));
+ INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Inflate", php_http_inflate_stream_methods);
+ php_http_inflate_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_get_encoding_stream_class_entry());
+ php_http_inflate_stream_class_entry->create_object = php_http_encoding_stream_object_new;
+
+ return SUCCESS;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
--- /dev/null
+/*
+ +--------------------------------------------------------------------+
+ | PECL :: http |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the conditions mentioned |
+ | in the accompanying LICENSE file are met. |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
+*/
+
+#ifndef PHP_HTTP_ENCODING_ZLIB_H
+#define PHP_HTTP_ENCODING_ZLIB_H
+
+#include "php_http_encoding.h"
+
+#include <zlib.h>
+
+#ifndef Z_FIXED
+/* Z_FIXED does not exist prior 1.2.2.2 */
+# define Z_FIXED 0
+#endif
+
+extern PHP_MINIT_FUNCTION(http_encoding_zlib);
+
+zend_class_entry *php_http_get_deflate_stream_class_entry(void);
+zend_class_entry *php_http_get_inflate_stream_class_entry(void);
+
+PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_deflate_ops(void);
+PHP_HTTP_API php_http_encoding_stream_ops_t *php_http_encoding_stream_get_inflate_ops(void);
+
+PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_deflate(int flags, const char *data, size_t data_len, char **encoded, size_t *encoded_len);
+PHP_HTTP_API ZEND_RESULT_CODE php_http_encoding_inflate(const char *data, size_t data_len, char **decoded, size_t *decoded_len);
+
+#define PHP_HTTP_DEFLATE_LEVEL_DEF 0x00000000
+#define PHP_HTTP_DEFLATE_LEVEL_MIN 0x00000001
+#define PHP_HTTP_DEFLATE_LEVEL_MAX 0x00000009
+#define PHP_HTTP_DEFLATE_TYPE_ZLIB 0x00000000
+#define PHP_HTTP_DEFLATE_TYPE_GZIP 0x00000010
+#define PHP_HTTP_DEFLATE_TYPE_RAW 0x00000020
+#define PHP_HTTP_DEFLATE_STRATEGY_DEF 0x00000000
+#define PHP_HTTP_DEFLATE_STRATEGY_FILT 0x00000100
+#define PHP_HTTP_DEFLATE_STRATEGY_HUFF 0x00000200
+#define PHP_HTTP_DEFLATE_STRATEGY_RLE 0x00000300
+#define PHP_HTTP_DEFLATE_STRATEGY_FIXED 0x00000400
+
+#define PHP_HTTP_INFLATE_TYPE_ZLIB 0x00000000
+#define PHP_HTTP_INFLATE_TYPE_GZIP 0x00000000
+#define PHP_HTTP_INFLATE_TYPE_RAW 0x00000001
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
}
static zend_function_entry php_http_env_request_methods[] = {
- PHP_ME(HttpEnvRequest, __construct, ai_HttpEnvRequest___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpEnvRequest, __construct, ai_HttpEnvRequest___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvRequest, getForm, ai_HttpEnvRequest_getForm, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvRequest, getQuery, ai_HttpEnvRequest_getQuery, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvRequest, getCookie, ai_HttpEnvRequest_getCookie, ZEND_ACC_PUBLIC)
static void set_option(zval *options, const char *name_str, size_t name_len, int type, void *value_ptr, size_t value_len)
{
if (Z_TYPE_P(options) == IS_OBJECT) {
- if (value_ptr) {
+ if (EXPECTED(value_ptr)) {
switch (type) {
case IS_DOUBLE:
zend_update_property_double(Z_OBJCE_P(options), options, name_str, name_len, *(double *)value_ptr);
}
} else {
convert_to_array(options);
- if (value_ptr) {
+ if (EXPECTED(value_ptr)) {
switch (type) {
case IS_DOUBLE:
add_assoc_double_ex(options, name_str, name_len, *(double *)value_ptr);
{
zval *val = NULL;
- if (Z_TYPE_P(options) == IS_OBJECT) {
+ if (EXPECTED(Z_TYPE_P(options) == IS_OBJECT)) {
val = zend_read_property(Z_OBJCE_P(options), options, name_str, name_len, 0, tmp);
- } else if (Z_TYPE_P(options) == IS_ARRAY) {
+ } else if (EXPECTED(Z_TYPE_P(options) == IS_ARRAY)) {
val = zend_symtable_str_find(Z_ARRVAL_P(options), name_str, name_len);
} else {
abort();
zval zbody_tmp, *zbody;
php_http_message_body_t *body = NULL;
- if ((zbody = get_option(options, ZEND_STRL("body"), &zbody_tmp))) {
+ if (EXPECTED(zbody = get_option(options, ZEND_STRL("body"), &zbody_tmp))) {
if ((Z_TYPE_P(zbody) == IS_OBJECT) && instanceof_function(Z_OBJCE_P(zbody), php_http_get_message_body_class_entry())) {
php_http_message_body_object_t *body_obj = PHP_HTTP_OBJ(NULL, zbody);
zval zrequest_tmp, *zrequest;
php_http_message_t *request = NULL;
- if ((zrequest = get_option(options, ZEND_STRL("request"), &zrequest_tmp))) {
- if (Z_TYPE_P(zrequest) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zrequest), php_http_message_get_class_entry())) {
+ if (EXPECTED(zrequest = get_option(options, ZEND_STRL("request"), &zrequest_tmp))) {
+ if (UNEXPECTED(Z_TYPE_P(zrequest) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zrequest), php_http_message_get_class_entry()))) {
php_http_message_object_t *request_obj = PHP_HTTP_OBJ(NULL, zrequest);
request = request_obj->message;
zval zetag_tmp, *zetag;
- if (!(body = get_body(options))) {
+ if (UNEXPECTED(!(body = get_body(options)))) {
return ret;
}
- if ((zetag = get_option(options, ZEND_STRL("etag"), &zetag_tmp)) && Z_TYPE_P(zetag) != IS_NULL) {
+ if (EXPECTED(zetag = get_option(options, ZEND_STRL("etag"), &zetag_tmp)) && Z_TYPE_P(zetag) != IS_NULL) {
zend_string *zs = zval_get_string(zetag);
etag = estrndup(zs->val, zs->len);
zend_string_release(zs);
php_http_message_body_t *body;
zval zlm_tmp, *zlm;
- if (!(body = get_body(options))) {
+ if (UNEXPECTED(!(body = get_body(options)))) {
return ret;
}
- if ((zlm = get_option(options, ZEND_STRL("lastModified"), &zlm_tmp))) {
+ if (EXPECTED(zlm = get_option(options, ZEND_STRL("lastModified"), &zlm_tmp))) {
lm = zval_get_long(zlm);
zval_ptr_dtor(zlm);
}
- if (lm <= 0) {
+ if (EXPECTED(lm <= 0)) {
lm = php_http_message_body_mtime(body);
set_option(options, ZEND_STRL("lastModified"), IS_LONG, &lm, 0);
}
{
php_http_env_response_t *r = context;
- if (SUCCESS != r->ops->write(r, buf, len)) {
+ if (UNEXPECTED(SUCCESS != r->ops->write(r, buf, len))) {
return (size_t) -1;
}
/* we really only need to flush when throttling is enabled,
because we push the data as fast as possible anyway if not */
- if (r->throttle.delay >= PHP_HTTP_DIFFSEC) {
+ if (UNEXPECTED(r->throttle.delay >= PHP_HTTP_DIFFSEC)) {
r->ops->flush(r);
php_http_sleep(r->throttle.delay);
}
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("headers"), &zoption_tmp))) {
- if (Z_TYPE_P(zoption) == IS_ARRAY) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("headers"), &zoption_tmp))) {
+ if (EXPECTED(Z_TYPE_P(zoption) == IS_ARRAY)) {
php_http_header_to_callback(Z_ARRVAL_P(zoption), 0, (php_http_pass_format_callback_t) r->ops->set_header, r);
}
zval_ptr_dtor(zoption);
}
- if ((zoption = get_option(options, ZEND_STRL("responseCode"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("responseCode"), &zoption_tmp))) {
zend_long rc = zval_get_long(zoption);
zval_ptr_dtor(zoption);
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("httpVersion"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("httpVersion"), &zoption_tmp))) {
php_http_version_t v;
zend_string *zs = zval_get_string(zoption);
zval_ptr_dtor(zoption);
- if (zs->len && php_http_version_parse(&v, zs->val)) {
+ if (EXPECTED(zs->len && php_http_version_parse(&v, zs->val))) {
ret = r->ops->set_protocol_version(r, &v);
php_http_version_dtor(&v);
}
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("cookies"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("cookies"), &zoption_tmp))) {
if (Z_TYPE_P(zoption) == IS_ARRAY) {
zval *zcookie;
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("contentType"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("contentType"), &zoption_tmp))) {
zend_string *zs = zval_get_string(zoption);
zval_ptr_dtor(zoption);
return ret;
}
- if (r->range.status == PHP_HTTP_RANGE_OK) {
+ if (UNEXPECTED(r->range.status == PHP_HTTP_RANGE_OK)) {
if (zend_hash_num_elements(&r->range.values) == 1) {
zval *range, *begin, *end;
- if ( 1 == php_http_array_list(&r->range.values, 1, &range)
- && 2 == php_http_array_list(Z_ARRVAL_P(range), 2, &begin, &end)
+ if (EXPECTED( 1 == php_http_array_list(&r->range.values, 1, &range)
+ && 2 == php_http_array_list(Z_ARRVAL_P(range), 2, &begin, &end))
) {
if (SUCCESS == (ret = r->ops->set_status(r, 206))) {
ret = r->ops->set_header(r, "Content-Range: bytes %ld-%ld/%zu", Z_LVAL_P(begin), Z_LVAL_P(end), r->content.length);
}
}
} else {
- if ((zoption = get_option(options, ZEND_STRL("cacheControl"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("cacheControl"), &zoption_tmp))) {
zend_string *zs = zval_get_string(zoption);
zval_ptr_dtor(zoption);
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("contentDisposition"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("contentDisposition"), &zoption_tmp))) {
if (Z_TYPE_P(zoption) == IS_ARRAY) {
php_http_buffer_t buf;
return ret;
}
- if ((zoption = get_option(options, ZEND_STRL("contentEncoding"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("contentEncoding"), &zoption_tmp))) {
zend_long ce = zval_get_long(zoption);
zval zsupported;
HashTable *result = NULL;
break;
}
- if ((zoption = get_option(options, ZEND_STRL("etag"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("etag"), &zoption_tmp))) {
zend_string *zs = zval_get_string(zoption);
zval_ptr_dtor(zoption);
- if (*zs->val != '"' && strncmp(zs->val, "W/\"", 3)) {
+ if (EXPECTED(*zs->val != '"' && strncmp(zs->val, "W/\"", 3))) {
ret = r->ops->set_header(r, "ETag: \"%s\"", zs->val);
} else {
ret = r->ops->set_header(r, "ETag: %s", zs->val);
}
zend_string_release(zs);
}
- if ((zoption = get_option(options, ZEND_STRL("lastModified"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(options, ZEND_STRL("lastModified"), &zoption_tmp))) {
zend_long lm = zval_get_long(zoption);
zval_ptr_dtor(zoption);
- if (lm) {
+ if (EXPECTED(lm)) {
zend_string *date = php_format_date(ZEND_STRL(PHP_HTTP_DATE_FORMAT), lm, 0);
if (date) {
ret = r->ops->set_header(r, "Last-Modified: %s", date->val);
return ret;
}
- if ((body = get_body(&r->options))) {
- if ((zoption = get_option(&r->options, ZEND_STRL("throttleDelay"), &zoption_tmp))) {
+ if (EXPECTED(body = get_body(&r->options))) {
+ if (EXPECTED(zoption = get_option(&r->options, ZEND_STRL("throttleDelay"), &zoption_tmp))) {
r->throttle.delay = zval_get_double(zoption);
zval_ptr_dtor(zoption);
}
- if ((zoption = get_option(&r->options, ZEND_STRL("throttleChunk"), &zoption_tmp))) {
+ if (EXPECTED(zoption = get_option(&r->options, ZEND_STRL("throttleChunk"), &zoption_tmp))) {
r->throttle.chunk = zval_get_long(zoption);
zval_ptr_dtor(zoption);
}
- if (r->range.status == PHP_HTTP_RANGE_OK) {
+ if (UNEXPECTED(r->range.status == PHP_HTTP_RANGE_OK)) {
if (zend_hash_num_elements(&r->range.values) == 1) {
/* single range */
zval *range, *begin, *end;
request = get_request(&r->options);
/* check for ranges */
- if ((body = get_body(&r->options))) {
+ if (EXPECTED(body = get_body(&r->options))) {
r->content.length = php_http_message_body_size(body);
- if (SUCCESS != r->ops->set_header(r, "Accept-Ranges: bytes")) {
+ if (UNEXPECTED(SUCCESS != r->ops->set_header(r, "Accept-Ranges: bytes"))) {
return FAILURE;
} else {
ZEND_INIT_SYMTABLE_EX(&r->range.values, 0, 0);
}
}
- if (SUCCESS != php_http_env_response_send_head(r, request)) {
+ if (UNEXPECTED(SUCCESS != php_http_env_response_send_head(r, request))) {
php_error_docref(NULL, E_WARNING, "Failed to send response headers");
return FAILURE;
}
- if (SUCCESS != php_http_env_response_send_body(r)) {
+ if (UNEXPECTED(SUCCESS != php_http_env_response_send_body(r))) {
php_error_docref(NULL, E_WARNING, "Failed to send response body");
return FAILURE;
}
- if (SUCCESS != r->ops->finish(r)) {
+ if (UNEXPECTED(SUCCESS != r->ops->finish(r))) {
php_error_docref(NULL, E_WARNING, "Failed to finish response");
return FAILURE;
}
ctx = ecalloc(1, sizeof(*ctx));
ctx->stream = init_arg;
- ++GC_REFCOUNT(ctx->stream->res);
+ GC_ADDREF(ctx->stream->res);
ZEND_INIT_SYMTABLE(&ctx->header);
php_http_version_init(&ctx->version, 1, 1);
php_stream_set_option(ctx->stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_FULL, &buffer_size);
ctx->request = get_request(&r->options);
/* there are some limitations regarding TE:chunked, see https://tools.ietf.org/html/rfc7230#section-3.3.1 */
- if (ctx->request && ctx->request->http.version.major == 1 && ctx->request->http.version.minor == 0) {
+ if (UNEXPECTED(ctx->request && ctx->request->http.version.major == 1 && ctx->request->http.version.minor == 0)) {
ctx->version.minor = 0;
}
{
php_http_env_response_stream_ctx_t *ctx = r->ctx;
- if (ctx->chunked_filter) {
+ if (UNEXPECTED(ctx->chunked_filter)) {
ctx->chunked_filter = php_stream_filter_remove(ctx->chunked_filter, 1);
}
zend_hash_destroy(&ctx->header);
ZEND_HASH_FOREACH_VAL(header, val)
{
- if (Z_TYPE_P(val) == IS_ARRAY) {
+ if (UNEXPECTED(Z_TYPE_P(val) == IS_ARRAY)) {
php_http_env_response_stream_header(ctx, Z_ARRVAL_P(val), buf);
} else {
zend_string *zs = zval_get_string(val);
php_http_buffer_appendf(&header_buf, "HTTP/%u.%u %ld %s" PHP_HTTP_CRLF, ctx->version.major, ctx->version.minor, ctx->status_code, php_http_env_get_response_status_for_code(ctx->status_code));
/* there are some limitations regarding TE:chunked, see https://tools.ietf.org/html/rfc7230#section-3.3.1 */
- if (ctx->version.major == 1 && ctx->version.minor == 0) {
+ if (UNEXPECTED(ctx->version.major == 1 && ctx->version.minor == 0)) {
ctx->chunked = 0;
- } else if (ctx->status_code == 204 || ctx->status_code/100 == 1) {
+ } else if (UNEXPECTED(ctx->status_code == 204 || ctx->status_code/100 == 1)) {
ctx->chunked = 0;
- } else if (ctx->request && ctx->status_code/100 == 2 && !strcasecmp(ctx->request->http.info.request.method, "CONNECT")) {
+ } else if (UNEXPECTED(ctx->request && ctx->status_code/100 == 2 && !strcasecmp(ctx->request->http.info.request.method, "CONNECT"))) {
ctx->chunked = 0;
}
if (ctx->chunked) {
ctx->chunked_filter = php_stream_filter_create("http.chunked_encode", NULL, 0);
- php_stream_filter_append(&ctx->stream->writefilters, ctx->chunked_filter);
+ if (ctx->chunked_filter) {
+ php_stream_filter_append(&ctx->stream->writefilters, ctx->chunked_filter);
+ }
}
return ctx->started ? SUCCESS : FAILURE;
zend_string *header_key;
ZEND_RESULT_CODE rv;
- if (stream_ctx->started || stream_ctx->finished) {
+ if (UNEXPECTED(stream_ctx->started || stream_ctx->finished)) {
return FAILURE;
}
header_len = vspprintf(&header_str, 0, fmt, argv);
- if (!(header_end = strchr(header_str, ':'))) {
+ if (UNEXPECTED(!(header_end = strchr(header_str, ':')))) {
efree(header_str);
return FAILURE;
}
{
php_http_env_response_stream_ctx_t *ctx = r->ctx;
- if (ctx->finished) {
+ if (UNEXPECTED(ctx->finished)) {
return FAILURE;
}
- if (!ctx->started) {
+ if (UNEXPECTED(!ctx->started)) {
if (SUCCESS != php_http_env_response_stream_start(ctx)) {
return FAILURE;
}
}
static zend_function_entry php_http_env_response_methods[] = {
- PHP_ME(HttpEnvResponse, __construct, ai_HttpEnvResponse___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpEnvResponse, __construct, ai_HttpEnvResponse___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvResponse, __invoke, ai_HttpEnvResponse___invoke, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvResponse, setEnvRequest, ai_HttpEnvResponse_setEnvRequest, ZEND_ACC_PUBLIC)
PHP_ME(HttpEnvResponse, setCookie, ai_HttpEnvResponse_setCookie, ZEND_ACC_PUBLIC)
do { \
zend_error_handling __zeh; \
zend_replace_error_handling(EH_THROW, php_http_get_exception_ ##e## _class_entry(), &__zeh); \
- if (!(test)) { \
+ if (UNEXPECTED(!(test))) { \
zend_restore_error_handling(&__zeh); \
fail; \
} \
ulong hexlen;
} PHP_HTTP_FILTER_BUFFER(chunked_decode);
-typedef php_http_encoding_stream_t PHP_HTTP_FILTER_BUFFER(zlib);
+typedef php_http_encoding_stream_t PHP_HTTP_FILTER_BUFFER(stream);
static PHP_HTTP_FILTER_FUNCTION(chunked_decode)
{
return PSFS_PASS_ON;
}
-static PHP_HTTP_FILTER_OPS(chunked_decode) = {
- PHP_HTTP_FILTER_FUNC(chunked_decode),
- PHP_HTTP_FILTER_DTOR(chunked_decode),
- "http.chunked_decode"
-};
-
-static PHP_HTTP_FILTER_OPS(chunked_encode) = {
- PHP_HTTP_FILTER_FUNC(chunked_encode),
- NULL,
- "http.chunked_encode"
-};
-
-static PHP_HTTP_FILTER_FUNCTION(zlib)
+static PHP_HTTP_FILTER_FUNCTION(stream)
{
php_stream_bucket *ptr, *nxt;
- PHP_HTTP_FILTER_BUFFER(zlib) *buffer = Z_PTR(this->abstract);
+ PHP_HTTP_FILTER_BUFFER(stream) *buffer = Z_PTR(this->abstract);
if (bytes_consumed) {
*bytes_consumed = 0;
}
#if DBG_FILTER
- fprintf(stderr, "update: deflate (-> %zu) (w: %zu, r: %zu)\n", encoded_len, stream->writepos, stream->readpos);
+ fprintf(stderr, "update: compress (-> %zu) (w: %zu, r: %zu)\n", encoded_len, stream->writepos, stream->readpos);
#endif
if (encoded) {
}
#if DBG_FILTER
- fprintf(stderr, "flush: deflate (-> %zu)\n", encoded_len);
+ fprintf(stderr, "flush: compress (-> %zu)\n", encoded_len);
#endif
if (encoded) {
}
#if DBG_FILTER
- fprintf(stderr, "finish: deflate (-> %zu)\n", encoded_len);
+ fprintf(stderr, "finish: compress (-> %zu)\n", encoded_len);
#endif
if (encoded) {
return PSFS_PASS_ON;
}
-static PHP_HTTP_FILTER_DESTRUCTOR(zlib)
+
+static PHP_HTTP_FILTER_DESTRUCTOR(stream)
{
- PHP_HTTP_FILTER_BUFFER(zlib) *buffer = Z_PTR(this->abstract);
+ PHP_HTTP_FILTER_BUFFER(stream) *buffer = Z_PTR(this->abstract);
php_http_encoding_stream_free(&buffer);
}
+static PHP_HTTP_FILTER_OPS(chunked_decode) = {
+ PHP_HTTP_FILTER_FUNC(chunked_decode),
+ PHP_HTTP_FILTER_DTOR(chunked_decode),
+ "http.chunked_decode"
+};
+
+static PHP_HTTP_FILTER_OPS(chunked_encode) = {
+ PHP_HTTP_FILTER_FUNC(chunked_encode),
+ NULL,
+ "http.chunked_encode"
+};
+
static PHP_HTTP_FILTER_OPS(deflate) = {
- PHP_HTTP_FILTER_FUNC(zlib),
- PHP_HTTP_FILTER_DTOR(zlib),
+ PHP_HTTP_FILTER_FUNC(stream),
+ PHP_HTTP_FILTER_DTOR(stream),
"http.deflate"
};
static PHP_HTTP_FILTER_OPS(inflate) = {
- PHP_HTTP_FILTER_FUNC(zlib),
- PHP_HTTP_FILTER_DTOR(zlib),
+ PHP_HTTP_FILTER_FUNC(stream),
+ PHP_HTTP_FILTER_DTOR(stream),
"http.inflate"
};
+#if PHP_HTTP_HAVE_LIBBROTLI
+static PHP_HTTP_FILTER_OPS(brotli_encode) = {
+ PHP_HTTP_FILTER_FUNC(stream),
+ PHP_HTTP_FILTER_DTOR(stream),
+ "http.brotli_encode"
+};
+
+static PHP_HTTP_FILTER_OPS(brotli_decode) = {
+ PHP_HTTP_FILTER_FUNC(stream),
+ PHP_HTTP_FILTER_DTOR(stream),
+ "http.brotli_decode"
+};
+#endif
+
+#if PHP_VERSION_ID >= 70200
+static php_stream_filter *http_filter_create(const char *name, zval *params, uint8_t p)
+#else
static php_stream_filter *http_filter_create(const char *name, zval *params, int p)
+#endif
{
zval *tmp = params;
php_stream_filter *f = NULL;
} else
if (!strcasecmp(name, "http.inflate")) {
- PHP_HTTP_FILTER_BUFFER(zlib) *b = NULL;
+ PHP_HTTP_FILTER_BUFFER(stream) *b = NULL;
if ((b = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_inflate_ops(), flags))) {
if (!(f = php_stream_filter_alloc(&PHP_HTTP_FILTER_OP(inflate), b, p))) {
} else
if (!strcasecmp(name, "http.deflate")) {
- PHP_HTTP_FILTER_BUFFER(zlib) *b = NULL;
+ PHP_HTTP_FILTER_BUFFER(stream) *b = NULL;
if ((b = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_deflate_ops(), flags))) {
if (!(f = php_stream_filter_alloc(&PHP_HTTP_FILTER_OP(deflate), b, p))) {
php_http_encoding_stream_free(&b);
}
}
+#if PHP_HTTP_HAVE_LIBBROTLI
+ } else
+
+ if (!strcasecmp(name, "http.brotli_encode")) {
+ PHP_HTTP_FILTER_BUFFER(stream) *b = NULL;
+
+ if ((b = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_enbrotli_ops(), flags))) {
+ if (!(f = php_stream_filter_alloc(&PHP_HTTP_FILTER_OP(brotli_encode), b, p))) {
+ php_http_encoding_stream_free(&b);
+ }
+ }
+ } else
+
+ if (!strcasecmp(name, "http.brotli_decode")) {
+ PHP_HTTP_FILTER_BUFFER(stream) *b = NULL;
+
+ if ((b = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_debrotli_ops(), flags))) {
+ if (!(f = php_stream_filter_alloc(&PHP_HTTP_FILTER_OP(brotli_decode), b, p))) {
+ php_http_encoding_stream_free(&b);
+ }
+ }
+#endif
}
return f;
}
static zend_function_entry php_http_header_methods[] = {
- PHP_ME(HttpHeader, __construct, ai_HttpHeader___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpHeader, __construct, ai_HttpHeader___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpHeader, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC)
ZEND_MALIAS(HttpHeader, __toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC)
ZEND_MALIAS(HttpHeader, toString, serialize, ai_HttpHeader_serialize, ZEND_ACC_PUBLIC)
return parser;
}
-php_http_header_parser_state_t php_http_header_parser_state_push(php_http_header_parser_t *parser, unsigned argc, ...)
-{
- va_list va_args;
- unsigned i;
- php_http_header_parser_state_t state = 0;
-
- /* short circuit */
- ZEND_PTR_STACK_RESIZE_IF_NEEDED((&parser->stack), argc);
-
- va_start(va_args, argc);
- for (i = 0; i < argc; ++i) {
- state = va_arg(va_args, php_http_header_parser_state_t);
- zend_ptr_stack_push(&parser->stack, (void *) state);
- }
- va_end(va_args);
-
- return state;
-}
+#define php_http_header_parser_state_push(parser, state) zend_ptr_stack_push(&(parser)->stack, (void *) (state)), (state)
+#define php_http_header_parser_state_ex(parser) ((parser)->stack.top \
+ ? (php_http_header_parser_state_t) (parser)->stack.elements[(parser)->stack.top - 1] \
+ : PHP_HTTP_HEADER_PARSER_STATE_START)
php_http_header_parser_state_t php_http_header_parser_state_is(php_http_header_parser_t *parser)
{
- if (parser->stack.top) {
- return (php_http_header_parser_state_t) parser->stack.elements[parser->stack.top - 1];
- }
-
- return PHP_HTTP_HEADER_PARSER_STATE_START;
+ return php_http_header_parser_state_ex(parser);
}
-php_http_header_parser_state_t php_http_header_parser_state_pop(php_http_header_parser_t *parser)
-{
- if (parser->stack.top) {
- return (php_http_header_parser_state_t) zend_ptr_stack_pop(&parser->stack);
- }
-
- return PHP_HTTP_HEADER_PARSER_STATE_START;
-}
+#define php_http_header_parser_state_pop(parser) ((parser)->stack.top \
+ ? (php_http_header_parser_state_t) zend_ptr_stack_pop(&(parser)->stack) \
+ : PHP_HTTP_HEADER_PARSER_STATE_START)
void php_http_header_parser_dtor(php_http_header_parser_t *parser)
{
/* NOTE: 'str' has to be null terminated */
static void php_http_header_parser_error(size_t valid_len, char *str, size_t len, const char *eol_str )
{
- zend_string *escaped_str = zend_string_init(str, len, 0);
+ zend_string *escaped_str, *zstr_str = zend_string_init(str, len, 0);
- escaped_str = php_addcslashes(escaped_str, 1, ZEND_STRL("\x0..\x1F\x7F..\xFF"));
+#if PHP_VERSION_ID < 70300
+ escaped_str = php_addcslashes(zstr_str, 1, ZEND_STRL("\x0..\x1F\x7F..\xFF"));
+#else
+ escaped_str = php_addcslashes(zstr_str, ZEND_STRL("\x0..\x1F\x7F..\xFF"));
+ zend_string_release_ex(zstr_str, 0);
+#endif
if (valid_len != len && (!eol_str || (str+valid_len) != eol_str)) {
php_error_docref(NULL, E_WARNING, "Failed to parse headers: unexpected character '\\%03o' at pos %zu of '%s'", str[valid_len], valid_len, escaped_str->val);
php_http_header_parser_state_t php_http_header_parser_parse(php_http_header_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, HashTable *headers, php_http_info_callback_t callback_func, void *callback_arg)
{
- while (buffer->used || !php_http_header_parser_states[php_http_header_parser_state_is(parser)].need_data) {
+ while (buffer->used || !php_http_header_parser_states[php_http_header_parser_state_ex(parser)].need_data) {
#if DBG_PARSER
const char *state[] = {"START", "KEY", "VALUE", "VALUE_EX", "HEADER_DONE", "DONE"};
fprintf(stderr, "#HP: %s (avail:%zu, num:%d cleanup:%u)\n", php_http_header_parser_state_is(parser) < 0 ? "FAILURE" : state[php_http_header_parser_state_is(parser)], buffer->used, headers?zend_hash_num_elements(headers):0, flags);
switch (php_http_header_parser_state_pop(parser)) {
case PHP_HTTP_HEADER_PARSER_STATE_FAILURE:
php_error_docref(NULL, E_WARNING, "Failed to parse headers");
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
case PHP_HTTP_HEADER_PARSER_STATE_START: {
char *ptr = buffer->data;
}
php_http_buffer_cut(buffer, 0, ptr - buffer->data);
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_KEY);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_KEY);
break;
}
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);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_DONE);
} else if (php_http_info_parse(&parser->info, buffer->data)) {
/* new message starting with request/response line */
if (callback_func) {
}
php_http_info_dtor(&parser->info);
php_http_buffer_cut(buffer, 0, eol_str + eol_len - buffer->data);
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
} else if ((colon = memchr(buffer->data, ':', buffer->used)) && (!eol_str || eol_str > colon)) {
/* header: string */
size_t valid_len;
if (valid_len != parser->_key.len) {
php_http_header_parser_error(valid_len, parser->_key.str, parser->_key.len, eol_str);
PTR_SET(parser->_key.str, NULL);
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
}
while (PHP_HTTP_IS_CTYPE(space, *++colon) && *colon != '\n' && *colon != '\r');
php_http_buffer_cut(buffer, 0, colon - buffer->data);
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
+ php_http_header_parser_state_push(parser, 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_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);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
} else {
/* keep feeding */
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_KEY);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_KEY);
}
break;
}
if ((eol_str = php_http_locate_bin_eol(buffer->data, buffer->used, &eol_len))) {
SET_ADD_VAL(eol_str - buffer->data, eol_len);
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE_EX);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_VALUE_EX);
} else if (flags & PHP_HTTP_HEADER_PARSER_CLEANUP) {
if (buffer->used) {
SET_ADD_VAL(buffer->used, 0);
}
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
} else {
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
}
break;
}
case PHP_HTTP_HEADER_PARSER_STATE_VALUE_EX:
if (buffer->used && (*buffer->data == ' ' || *buffer->data == '\t')) {
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_VALUE);
} else if (buffer->used || (flags & PHP_HTTP_HEADER_PARSER_CLEANUP)) {
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_HEADER_DONE);
} else {
/* keep feeding */
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_VALUE_EX);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_VALUE_EX);
}
break;
PTR_SET(parser->_key.str, NULL);
PTR_SET(parser->_val.str, NULL);
- return php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
+ return php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_FAILURE);
}
if (!headers && callback_func) {
PTR_SET(parser->_key.str, NULL);
PTR_SET(parser->_val.str, NULL);
- php_http_header_parser_state_push(parser, 1, PHP_HTTP_HEADER_PARSER_STATE_KEY);
+ php_http_header_parser_state_push(parser, PHP_HTTP_HEADER_PARSER_STATE_KEY);
break;
case PHP_HTTP_HEADER_PARSER_STATE_DONE:
} php_http_header_parser_t;
PHP_HTTP_API php_http_header_parser_t *php_http_header_parser_init(php_http_header_parser_t *parser);
-PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_push(php_http_header_parser_t *parser, unsigned argc, ...);
PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_is(php_http_header_parser_t *parser);
-PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_state_pop(php_http_header_parser_t *parser);
PHP_HTTP_API void php_http_header_parser_dtor(php_http_header_parser_t *parser);
PHP_HTTP_API void php_http_header_parser_free(php_http_header_parser_t **parser);
PHP_HTTP_API php_http_header_parser_state_t php_http_header_parser_parse(php_http_header_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, HashTable *headers, php_http_info_callback_t callback_func, void *callback_arg);
zend_bool free_info = !info;
/* sane parameter */
- if ((!pre_header) || (!*pre_header)) {
+ if (UNEXPECTED((!pre_header) || (!*pre_header))) {
return NULL;
}
/* where's the end of the line */
- if (!(end = php_http_locate_eol(pre_header, NULL))) {
+ if (UNEXPECTED(!(end = php_http_locate_eol(pre_header, NULL)))) {
end = pre_header + strlen(pre_header);
}
info = php_http_info_init(info);
- if (!php_http_version_parse(&info->http.version, http)) {
+ if (UNEXPECTED(!php_http_version_parse(&info->http.version, http))) {
if (free_info) {
php_http_info_free(&info);
}
}
/* and nothing than SPACE or NUL after HTTP/X(.x) */
- if (*off && (!PHP_HTTP_IS_CTYPE(space, *off))) {
+ if (UNEXPECTED(*off && (!PHP_HTTP_IS_CTYPE(space, *off)))) {
if (free_info) {
php_http_info_free(&info);
}
info->type = PHP_HTTP_RESPONSE;
while (code < end && ' ' == *code) ++code;
- if (end > code) {
+ if (EXPECTED(end > code)) {
/* rfc7230#3.1.2 The status-code element is a 3-digit integer code */
PHP_HTTP_INFO(info).response.code = 100*(*code++ - '0');
PHP_HTTP_INFO(info).response.code += 10*(*code++ - '0');
} else {
PHP_HTTP_INFO(info).response.code = 0;
}
- if (status && end > status) {
- while (' ' == *status) ++status;
+ if (EXPECTED(status && end > status)) {
+ while (' ' == *status && end > status) ++status;
PHP_HTTP_INFO(info).response.status = estrndup(status, end - status);
} else {
PHP_HTTP_INFO(info).response.status = NULL;
const char *url = strchr(pre_header, ' ');
info->type = PHP_HTTP_REQUEST;
- if (url && http > url) {
+ if (EXPECTED(url && http > url)) {
size_t url_len = url - pre_header;
PHP_HTTP_INFO(info).request.method = estrndup(pre_header, url_len);
- while (' ' == *url) ++url;
+ while (' ' == *url && http > url) ++url;
while (' ' == *(http-1)) --http;
- if (http > url) {
+ if (EXPECTED(http > url)) {
/* CONNECT presents an authority only */
- if (strcasecmp(PHP_HTTP_INFO(info).request.method, "CONNECT")) {
+ if (UNEXPECTED(strcasecmp(PHP_HTTP_INFO(info).request.method, "CONNECT"))) {
PHP_HTTP_INFO(info).request.url = php_http_url_parse(url, http - url, PHP_HTTP_URL_STDFLAGS);
} else {
PHP_HTTP_INFO(info).request.url = php_http_url_parse_authority(url, http - url, PHP_HTTP_URL_STDFLAGS);
break;
case PHP_HTTP_RESPONSE:
- message = php_http_message_init(NULL, type, NULL);
+ message = php_http_message_init(message, type, NULL);
if (!SG(sapi_headers).http_status_line || !php_http_info_parse((php_http_info_t *) &message->http, SG(sapi_headers).http_status_line)) {
if (!(message->http.info.response.code = SG(sapi_headers).http_response_code)) {
message->http.info.response.code = 200;
popts.input.str = ct->val;
popts.input.len = ct->len;
- if (php_http_params_parse(¶ms, &popts)) {
+ if (EXPECTED(php_http_params_parse(¶ms, &popts))) {
zval *cur, *arg;
zend_string *ct_str;
zend_ulong index;
zend_hash_internal_pointer_reset(¶ms);
- if ((cur = zend_hash_get_current_data(¶ms))
+ if (EXPECTED((cur = zend_hash_get_current_data(¶ms))
&& (Z_TYPE_P(cur) == IS_ARRAY)
- && (HASH_KEY_IS_STRING == zend_hash_get_current_key(¶ms, &ct_str, &index))
+ && (HASH_KEY_IS_STRING == zend_hash_get_current_key(¶ms, &ct_str, &index)))
) {
if (php_http_match(ct_str->val, "multipart", PHP_HTTP_MATCH_WORD)) {
is_multipart = 1;
/* get boundary */
- if (boundary
+ if (EXPECTED(boundary
&& (arg = zend_hash_str_find(Z_ARRVAL_P(cur), ZEND_STRL("arguments")))
- && Z_TYPE_P(arg) == IS_ARRAY
+ && Z_TYPE_P(arg) == IS_ARRAY)
) {
zval *val;
php_http_arrkey_t key;
if (key.key && key.key->len == lenof("boundary") && !strcasecmp(key.key->val, "boundary")) {
zend_string *bnd = zval_get_string(val);
- if (bnd->len) {
+ if (EXPECTED(bnd->len)) {
*boundary = estrndup(bnd->val, bnd->len);
}
zend_string_release(bnd);
void php_http_message_dtor(php_http_message_t *message)
{
- if (message) {
+ if (EXPECTED(message)) {
zend_hash_destroy(&message->hdrs);
php_http_message_body_free(&message->body);
void php_http_message_free(php_http_message_t **message)
{
- if (*message) {
+ if (EXPECTED(*message)) {
if ((*message)->parent) {
php_http_message_free(&(*message)->parent);
}
return zend_hash_str_find_ptr(&php_http_message_object_prophandlers, name_str->val, name_str->len);
}
static void php_http_message_object_prophandler_get_type(php_http_message_object_t *obj, zval *return_value) {
+ zval_ptr_dtor(return_value);
RETVAL_LONG(obj->message->type);
}
static void php_http_message_object_prophandler_set_type(php_http_message_object_t *obj, zval *value) {
php_http_message_set_type(obj->message, zval_get_long(value));
}
static void php_http_message_object_prophandler_get_request_method(php_http_message_object_t *obj, zval *return_value) {
+ zval_ptr_dtor(return_value);
if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message) && obj->message->http.info.request.method) {
RETVAL_STRING(obj->message->http.info.request.method);
} else {
char *url_str;
size_t url_len;
+ zval_ptr_dtor(return_value);
if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message) && obj->message->http.info.request.url && php_http_url_to_string(obj->message->http.info.request.url, &url_str, &url_len, 0)) {
RETVAL_STR(php_http_cs2zs(url_str, url_len));
} else {
}
}
static void php_http_message_object_prophandler_get_response_status(php_http_message_object_t *obj, zval *return_value) {
+ zval_ptr_dtor(return_value);
if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message) && obj->message->http.info.response.status) {
RETVAL_STRING(obj->message->http.info.response.status);
} else {
}
}
static void php_http_message_object_prophandler_get_response_code(php_http_message_object_t *obj, zval *return_value) {
+ zval_ptr_dtor(return_value);
if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
RETVAL_LONG(obj->message->http.info.response.code);
} else {
char *version_str;
size_t version_len;
+ zval_ptr_dtor(return_value);
php_http_version_to_string(&obj->message->http.version, &version_str, &version_len, NULL, NULL);
RETVAL_STR(php_http_cs2zs(version_str, version_len));
}
zend_string_release(zs);
}
static void php_http_message_object_prophandler_get_headers(php_http_message_object_t *obj, zval *return_value ) {
+ zval tmp;
+
+ ZVAL_COPY_VALUE(&tmp, return_value);
array_init(return_value);
array_copy(&obj->message->hdrs, Z_ARRVAL_P(return_value));
+ zval_ptr_dtor(&tmp);
}
static void php_http_message_object_prophandler_set_headers(php_http_message_object_t *obj, zval *value) {
- HashTable *headers;
- zval *orig_value = value;
+ int converted = 0;
+ HashTable garbage, *src;
if (Z_TYPE_P(value) != IS_ARRAY && Z_TYPE_P(value) != IS_OBJECT) {
- convert_to_array_ex(value);
+ converted = 1;
+ SEPARATE_ZVAL(value);
+ convert_to_array(value);
}
- headers = HASH_OF(value);
+ src = HASH_OF(value);
- zend_hash_clean(&obj->message->hdrs);
- array_copy(headers, &obj->message->hdrs);
+ garbage = obj->message->hdrs;
+ zend_hash_init(&obj->message->hdrs, zend_hash_num_elements(src), NULL, ZVAL_PTR_DTOR, 0);
+ array_copy(HASH_OF(value), &obj->message->hdrs);
- if (orig_value != value) {
+ zend_hash_destroy(&garbage);
+
+ if (converted) {
zval_ptr_dtor(value);
}
}
static void php_http_message_object_prophandler_get_body(php_http_message_object_t *obj, zval *return_value) {
if (obj->body) {
+ zval tmp;
+
+ ZVAL_COPY_VALUE(&tmp, return_value);
RETVAL_OBJECT(&obj->body->zo, 1);
+ zval_ptr_dtor(&tmp);
} else {
RETVAL_NULL();
}
}
static void php_http_message_object_prophandler_get_parent_message(php_http_message_object_t *obj, zval *return_value) {
if (obj->message->parent) {
+ zval tmp;
+
+ ZVAL_COPY_VALUE(&tmp, return_value);
RETVAL_OBJECT(&obj->parent->zo, 1);
+ zval_ptr_dtor(&tmp);
} else {
RETVAL_NULL();
}
if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_message_class_entry)) {
php_http_message_object_t *parent_obj = PHP_HTTP_OBJ(NULL, value);
+ Z_ADDREF_P(value);
if (obj->message->parent) {
zend_object_release(&obj->parent->zo);
}
- Z_ADDREF_P(value);
obj->parent = parent_obj;
obj->message->parent = parent_obj->message;
}
zend_object *php_http_message_object_clone(zval *this_ptr)
{
- php_http_message_object_t *new_obj = NULL;
+ php_http_message_object_t *new_obj;
php_http_message_object_t *old_obj = PHP_HTTP_OBJ(NULL, this_ptr);
new_obj = php_http_message_object_new_ex(old_obj->zo.ce, php_http_message_copy(old_obj->message, NULL));
zend_string *member_name = zval_get_string(member);
php_http_message_object_prophandler_t *handler = php_http_message_object_get_prophandler(member_name);
- if (!handler || type == BP_VAR_R || type == BP_VAR_IS) {
- return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
+ return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
- if (handler) {
+ if (handler && handler->read) {
+ if (type == BP_VAR_R || type == BP_VAR_IS) {
php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object);
- PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
- handler->read(obj, tmp);
-
- //zval_ptr_dtor(return_value);
- ZVAL_COPY_VALUE(return_value, tmp);
- }
- zend_string_release(member_name);
- return return_value;
- } else {
- php_property_proxy_t *proxy;
- php_property_proxy_object_t *proxy_obj;
+ handler->read(obj, return_value);
+ } else {
+ php_property_proxy_t *proxy;
+ php_property_proxy_object_t *proxy_obj;
- proxy = php_property_proxy_init(object, member_name);
- proxy_obj = php_property_proxy_object_new_ex(NULL, proxy);
+ proxy = php_property_proxy_init(object, member_name);
+ proxy_obj = php_property_proxy_object_new_ex(NULL, proxy);
- ZVAL_OBJ(tmp, &proxy_obj->zo);
- zend_string_release(member_name);
- return tmp;
+ ZVAL_OBJ(tmp, &proxy_obj->zo);
+ return_value = tmp;
+ }
}
+
+ zend_string_release(member_name);
+ return return_value;
}
static void php_http_message_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot)
if (!obj->body) {
php_http_message_object_init_body_object(obj);
-
}
if (obj->body) {
RETVAL_OBJECT(&obj->body->zo, 1);
}
static zend_function_entry php_http_message_methods[] = {
- PHP_ME(HttpMessage, __construct, ai_HttpMessage___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpMessage, __construct, ai_HttpMessage___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpMessage, getBody, ai_HttpMessage_getBody, ZEND_ACC_PUBLIC)
PHP_ME(HttpMessage, setBody, ai_HttpMessage_setBody, ZEND_ACC_PUBLIC)
PHP_ME(HttpMessage, addBody, ai_HttpMessage_addBody, ZEND_ACC_PUBLIC)
php_http_message_body_addref(body);
return body;
}
-
+
body = ecalloc(1, sizeof(php_http_message_body_t));
body->refcount = 1;
if (stream) {
body->res = stream->res;
- ++GC_REFCOUNT(body->res);
+ GC_ADDREF(body->res);
} else {
body->res = php_stream_temp_create(TEMP_STREAM_DEFAULT, 0xffff)->res;
}
{
if (*body_ptr) {
php_http_message_body_t *body = *body_ptr;
-
if (!--body->refcount) {
zend_list_delete(body->res);
+ body->res = NULL;
PTR_FREE(body->boundary);
efree(body);
}
ZEND_RESULT_CODE php_http_message_body_add_form_field(php_http_message_body_t *body, const char *name, const char *value_str, size_t value_len)
{
- zend_string *safe_name = zend_string_init(name, strlen(name), 0);
+ zend_string *safe_name, *zstr_name = zend_string_init(name, strlen(name), 0);
- safe_name = php_addslashes(safe_name, 1);
+#if PHP_VERSION_ID < 70300
+ safe_name = php_addslashes(zstr_name, 1);
+#else
+ safe_name = php_addslashes(zstr_name);
+ zend_string_release_ex(zstr_name, 0);
+#endif
BOUNDARY_OPEN(body);
php_http_message_body_appendf(
{
size_t path_len = strlen(path);
char *path_dup = estrndup(path, path_len);
- zend_string *base_name, *safe_name = zend_string_init(name, strlen(name), 0);
-
- safe_name = php_addslashes(safe_name, 1);
+ zend_string *base_name, *safe_name, *zstr_name = zend_string_init(name, strlen(name), 0);
+
+#if PHP_VERSION_ID < 70300
+ safe_name = php_addslashes(zstr_name, 1);
+#else
+ safe_name = php_addslashes(zstr_name);
+ zend_string_release_ex(zstr_name, 0);
+#endif
base_name = php_basename(path_dup, path_len, NULL, 0);
BOUNDARY_OPEN(body);
zval *val;
php_http_arrkey_t key;
- if (!ZEND_HASH_GET_APPLY_COUNT(fields)) {
- ZEND_HASH_INC_APPLY_COUNT(fields);
+ if (!HT_IS_RECURSIVE(fields)) {
+ HT_PROTECT_RECURSION(fields);
ZEND_HASH_FOREACH_KEY_VAL_IND(fields, key.h, key.key, val)
{
char *str = format_key(&key, name);
if (Z_TYPE_P(val) != IS_ARRAY && Z_TYPE_P(val) != IS_OBJECT) {
if (SUCCESS != add_recursive_field_value(body, str, val)) {
efree(str);
- ZEND_HASH_DEC_APPLY_COUNT(fields);
+ HT_UNPROTECT_RECURSION(fields);
return FAILURE;
}
} else if (SUCCESS != add_recursive_fields(body, str, HASH_OF(val))) {
efree(str);
- ZEND_HASH_DEC_APPLY_COUNT(fields);
+ HT_UNPROTECT_RECURSION(fields);
return FAILURE;
}
efree(str);
}
ZEND_HASH_FOREACH_END();
- ZEND_HASH_DEC_APPLY_COUNT(fields);
+ HT_UNPROTECT_RECURSION(fields);
}
return SUCCESS;
zval *val;
php_http_arrkey_t key;
- if (!ZEND_HASH_GET_APPLY_COUNT(files)) {
- ZEND_HASH_INC_APPLY_COUNT(files);
+ if (!HT_IS_RECURSIVE(files)) {
+ HT_PROTECT_RECURSION(files);
ZEND_HASH_FOREACH_KEY_VAL_IND(files, key.h, key.key, val)
{
if (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT) {
if (SUCCESS != add_recursive_files(body, str, HASH_OF(val))) {
efree(str);
- ZEND_HASH_DEC_APPLY_COUNT(files);
+ HT_UNPROTECT_RECURSION(files);
return FAILURE;
}
efree(str);
}
}
ZEND_HASH_FOREACH_END();
- ZEND_HASH_DEC_APPLY_COUNT(files);
+ HT_UNPROTECT_RECURSION(files);
}
return SUCCESS;
} else {
if (body) {
o->body = body;
- php_stream_to_zval(php_http_message_body_stream(o->body), o->gc);
-
}
o->zo.handlers = &php_http_message_body_object_handlers;
zend_object *php_http_message_body_object_clone(zval *object)
{
- php_http_message_body_object_t *new_obj = NULL;
+ php_http_message_body_object_t *new_obj;
php_http_message_body_object_t *old_obj = PHP_HTTP_OBJ(NULL, object);
php_http_message_body_t *body = php_http_message_body_copy(old_obj->body, NULL);
HashTable *props = Z_OBJPROP_P(object);
uint32_t count = zend_hash_num_elements(props);
- *n = 1;
+ obj->gc = erealloc(obj->gc, (1 + count) * sizeof(zval));
+
+ if (php_http_message_body_stream(obj->body)) {
+ *n = 1;
+ php_stream_to_zval(php_http_message_body_stream(obj->body), obj->gc);
+ } else {
+ *n = 0;
+ }
+
if (count) {
zval *val;
- obj->gc = erealloc(obj->gc, (*n + count) * sizeof(zval));
-
ZEND_HASH_FOREACH_VAL(props, val)
{
ZVAL_COPY_VALUE(&obj->gc[(*n)++], val);
}
static zend_function_entry php_http_message_body_methods[] = {
- PHP_ME(HttpMessageBody, __construct, ai_HttpMessageBody___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpMessageBody, __construct, ai_HttpMessageBody___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpMessageBody, __toString, ai_HttpMessageBody___toString, ZEND_ACC_PUBLIC)
PHP_MALIAS(HttpMessageBody, toString, __toString, ai_HttpMessageBody___toString, ZEND_ACC_PUBLIC)
PHP_MALIAS(HttpMessageBody, serialize, __toString, ai_HttpMessageBody___toString, ZEND_ACC_PUBLIC)
return parser;
}
-php_http_message_parser_state_t php_http_message_parser_state_push(php_http_message_parser_t *parser, unsigned argc, ...)
-{
- php_http_message_parser_state_t state = PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;
- va_list va_args;
- unsigned i;
-
- if (argc > 0) {
- /* short circuit */
- ZEND_PTR_STACK_RESIZE_IF_NEEDED((&parser->stack), argc);
-
- va_start(va_args, argc);
- for (i = 0; i < argc; ++i) {
- state = va_arg(va_args, php_http_message_parser_state_t);
- zend_ptr_stack_push(&parser->stack, (void *) state);
- }
- va_end(va_args);
- }
-
- return state;
-}
-
+#define php_http_message_parser_state_push(parser, state) zend_ptr_stack_push(&(parser)->stack, (void *) (state)), (state)
+#define php_http_message_parser_state_pop(parser) ((parser)->stack.top \
+ ? (php_http_message_parser_state_t) zend_ptr_stack_pop(&parser->stack) \
+ : PHP_HTTP_MESSAGE_PARSER_STATE_START)
+#define php_http_message_parser_state_is_ex(parser) ((parser)->stack.top \
+ ? (php_http_message_parser_state_t) (parser)->stack.elements[(parser)->stack.top - 1] \
+ : PHP_HTTP_MESSAGE_PARSER_STATE_START)
php_http_message_parser_state_t php_http_message_parser_state_is(php_http_message_parser_t *parser)
{
- if (parser->stack.top) {
- return (php_http_message_parser_state_t) parser->stack.elements[parser->stack.top - 1];
- }
- return PHP_HTTP_MESSAGE_PARSER_STATE_START;
-}
-
-php_http_message_parser_state_t php_http_message_parser_state_pop(php_http_message_parser_t *parser)
-{
- if (parser->stack.top) {
- return (php_http_message_parser_state_t) zend_ptr_stack_pop(&parser->stack);
- }
- return PHP_HTTP_MESSAGE_PARSER_STATE_START;
+ return php_http_message_parser_state_is_ex(parser);
}
void php_http_message_parser_dtor(php_http_message_parser_t *parser)
case PHP_HTTP_MESSAGE_PARSER_STATE_DONE:
case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE:
- return php_http_message_parser_state_is(parser);
+ return php_http_message_parser_state_is_ex(parser);
}
if (justread) {
size_t len = 0;
size_t cut = 0;
- while (buffer->used || !php_http_message_parser_states[php_http_message_parser_state_is(parser)].need_data) {
+ while (buffer->used || !php_http_message_parser_states[php_http_message_parser_state_is_ex(parser)].need_data) {
#if DBG_PARSER
fprintf(stderr, "#MP: %s (f: %u, t:%d, l:%zu)\n",
php_http_message_parser_state_name(php_http_message_parser_state_is(parser)),
switch (php_http_message_parser_state_pop(parser))
{
case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE:
- return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
+ return php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
case PHP_HTTP_MESSAGE_PARSER_STATE_START:
{
php_http_buffer_cut(buffer, 0, ptr - buffer->data);
if (buffer->used) {
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
}
break;
}
return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;
case PHP_HTTP_HEADER_PARSER_STATE_DONE:
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
break;
default:
if (buffer->used || !(flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP)) {
- return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
+ return php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER);
} else {
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE);
}
}
break;
if (php_http_match(con->val, "close", PHP_HTTP_MATCH_WORD)) {
zend_string_release(con);
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
break;
}
zend_string_release(con);
}
if ((flags & PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES)) {
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
} else {
if (chunked) {
parser->dechunk = php_http_encoding_stream_init(parser->dechunk, php_http_encoding_stream_get_dechunk_ops(), 0);
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
break;
}
if (end >= start && (!total || end <= total)) {
parser->body_length = end + 1 - start;
- php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ if (parser->body_length) {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ } else {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ }
zend_string_release(content_range);
break;
}
if (content_length >= 0) {
parser->body_length = content_length;
- php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ if (parser->body_length) {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ } else {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ }
break;
}
if ((*message)->type == PHP_HTTP_REQUEST) {
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
} else {
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB);
}
}
break;
size_t dec_len;
if (SUCCESS != php_http_encoding_stream_update(parser->inflate, str, len, &dec_str, &dec_len)) {
- return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
+ return php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
}
if (str != buffer->data) {
len = buffer->used;
cut = len;
- php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
break;
}
parser->body_length -= len;
- php_http_message_parser_state_push(parser, 2, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ if (parser->body_length) {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH);
+ } else {
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ }
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
break;
}
if (php_http_encoding_stream_done(parser->dechunk)) {
cut = buffer->used - PHP_HTTP_BUFFER(parser->dechunk->ctx)->used;
- php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
} else {
cut = buffer->used;
- php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
}
break;
}
case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:
{
- php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_DONE);
if (parser->dechunk && parser->dechunk->ctx) {
char *dec_str = NULL;
size_t dec_len;
if (SUCCESS != php_http_encoding_stream_finish(parser->dechunk, &dec_str, &dec_len)) {
- return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
+ return php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE);
}
php_http_encoding_stream_dtor(parser->dechunk);
str = dec_str;
len = dec_len;
cut = 0;
- php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL);
+ php_http_message_parser_state_push(parser, PHP_HTTP_MESSAGE_PARSER_STATE_BODY);
}
}
}
}
- return php_http_message_parser_state_is(parser);
+ return php_http_message_parser_state_is_ex(parser);
}
static zend_class_entry *php_http_message_parser_class_entry;
zend_parse_parameters_none();
/* always return the real state */
- RETVAL_LONG(php_http_message_parser_state_is(parser_obj->parser));
+ RETVAL_LONG(php_http_message_parser_state_is_ex(parser_obj->parser));
}
ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_parse, 0, 0, 3)
} php_http_message_parser_t;
PHP_HTTP_API php_http_message_parser_t *php_http_message_parser_init(php_http_message_parser_t *parser);
-PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_push(php_http_message_parser_t *parser, unsigned argc, ...);
PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_is(php_http_message_parser_t *parser);
-PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_state_pop(php_http_message_parser_t *parser);
PHP_HTTP_API void php_http_message_parser_dtor(php_http_message_parser_t *parser);
PHP_HTTP_API void php_http_message_parser_free(php_http_message_parser_t **parser);
PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message);
{
int result = 0;
- if (!haystack_str || !needle_str) {
+ if (UNEXPECTED(!haystack_str || !needle_str)) {
return result;
}
- if (flags & PHP_HTTP_MATCH_FULL) {
+ if (UNEXPECTED(flags & PHP_HTTP_MATCH_FULL)) {
if (flags & PHP_HTTP_MATCH_CASE) {
result = !strcmp(haystack_str, needle_str);
} else {
const char *found;
char *haystack = estrdup(haystack_str), *needle = estrdup(needle_str);
- if (flags & PHP_HTTP_MATCH_CASE) {
+ if (UNEXPECTED(flags & PHP_HTTP_MATCH_CASE)) {
found = zend_memnstr(haystack, needle, strlen(needle), haystack+strlen(haystack));
} else {
found = php_stristr(haystack, needle, strlen(haystack), strlen(needle));
if (found) {
if (!(flags & PHP_HTTP_MATCH_WORD)
|| ( (found == haystack || !PHP_HTTP_IS_CTYPE(alnum, *(found - 1)))
- && (!*(found + strlen(needle)) || !PHP_HTTP_IS_CTYPE(alnum, *(found + strlen(needle))))
+ && EXPECTED(!*(found + strlen(needle)) || !PHP_HTTP_IS_CTYPE(alnum, *(found + strlen(needle))))
)
) {
result = 1;
return result;
}
-char *php_http_pretty_key(register char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
+char *php_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
{
- size_t i = 1;
+ size_t i;
int wasalpha;
if (key && key_len) {
- if ((wasalpha = PHP_HTTP_IS_CTYPE(alpha, key[0]))) {
- key[0] = (char) (uctitle ? PHP_HTTP_TO_CTYPE(upper, key[0]) : PHP_HTTP_TO_CTYPE(lower, key[0]));
+ if (EXPECTED(wasalpha = PHP_HTTP_IS_CTYPE(alpha, key[0]))) {
+ if (EXPECTED(uctitle)) {
+ key[0] = PHP_HTTP_TO_CTYPE(upper, key[0]);
+ } else {
+ key[0] = PHP_HTTP_TO_CTYPE(lower, key[0]);
+ }
}
- PHP_HTTP_DUFF(key_len,
- if (PHP_HTTP_IS_CTYPE(alpha, key[i])) {
- key[i] = (char) (((!wasalpha) && uctitle) ? PHP_HTTP_TO_CTYPE(upper, key[i]) : PHP_HTTP_TO_CTYPE(lower, key[i]));
- wasalpha = 1;
+ for (i = 1; i < key_len; ++i) {
+ if (EXPECTED(PHP_HTTP_IS_CTYPE(alpha, key[i]))) {
+ if (EXPECTED(wasalpha)) {
+ key[i] = PHP_HTTP_TO_CTYPE(lower, key[i]);
+ } else if (EXPECTED(uctitle)) {
+ key[i] = PHP_HTTP_TO_CTYPE(upper, key[i]);
+ wasalpha = 1;
+ } else {
+ key[i] = PHP_HTTP_TO_CTYPE(lower, key[i]);
+ wasalpha = 1;
+ }
} else {
- if (xhyphen && (key[i] == '_')) {
+ if (EXPECTED(xhyphen && (key[i] == '_'))) {
key[i] = '-';
}
wasalpha = 0;
}
- ++i;
- );
+ }
}
return key;
}
if (flags & ARRAY_JOIN_STRINGIFY) {
convert_to_string_ex(value);
}
- Z_ADDREF_P(value);
+ Z_TRY_ADDREF_P(value);
if (data) {
if (Z_TYPE_P(data) != IS_ARRAY) {
size_t php_http_boundary(char *buf, size_t len);
int php_http_select_str(const char *cmp, int argc, ...);
-/* See "A Reusable Duff Device" By Ralf Holly, August 01, 2005 */
-#define PHP_HTTP_DUFF_BREAK() times_=1
-#define PHP_HTTP_DUFF(c, a) do { \
- size_t count_ = (c); \
- size_t times_ = (count_ + 7) >> 3; \
- switch (count_ & 7){ \
- case 0: do { \
- a; \
- case 7: \
- a; \
- case 6: \
- a; \
- case 5: \
- a; \
- case 4: \
- a; \
- case 3: \
- a; \
- case 2: \
- a; \
- case 1: \
- a; \
- } while (--times_ > 0); \
- } \
-} while (0)
-
-static inline const char *php_http_locate_str(register const char *h, size_t h_len, const char *n, size_t n_len)
-{
- if (!n_len || !h_len || h_len < n_len) {
- return NULL;
- }
-
- PHP_HTTP_DUFF(h_len - n_len + 1,
- if (*h == *n && !strncmp(h + 1, n + 1, n_len - 1)) {
- return h;
- }
- ++h;
- );
-
- return NULL;
-}
+#define php_http_locate_str(h, h_len, n, n_len) zend_memnstr((h), (n), (n_len), (h)+(h_len))
static inline const char *php_http_locate_eol(const char *line, int *eol_len)
{
{
register const char *eol = bin;
- if (len > 0) {
- PHP_HTTP_DUFF(len,
- if (*eol == '\r' || *eol == '\n') {
- if (eol_len) {
- *eol_len = ((eol[0] == '\r' && eol[1] == '\n') ? 2 : 1);
- }
- return eol;
+ while (len--) {
+ if (UNEXPECTED(*eol == '\r' || *eol == '\n')) {
+ if (EXPECTED(eol_len)) {
+ *eol_len = (EXPECTED(eol[0] == '\r' && eol[1] == '\n') ? 2 : 1);
}
- ++eol;
- );
+ return eol;
+ }
+ ++eol;
}
return NULL;
}
# define HASH_OF(p) ((HashTable*)(Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p)) : NULL))))
#endif
+#ifndef GC_SET_REFCOUNT
+# define GC_SET_REFCOUNT(gc, rc) GC_REFCOUNT(gc) = rc
+#endif
+#ifndef GC_ADDREF
+# define GC_ADDREF(gc) ++GC_REFCOUNT(gc)
+#endif
+#ifndef GC_DELREF
+# define GC_DELREF(gc) --GC_REFCOUNT(gc)
+#endif
+
+#ifdef ZEND_HASH_GET_APPLY_COUNT
+# define HT_IS_RECURSIVE(ht) (ZEND_HASH_GET_APPLY_COUNT(ht) > 0)
+#else
+# define HT_IS_RECURSIVE(ht) GC_IS_RECURSIVE(ht)
+#endif
+#ifdef ZEND_HASH_INC_APPLY_COUNT
+# define HT_PROTECT_RECURSION(ht) ZEND_HASH_INC_APPLY_COUNT(ht)
+#else
+# define HT_PROTECT_RECURSION(ht) GC_PROTECT_RECURSION(ht)
+#endif
+#ifdef ZEND_HASH_DEC_APPLY_COUNT
+# define HT_UNPROTECT_RECURSION(ht) ZEND_HASH_DEC_APPLY_COUNT(ht)
+#else
+# define HT_UNPROTECT_RECURSION(ht) GC_UNPROTECT_RECURSION(ht)
+#endif
+
static inline void *PHP_HTTP_OBJ(zend_object *zo, zval *zv)
{
if (!zo) {
str->len = l;
str->h = 0;
- GC_REFCOUNT(str) = 1;
+ GC_SET_REFCOUNT(str, 1);
GC_TYPE_INFO(str) = IS_STRING;
return str;
cb->fci.size = sizeof(cb->fci);
ZVAL_STRINGL(&cb->fci.function_name, method_str, method_len);
+#if PHP_VERSION_ID < 70300
cb->fcc.initialized = 1;
+#endif
cb->fcc.calling_scope = cb->fcc.called_scope = Z_OBJCE_P(zobject);
cb->fcc.function_handler = Z_OBJ_HT_P(zobject)->get_method(&Z_OBJ_P(zobject), Z_STR(cb->fci.function_name), NULL);
{
php_http_option_t *opt = Z_PTR_P(pData);
- zval_ptr_dtor(&opt->defval);
+ zval_internal_dtor(&opt->defval);
zend_hash_destroy(&opt->suboptions.options);
zend_string_release(opt->name);
pefree(opt, opt->persistent);
{
size_t len = (zs)->len;
+#if PHP_VERSION_ID < 70300
zs = php_addcslashes(zs, 0, ZEND_STRL("\0..\37\173\\\""));
+#else
+ zs = php_addcslashes(zs, ZEND_STRL("\0..\37\173\\\""));
+#endif
if (force || len != (zs)->len || strpbrk((zs)->val, "()<>@,;:\"[]?={} ")) {
int len = (zs)->len + 2;
static void sanitize_dimension(zval *zv)
{
- zval arr, tmp, *cur = NULL;
+ zval arr, tmp, *cur = &arr;
char *var = NULL, *ptr = Z_STRVAL_P(zv), *end = Z_STRVAL_P(zv) + Z_STRLEN_P(zv);
long level = 0;
array_init(&arr);
- cur = &arr;
while (ptr < end) {
if (!var) {
zval *val;
php_http_buffer_t prefix;
- if (!ZEND_HASH_GET_APPLY_COUNT(ht)) {
- ZEND_HASH_INC_APPLY_COUNT(ht);
+ if (!HT_IS_RECURSIVE(ht)) {
+ HT_PROTECT_RECURSION(ht);
php_http_buffer_init(&prefix);
php_http_buffer_append(&prefix, keybuf->data, keybuf->used);
php_http_buffer_cut(&prefix, keybuf->used, prefix.used - keybuf->used);
}
ZEND_HASH_FOREACH_END();
- ZEND_HASH_DEC_APPLY_COUNT(ht);
+ HT_UNPROTECT_RECURSION(ht);
php_http_buffer_dtor(&prefix);
}
}
static zend_function_entry php_http_params_methods[] = {
- PHP_ME(HttpParams, __construct, ai_HttpParams___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
+ PHP_ME(HttpParams, __construct, ai_HttpParams___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(HttpParams, toArray, ai_HttpParams_toArray, ZEND_ACC_PUBLIC)
PHP_ME(HttpParams, toString, ai_HttpParams_toString, ZEND_ACC_PUBLIC)
ZVAL_MAKE_REF(_GET);
zend_update_property(php_http_querystring_class_entry, return_value, ZEND_STRL("queryArray"), _GET);
-
- zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), return_value);
} else {
php_http_throw(unexpected_val, "Could not acquire reference to superglobal GET array", NULL);
}
}
static zend_function_entry php_http_querystring_methods[] = {
- PHP_ME(HttpQueryString, __construct, ai_HttpQueryString___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
+ PHP_ME(HttpQueryString, __construct, ai_HttpQueryString___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(HttpQueryString, toArray, ai_HttpQueryString_toArray, ZEND_ACC_PUBLIC)
PHP_ME(HttpQueryString, toString, ai_HttpQueryString_toString, ZEND_ACC_PUBLIC)
#include "php_http_api.h"
-#if PHP_HTTP_HAVE_LIBIDN2
-# include <idn2.h>
-#endif
#if PHP_HTTP_HAVE_LIBIDN
# include <idna.h>
#endif
+#if PHP_HTTP_HAVE_LIBIDN2
+# include <idn2.h>
+#endif
#if PHP_HTTP_HAVE_LIBICU
+# include <unicode/uchar.h>
# include <unicode/uidna.h>
#endif
#if PHP_HTTP_HAVE_LIBIDNKIT || PHP_HTTP_HAVE_LIBIDNKIT2
static inline char *localhostname(void)
{
char hostname[1024] = {0};
-
+
#if PHP_WIN32
if (SUCCESS == gethostname(hostname, lenof(hostname))) {
return estrdup(hostname);
if (!(flags & PHP_HTTP_URL_STRIP_PASS)) {
url_copy(pass);
}
-
+
url_copy(host);
-
+
if (!(flags & PHP_HTTP_URL_STRIP_PORT)) {
url(buf)->port = url_isset(new_url, port) ? new_url->port : ((old_url) ? old_url->port : 0);
}
if ((flags & PHP_HTTP_URL_JOIN_PATH) && url_isset(old_url, path) && url_isset(new_url, path) && *new_url->path != '/') {
size_t old_path_len = strlen(old_url->path), new_path_len = strlen(new_url->path);
char *path = ecalloc(1, old_path_len + new_path_len + 1 + 1);
-
+
strcat(path, old_url->path);
if (path[old_path_len - 1] != '/') {
php_dirname(path, old_path_len);
strcat(path, "/");
}
strcat(path, new_url->path);
-
+
url(buf)->path = &buf.data[buf.used];
if (path[0] != '/') {
url_append(&buf, php_http_buffer_append(&buf, "/", 1));
if (!(flags & PHP_HTTP_URL_STRIP_QUERY)) {
if ((flags & PHP_HTTP_URL_JOIN_QUERY) && url_isset(new_url, query) && url_isset(old_url, query)) {
zval qarr, qstr;
-
+
array_init(&qarr);
-
+
ZVAL_STRING(&qstr, old_url->query);
php_http_querystring_update(&qarr, &qstr, NULL);
zval_ptr_dtor(&qstr);
ZVAL_STRING(&qstr, new_url->query);
php_http_querystring_update(&qarr, &qstr, NULL);
zval_ptr_dtor(&qstr);
-
+
ZVAL_NULL(&qstr);
php_http_querystring_update(&qarr, NULL, &qstr);
if (!(flags & PHP_HTTP_URL_STRIP_FRAGMENT)) {
url_copy(fragment);
}
-
+
/* done with copy & combine & strip */
if (flags & PHP_HTTP_URL_FROM_ENV) {
&& url(buf)->path
&& url(buf)->path[0] && url(buf)->path[1]) {
char *ptr, *end = url(buf)->path + strlen(url(buf)->path) + 1;
-
+
for (ptr = strchr(url(buf)->path, '/'); ptr; ptr = strchr(ptr, '/')) {
switch (ptr[1]) {
case '/':
memmove(&ptr[1], &ptr[2], end - &ptr[2]);
break;
-
+
case '.':
switch (ptr[2]) {
case '\0':
url(buf)->port = 0;
}
}
-
+
return url(buf);
}
return cpy;
}
-static size_t parse_mb_utf8(unsigned *wc, const char *ptr, const char *end)
+static inline size_t parse_mb_utf8(unsigned *wc, const char *ptr, const char *end)
{
unsigned wchar;
size_t consumed = utf8towc(&wchar, (const unsigned char *) ptr, end - ptr);
}
#if PHP_HTTP_HAVE_WCHAR
-static size_t parse_mb_loc(unsigned *wc, const char *ptr, const char *end)
+static inline size_t parse_mb_loc(unsigned *wc, const char *ptr, const char *end)
{
wchar_t wchar;
size_t consumed = 0;
static const char parse_xdigits[] = "0123456789ABCDEF";
-static size_t parse_mb(struct parse_state *state, parse_mb_what_t what, const char *ptr, const char *end, const char *begin, zend_bool force_silent)
+static inline size_t parse_mb(struct parse_state *state, parse_mb_what_t what, const char *ptr, const char *end, const char *begin, zend_bool force_silent)
{
unsigned wchar;
size_t consumed = 0;
if (what == PARSE_HOSTINFO && (state->flags & PHP_HTTP_URL_PARSE_TOIDN)) {
/* idna */
} else if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) {
+#if PHP_HTTP_HAVE_LIBICU
+ if (!u_isalnum(wchar)) {
+#else
if (!isualnum(wchar)) {
+#endif
break;
}
#if PHP_HTTP_HAVE_WCHAR
}
#endif
}
- PHP_HTTP_DUFF(consumed, state->buffer[state->offset++] = *ptr++);
+
+ memcpy(&state->buffer[state->offset], ptr, consumed);
+ state->offset += consumed;
} else {
- int i = 0;
-
- PHP_HTTP_DUFF(consumed,
- state->buffer[state->offset++] = '%';
- state->buffer[state->offset++] = parse_xdigits[((unsigned char) ptr[i]) >> 4];
- state->buffer[state->offset++] = parse_xdigits[((unsigned char) ptr[i]) & 0xf];
- ++i;
- );
+ size_t i;
+
+ for (i = 0; i < consumed; ++i) {
+ state->buffer[state->offset++] = '%';
+ state->buffer[state->offset++] = parse_xdigits[((unsigned char) ptr[i]) >> 4];
+ state->buffer[state->offset++] = parse_xdigits[((unsigned char) ptr[i]) & 0xf];
+ }
}
return consumed;
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_2003(struct parse_state *state)
+static ZEND_RESULT_CODE parse_uidn_2003(struct parse_state *state, size_t prev_len)
{
- char *host_ptr = state->url.host, ebuf[64] = {0}, *error = NULL;
- uint16_t *uhost_str, ahost_str[256], *ahost_ptr;
+ char ebuf[64] = {0}, *error = NULL;
+ uint16_t *uhost_str, ahost_str[256];
size_t uhost_len, ahost_len;
UErrorCode rc = U_ZERO_ERROR;
goto error;
}
- ahost_ptr = ahost_str;
- PHP_HTTP_DUFF(ahost_len, *host_ptr++ = *ahost_ptr++);
- *host_ptr = '\0';
- state->offset += host_ptr - state->url.host;
+ state->url.host[ahost_len] = '\0';
+ state->offset += ahost_len - prev_len;
+ while (ahost_len--) {
+ state->url.host[ahost_len] = ahost_str[ahost_len];
+ }
return SUCCESS;
#endif
#if PHP_HTTP_HAVE_LIBICU && HAVE_UIDNA_NAMETOASCII_UTF8
-static ZEND_RESULT_CODE parse_uidn_2008(struct parse_state *state)
+static ZEND_RESULT_CODE parse_uidn_2008(struct parse_state *state, size_t prev_len)
{
- char *host_ptr, *error = NULL, ebuf[64] = {0};
+ char *error = NULL, ebuf[64] = {0};
UErrorCode rc = U_ZERO_ERROR;
UIDNAInfo info = UIDNA_INFO_INITIALIZER;
UIDNA *uidna = uidna_openUTS46(UIDNA_ALLOW_UNASSIGNED, &rc);
return FAILURE;
}
- host_ptr = state->url.host;
-
if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) {
- char ahost_str[256], *ahost_ptr = &ahost_str[0];
- size_t ahost_len = uidna_nameToASCII_UTF8(uidna, host_ptr, -1, ahost_str, sizeof(ahost_str)-1, &info, &rc);
+ char ahost_str[256];
+ size_t ahost_len = uidna_nameToASCII_UTF8(uidna, state->url.host, -1, ahost_str, sizeof(ahost_str)-1, &info, &rc);
if (U_FAILURE(rc) || info.errors) {
goto error;
}
- PHP_HTTP_DUFF(ahost_len, *host_ptr++ = *ahost_ptr++);
+
+ memcpy(state->url.host, ahost_str, ahost_len);
+ state->url.host[ahost_len] = '\0';
+ state->offset += ahost_len - prev_len;
+
#if PHP_HTTP_HAVE_WCHAR
} else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) {
- uint16_t *uhost_str, whost_str[256], *whost_ptr = &whost_str[0];
+ uint16_t *uhost_str, whost_str[256];
size_t uhost_len, whost_len;
- if (SUCCESS != to_utf16(parse_mb_loc, host_ptr, &uhost_str, &uhost_len)) {
+ if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len)) {
error = "could not convert to UTF-16";
goto error;
}
whost_len = uidna_nameToASCII(uidna, uhost_str, uhost_len, whost_str, sizeof(whost_str)-1, &info, &rc);
- whost_ptr = whost_str;
efree(uhost_str);
+
if (U_FAILURE(rc) || info.errors) {
goto error;
}
- PHP_HTTP_DUFF(whost_len, *host_ptr++ = *whost_ptr++);
+
+ state->url.host[whost_len] = '\0';
+ state->offset += whost_len - prev_len;
+ while (whost_len--) {
+ state->url.host[whost_len] = whost_str[whost_len];
+ }
#endif
} else {
error = "codepage not specified";
goto error;
}
- *host_ptr = '\0';
- state->offset += host_ptr - state->url.host;
-
uidna_close(uidna);
return SUCCESS;
# if __GNUC__
__attribute__ ((unused))
# endif
-static ZEND_RESULT_CODE parse_kidn(struct parse_state *state)
+static ZEND_RESULT_CODE parse_kidn(struct parse_state *state, size_t prev_len)
{
idn_result_t rc;
#if PHP_HTTP_HAVE_LIBIDNKIT
#elif PHP_HTTP_HAVE_LIBIDNKIT2
int actions = IDN_MAP|IDN_ASCLOWER|IDN_RTCONV|IDN_PROHCHECK|IDN_NFCCHECK|IDN_PREFCHECK|IDN_COMBCHECK|IDN_CTXOLITECHECK|IDN_BIDICHECK|IDN_LOCALCHECK|IDN_IDNCONV|IDN_LENCHECK|IDN_RTCHECK;
#endif
- char ahost_str[256] = {0}, *ahost_ptr = &ahost_str[0], *host_ptr = state->url.host;
+ char ahost_str[256] = {0};
if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) {
#if PHP_HTTP_HAVE_LIBIDNKIT
rc = idn_encodename(actions, state->url.host, ahost_str, 256);
if (rc == idn_success) {
- PHP_HTTP_DUFF(strlen(ahost_str), *host_ptr++ = *ahost_ptr++);
+ size_t ahost_len = strlen(ahost_str);
- *host_ptr = '\0';
- state->offset += host_ptr - state->url.host;
+ memcpy(state->url.host, ahost_str, ahost_len + 1);
+ state->offset += ahost_len - prev_len;
return SUCCESS;
} else {
#endif
#if 0 && PHP_WIN32
-static ZEND_RESULT_CODE parse_widn_2003(struct parse_state *state)
+static ZEND_RESULT_CODE parse_widn_2003(struct parse_state *state, size_t prev_len)
{
char *host_ptr;
- uint16_t *uhost_str, ahost_str[256], *ahost_ptr;
- size_t uhost_len;
+ uint16_t *uhost_str, ahost_str[256];
+ size_t uhost_len, ahost_len;
if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) {
if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len)) {
}
efree(uhost_str);
- host_ptr = state->url.host;
- ahost_ptr = ahost_str;
- PHP_HTTP_DUFF(wcslen(ahost_str), *host_ptr++ = *ahost_ptr++);
-
- *host_ptr = '\0';
- state->offset += host_ptr - state->url.host;
+ ahost_len = wcslen(ahost_str);
+ state->url.host[ahost_len] = '\0';
+ state->offset += ahost_len - prev_len;
+ while (ahost_len--) {
+ state->url.host[ahost_len] = ahost_str[ahost_len];
+ }
return SUCCESS;
}
# endif
) {
#if PHP_HTTP_HAVE_LIBICU && HAVE_UIDNA_NAMETOASCII_UTF8
- return parse_uidn_2008(state);
+ return parse_uidn_2008(state, len);
#elif PHP_HTTP_HAVE_LIBIDN2
return parse_gidn_2008(state, len);
#elif PHP_HTTP_HAVE_LIBIDNKIT2
- return parse_kidn(state);
+ return parse_kidn(state, len);
#endif
}
#endif
#endif
) {
#if HAVE_UIDNA_IDNTOASCII
- return parse_uidn_2003(state);
+ return parse_uidn_2003(state, len);
#elif PHP_HTTP_HAVE_LIBIDN
return parse_gidn_2003(state, len);
#elif PHP_HTTP_HAVE_LIBIDNKIT
- return parse_kidn(state);
+ return parse_kidn(state, len);
#endif
}
#endif
#if 0 && PHP_WIN32
- return parse_widn_2003(state);
+ return parse_widn_2003(state, len);
#endif
#if PHP_HTTP_HAVE_LIBICU && HAVE_UIDNA_NAMETOASCII_UTF8
- return parse_uidn_2008(state);
+ return parse_uidn_2008(state, len);
#elif PHP_HTTP_HAVE_LIBIDN2
return parse_gidn_2008(state, len);
#elif PHP_HTTP_HAVE_LIBIDNKIT2
- return parse_kidn(state);
+ return parse_kidn(state, len);
#elif HAVE_UIDNA_IDNTOASCII
- return parse_uidn_2003(state);
+ return parse_uidn_2003(state, len);
#elif PHP_HTTP_HAVE_LIBIDN
return parse_gidn_2003(state, len);
#elif PHP_HTTP_HAVE_LIBIDNKIT
- return parse_kidn(state);
+ return parse_kidn(state, len);
#endif
return SUCCESS;
state->maxlen = maxlen;
if (!parse_scheme(state)) {
- php_error_docref(NULL, E_WARNING, "Failed to parse URL scheme: '%s'", state->ptr);
+ if (!(flags & PHP_HTTP_URL_SILENT_ERRORS)) {
+ php_error_docref(NULL, E_WARNING, "Failed to parse URL scheme: '%s'", state->ptr);
+ }
efree(state);
return NULL;
}
}
if (!parse_query(state)) {
- php_error_docref(NULL, E_WARNING, "Failed to parse URL query: '%s'", state->ptr);
+ if (!(flags & PHP_HTTP_URL_SILENT_ERRORS)) {
+ php_error_docref(NULL, E_WARNING, "Failed to parse URL query: '%s'", state->ptr);
+ }
efree(state);
return NULL;
}
if (!parse_fragment(state)) {
- php_error_docref(NULL, E_WARNING, "Failed to parse URL fragment: '%s'", state->ptr);
+ if (!(flags & PHP_HTTP_URL_SILENT_ERRORS)) {
+ php_error_docref(NULL, E_WARNING, "Failed to parse URL fragment: '%s'", state->ptr);
+ }
efree(state);
return NULL;
}
flags |= PHP_HTTP_URL_FROM_ENV;
}
- if (flags & PHP_HTTP_URL_SILENT_ERRORS) {
- zend_replace_error_handling(EH_SUPPRESS, NULL, &zeh);
- } else if (flags & PHP_HTTP_URL_IGNORE_ERRORS) {
+ if (flags & (PHP_HTTP_URL_SILENT_ERRORS|PHP_HTTP_URL_IGNORE_ERRORS)) {
zend_replace_error_handling(EH_NORMAL, NULL, &zeh);
} else {
zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_url_class_entry(), &zeh);
php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "z!|l", &new_url, &flags), invalid_arg, return);
- if (flags & PHP_HTTP_URL_SILENT_ERRORS) {
- zend_replace_error_handling(EH_SUPPRESS, NULL, &zeh);
- } else if (flags & PHP_HTTP_URL_IGNORE_ERRORS) {
+ if (flags & (PHP_HTTP_URL_SILENT_ERRORS|PHP_HTTP_URL_IGNORE_ERRORS)) {
zend_replace_error_handling(EH_NORMAL, NULL, &zeh);
} else {
zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_url_class_entry(), &zeh);
}
static zend_function_entry php_http_url_methods[] = {
- PHP_ME(HttpUrl, __construct, ai_HttpUrl___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(HttpUrl, __construct, ai_HttpUrl___construct, ZEND_ACC_PUBLIC)
PHP_ME(HttpUrl, mod, ai_HttpUrl_mod, ZEND_ACC_PUBLIC)
PHP_ME(HttpUrl, toString, ai_HttpUrl_toString, ZEND_ACC_PUBLIC)
ZEND_MALIAS(HttpUrl, __toString, toString, ai_HttpUrl_toString, ZEND_ACC_PUBLIC)
#ifndef PHP_HTTP_UTF8_H
#define PHP_HTTP_UTF8_H
-typedef struct utf8_range {
- unsigned int start;
- unsigned int end;
- unsigned char step;
-} utf8_range_t;
-
static const unsigned char utf8_mblen[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01
};
-static const utf8_range_t utf8_ranges[] = {
+typedef struct utf8_range {
+ const unsigned int start;
+ const unsigned int end;
+} utf8_range_t;
+
/* BEGIN::UTF8TABLE */
- { 0x0041, 0x005A, 1},
- { 0x0061, 0x007A, 1},
- { 0x00AA, 0, 0},
- { 0x00B5, 0, 0},
- { 0x00BA, 0, 0},
- { 0x00C0, 0x00D6, 1},
- { 0x00D8, 0x00F6, 1},
- { 0x00F8, 0x00FF, 1},
- { 0x0100, 0x017F, 1},
- { 0x0180, 0x024F, 1},
- { 0x0250, 0x02AF, 1},
- { 0x02B0, 0x02C1, 1},
- { 0x02C6, 0x02D1, 1},
- { 0x02E0, 0x02E4, 1},
- { 0x02EE, 0, 0},
- { 0x0345, 0, 0},
- { 0x0370, 0x0373, 1},
- { 0x0376, 0x0377, 1},
- { 0x037A, 0x037D, 1},
- { 0x0386, 0, 0},
- { 0x0388, 0x038A, 1},
- { 0x038C, 0, 0},
- { 0x038E, 0x03A1, 1},
- { 0x03A3, 0x03CE, 1},
- { 0x03D0, 0x03F5, 1},
- { 0x03F7, 0x03FF, 1},
- { 0x0400, 0x0481, 1},
- { 0x048A, 0x04FF, 1},
- { 0x0500, 0x0523, 1},
- { 0x0531, 0x0556, 1},
- { 0x0559, 0, 0},
- { 0x0561, 0x0587, 1},
- { 0x05D0, 0x05EA, 1},
- { 0x05F0, 0x05F2, 1},
- { 0x0621, 0x064A, 1},
- { 0x066E, 0x066F, 1},
- { 0x0671, 0x06D3, 1},
- { 0x06D5, 0, 0},
- { 0x06E5, 0x06E6, 1},
- { 0x06EE, 0x06EF, 1},
- { 0x06FA, 0x06FC, 1},
- { 0x06FF, 0, 0},
- { 0x0710, 0, 0},
- { 0x0712, 0x072F, 1},
- { 0x074D, 0x074F, 1},
- { 0x0750, 0x077F, 1},
- { 0x0780, 0x07A5, 1},
- { 0x07B1, 0, 0},
- { 0x07C0, 0x07EA, 1},
- { 0x07F4, 0x07F5, 1},
- { 0x07FA, 0, 0},
- { 0x0901, 0x0939, 1},
- { 0x093C, 0x094D, 1},
- { 0x0950, 0x0954, 1},
- { 0x0958, 0x0961, 1},
- { 0x0962, 0, 0},
- { 0x0963, 0, 0},
- { 0x0972, 0, 0},
- { 0x097B, 0x097F, 1},
- { 0x0981, 0x0983, 1},
- { 0x0985, 0x098C, 1},
- { 0x098F, 0, 0},
- { 0x0990, 0, 0},
- { 0x0993, 0x09A8, 1},
- { 0x09AA, 0x09B0, 1},
- { 0x09B2, 0, 0},
- { 0x09B6, 0x09B9, 1},
- { 0x09BC, 0x09C4, 1},
- { 0x09C7, 0, 0},
- { 0x09C8, 0, 0},
- { 0x09CB, 0x09CE, 1},
- { 0x09D7, 0, 0},
- { 0x09DC, 0, 0},
- { 0x09DD, 0, 0},
- { 0x09DF, 0x09E3, 1},
- { 0x09F0, 0x09FA, 1},
- { 0x0A01, 0x0A03, 1},
- { 0x0A05, 0x0A0A, 1},
- { 0x0A0F, 0, 0},
- { 0x0A10, 0, 0},
- { 0x0A13, 0x0A28, 1},
- { 0x0A2A, 0x0A30, 1},
- { 0x0A32, 0, 0},
- { 0x0A33, 0, 0},
- { 0x0A35, 0, 0},
- { 0x0A36, 0, 0},
- { 0x0A38, 0, 0},
- { 0x0A39, 0, 0},
- { 0x0A3C, 0, 0},
- { 0x0A3E, 0x0A42, 1},
- { 0x0A47, 0, 0},
- { 0x0A48, 0, 0},
- { 0x0A4B, 0x0A4D, 1},
- { 0x0A51, 0, 0},
- { 0x0A59, 0x0A5C, 1},
- { 0x0A5E, 0, 0},
- { 0x0A70, 0x0A75, 1},
- { 0x0A81, 0x0A83, 1},
- { 0x0A85, 0x0A8D, 1},
- { 0x0A8F, 0x0A91, 1},
- { 0x0A93, 0x0AA8, 1},
- { 0x0AAA, 0x0AB0, 1},
- { 0x0AB2, 0, 0},
- { 0x0AB3, 0, 0},
- { 0x0AB5, 0x0AB9, 1},
- { 0x0ABC, 0x0AC5, 1},
- { 0x0AC7, 0x0AC9, 1},
- { 0x0ACB, 0x0ACD, 1},
- { 0x0AD0, 0, 0},
- { 0x0AE0, 0x0AE3, 1},
- { 0x0AF1, 0, 0},
- { 0x0B01, 0x0B03, 1},
- { 0x0B05, 0x0B0C, 1},
- { 0x0B0F, 0, 0},
- { 0x0B10, 0, 0},
- { 0x0B13, 0x0B28, 1},
- { 0x0B2A, 0x0B30, 1},
- { 0x0B32, 0, 0},
- { 0x0B33, 0, 0},
- { 0x0B35, 0x0B39, 1},
- { 0x0B3C, 0x0B44, 1},
- { 0x0B47, 0x0B48, 1},
- { 0x0B4B, 0x0B4D, 1},
- { 0x0B56, 0x0B57, 1},
- { 0x0B5C, 0, 0},
- { 0x0B5D, 0, 0},
- { 0x0B5F, 0x0B63, 1},
- { 0x0B70, 0, 0},
- { 0x0B71, 0, 0},
- { 0x0B82, 0, 0},
- { 0x0B83, 0, 0},
- { 0x0B85, 0x0B8A, 1},
- { 0x0B8E, 0x0B90, 1},
- { 0x0B92, 0x0B95, 1},
- { 0x0B99, 0, 0},
- { 0x0B9A, 0, 0},
- { 0x0B9C, 0, 0},
- { 0x0B9E, 0, 0},
- { 0x0B9F, 0, 0},
- { 0x0BA3, 0, 0},
- { 0x0BA4, 0, 0},
- { 0x0BA8, 0x0BAA, 1},
- { 0x0BAE, 0x0BB9, 1},
- { 0x0BBE, 0x0BC2, 1},
- { 0x0BC6, 0x0BC8, 1},
- { 0x0BCA, 0x0BCD, 1},
- { 0x0BD0, 0, 0},
- { 0x0BD7, 0, 0},
- { 0x0BF0, 0x0BFA, 1},
- { 0x0C01, 0x0C03, 1},
- { 0x0C05, 0x0C0C, 1},
- { 0x0C0E, 0x0C10, 1},
- { 0x0C12, 0x0C28, 1},
- { 0x0C2A, 0x0C33, 1},
- { 0x0C35, 0x0C39, 1},
- { 0x0C3D, 0x0C44, 1},
- { 0x0C46, 0x0C48, 1},
- { 0x0C4A, 0x0C4D, 1},
- { 0x0C55, 0x0C56, 1},
- { 0x0C58, 0x0C59, 1},
- { 0x0C60, 0x0C63, 1},
- { 0x0C82, 0x0C83, 1},
- { 0x0C85, 0x0C8C, 1},
- { 0x0C8E, 0x0C90, 1},
- { 0x0C92, 0x0CA8, 1},
- { 0x0CAA, 0x0CB3, 1},
- { 0x0CB5, 0x0CB9, 1},
- { 0x0CBC, 0x0CC4, 1},
- { 0x0CC6, 0x0CC8, 1},
- { 0x0CCA, 0x0CCD, 1},
- { 0x0CD5, 0x0CD6, 1},
- { 0x0CDE, 0, 0},
- { 0x0CE0, 0x0CE3, 1},
- { 0x0CF1, 0, 0},
- { 0x0CF2, 0, 0},
- { 0x0D02, 0x0D03, 1},
- { 0x0D05, 0x0D0C, 1},
- { 0x0D0E, 0x0D10, 1},
- { 0x0D12, 0x0D28, 1},
- { 0x0D2A, 0x0D39, 1},
- { 0x0D3D, 0x0D44, 1},
- { 0x0D46, 0x0D48, 1},
- { 0x0D4A, 0x0D4D, 1},
- { 0x0D57, 0, 0},
- { 0x0D60, 0x0D63, 1},
- { 0x0D79, 0x0D7F, 1},
- { 0x0D82, 0x0D83, 1},
- { 0x0D85, 0x0D96, 1},
- { 0x0D9A, 0x0DB1, 1},
- { 0x0DB3, 0x0DBB, 1},
- { 0x0DBD, 0, 0},
- { 0x0DC0, 0x0DC6, 1},
- { 0x0DCA, 0, 0},
- { 0x0DCF, 0x0DD4, 1},
- { 0x0DD6, 0, 0},
- { 0x0DD8, 0x0DDF, 1},
- { 0x0DF2, 0x0DF4, 1},
- { 0x0E01, 0x0E2E, 1},
- { 0x0E30, 0x0E3A, 1},
- { 0x0E40, 0x0E45, 1},
- { 0x0E47, 0x0E4E, 1},
- { 0x0E81, 0x0E82, 1},
- { 0x0E84, 0, 0},
- { 0x0E87, 0x0E88, 1},
- { 0x0E8A, 0, 0},
- { 0x0E8D, 0, 0},
- { 0x0E94, 0x0E97, 1},
- { 0x0E99, 0x0E9F, 1},
- { 0x0EA1, 0x0EA3, 1},
- { 0x0EA5, 0, 0},
- { 0x0EA7, 0, 0},
- { 0x0EAA, 0x0EAB, 1},
- { 0x0EAD, 0x0EB0, 1},
- { 0x0EB2, 0x0EB3, 1},
- { 0x0EBD, 0, 0},
- { 0x0EC0, 0x0EC4, 1},
- { 0x0EC6, 0, 0},
- { 0x0EDC, 0x0EDD, 1},
- { 0x0F00, 0, 0},
- { 0x0F40, 0x0F47, 1},
- { 0x0F49, 0x0F6C, 1},
- { 0x0F88, 0x0F8B, 1},
- { 0x1000, 0x102A, 1},
- { 0x1050, 0x1055, 1},
- { 0x105A, 0x105D, 1},
- { 0x1061, 0, 0},
- { 0x0165, 0, 0},
- { 0x1066, 0, 0},
- { 0x106E, 0x1070, 1},
- { 0x1075, 0x1081, 1},
- { 0x108E, 0, 0},
- { 0x10A0, 0x10C5, 1},
- { 0x10D0, 0x10FA, 1},
- { 0x10FC, 0, 0},
- { 0x1100, 0x1159, 1},
- { 0x115F, 0x11A2, 1},
- { 0x11A8, 0x11F9, 1},
- { 0x1200, 0x1248, 1},
- { 0x124A, 0x124D, 1},
- { 0x1250, 0x1256, 1},
- { 0x1258, 0, 0},
- { 0x125A, 0x125D, 1},
- { 0x1260, 0x1288, 1},
- { 0x128A, 0x128D, 1},
- { 0x1290, 0x12B0, 1},
- { 0x12B2, 0x12B5, 1},
- { 0x12B8, 0x12BE, 1},
- { 0x12C0, 0, 0},
- { 0x12C2, 0x12C5, 1},
- { 0x12C8, 0x12D6, 1},
- { 0x12D8, 0x1310, 1},
- { 0x1312, 0x1315, 1},
- { 0x1318, 0x135A, 1},
- { 0x1380, 0x138F, 1},
- { 0x13A0, 0x13F4, 1},
- { 0x1401, 0x166C, 1},
- { 0x166F, 0x1676, 1},
- { 0x1681, 0x169A, 1},
- { 0x16A0, 0x16EA, 1},
- { 0x16EE, 0x16F0, 1},
- { 0x1700, 0x170C, 1},
- { 0x170E, 0x1711, 1},
- { 0x1720, 0x1731, 1},
- { 0x1740, 0x1751, 1},
- { 0x1760, 0x176C, 1},
- { 0x176E, 0x1770, 1},
- { 0x1780, 0x17B3, 1},
- { 0x17D7, 0, 0},
- { 0x17DC, 0, 0},
- { 0x1820, 0x1877, 1},
- { 0x1880, 0x18A8, 1},
- { 0x18AA, 0, 0},
- { 0x1900, 0x191C, 1},
- { 0x1946, 0x194F, 1},
- { 0x1950, 0x196D, 1},
- { 0x1970, 0x1974, 1},
- { 0x1980, 0x19A9, 1},
- { 0x19C1, 0x19C7, 1},
- { 0x19D0, 0x19D9, 1},
- { 0x1A00, 0x1A16, 1},
- { 0x1B05, 0x1B33, 1},
- { 0x1B45, 0x1B4B, 1},
- { 0x1B50, 0x1B59, 1},
- { 0x1B83, 0x1BA0, 1},
- { 0x1BAE, 0x1BAF, 1},
- { 0x1C00, 0x1C23, 1},
- { 0x1C4D, 0x1C4F, 1},
- { 0x1C5A, 0x1C7D, 1},
- { 0x1D00, 0x1DBF, 1},
- { 0x1E00, 0x1E9F, 1},
- { 0x1EA0, 0x1EFF, 1},
- { 0x1F00, 0x1F15, 1},
- { 0x1F18, 0x1F1D, 1},
- { 0x1F20, 0x1F45, 1},
- { 0x1F48, 0x1F4D, 1},
- { 0x1F50, 0x1F57, 1},
- { 0x1F59, 0, 0},
- { 0x1F5B, 0, 0},
- { 0x1F5D, 0, 0},
- { 0x1F5F, 0x1F7D, 1},
- { 0x1F80, 0x1FB4, 1},
- { 0x1FB6, 0x1FBC, 1},
- { 0x1FBE, 0, 0},
- { 0x1FC2, 0x1FC4, 1},
- { 0x1FC6, 0x1FCC, 1},
- { 0x1FD0, 0x1FD3, 1},
- { 0x1FD6, 0x1FDB, 1},
- { 0x1FE0, 0x1FEC, 1},
- { 0x1FF2, 0x1FF4, 1},
- { 0x1FF6, 0x1FFC, 1},
- { 0x2071, 0, 0},
- { 0x207F, 0, 0},
- { 0x2090, 0x2094, 1},
- { 0x2102, 0, 0},
- { 0x2107, 0, 0},
- { 0x210A, 0x2113, 1},
- { 0x2115, 0, 0},
- { 0x2119, 0x211D, 1},
- { 0x2124, 0, 0},
- { 0x2126, 0, 0},
- { 0x2128, 0x212D, 1},
- { 0x212F, 0x2139, 1},
- { 0x213C, 0x213F, 1},
- { 0x2145, 0x2149, 1},
- { 0x214E, 0, 0},
- { 0x2160, 0x2188, 1},
- { 0x249C, 0x24E9, 1},
- { 0x2C00, 0x2C2E, 1},
- { 0x2C30, 0x2C5E, 1},
- { 0x2C60, 0x2C6F, 1},
- { 0x2C71, 0x2C7D, 1},
- { 0x2C80, 0x2CE4, 1},
- { 0x2D00, 0x2D25, 1},
- { 0x2D30, 0x2D65, 1},
- { 0x2D6F, 0, 0},
- { 0x2D80, 0x2D96, 1},
- { 0x2DA0, 0x2DA6, 1},
- { 0x2DA8, 0x2DAE, 1},
- { 0x2DB0, 0x2DB6, 1},
- { 0x2DB8, 0x2DBE, 1},
- { 0x2DC0, 0x2DC6, 1},
- { 0x2DC8, 0x2DCE, 1},
- { 0x2DD0, 0x2DD6, 1},
- { 0x2DD8, 0x2DDE, 1},
- { 0x3005, 0x3007, 1},
- { 0x3021, 0x3029, 1},
- { 0x3031, 0x3035, 1},
- { 0x3038, 0x303C, 1},
- { 0x3041, 0x3096, 1},
- { 0x309D, 0x309F, 1},
- { 0x30A1, 0x30FA, 1},
- { 0x30FC, 0x30FF, 1},
- { 0x3105, 0x312D, 1},
- { 0x3131, 0x318E, 1},
- { 0x31A0, 0x31B7, 1},
- { 0x31F0, 0x31FF, 1},
- { 0x3400, 0x4DB5, 1},
- { 0x4E00, 0x9FBB, 1},
- { 0xA000, 0xA48C, 1},
- { 0xA500, 0xA60B, 1},
- { 0xA610, 0xA61F, 1},
- { 0xA62A, 0xA62B, 1},
- { 0xA640, 0xA65F, 1},
- { 0xA662, 0xA66E, 1},
- { 0xA680, 0xA697, 1},
- { 0xA717, 0xA71F, 1},
- { 0xA722, 0xA78C, 1},
- { 0xA7FB, 0xA7FF, 1},
- { 0xA800, 0, 0},
- { 0xA801, 0, 0},
- { 0xA803, 0xA805, 1},
- { 0xA807, 0xA80A, 1},
- { 0xA80C, 0xA822, 1},
- { 0xA840, 0xA873, 1},
- { 0xA882, 0xA8B3, 1},
- { 0xA90A, 0xA92D, 1},
- { 0xA930, 0xA946, 1},
- { 0xAA00, 0xAA28, 1},
- { 0xAA40, 0xAA42, 1},
- { 0xAA44, 0xAA4B, 1},
- { 0xAC00, 0xD7A3, 1},
- { 0xF900, 0xFA2D, 1},
- { 0xFA30, 0xFA6A, 1},
- { 0xFA70, 0xFAD9, 1},
- { 0xFB00, 0xFB06, 1},
- { 0xFB13, 0xFB17, 1},
- { 0xFB1D, 0, 0},
- { 0xFB1F, 0xFB28, 1},
- { 0xFB2A, 0xFB36, 1},
- { 0xFB38, 0xFB3C, 1},
- { 0xFB3E, 0, 0},
- { 0xFB40, 0, 0},
- { 0xFB41, 0, 0},
- { 0xFB43, 0, 0},
- { 0xFB44, 0, 0},
- { 0xFB46, 0xFB4F, 1},
- { 0xFB50, 0xFBB1, 1},
- { 0xFBD3, 0xFD3D, 1},
- { 0xFD50, 0xFD8F, 1},
- { 0xFD92, 0xFDC7, 1},
- { 0xFDF0, 0xFDFB, 1},
- { 0xFE70, 0xFE74, 1},
- { 0xFE76, 0xFEFC, 1},
- { 0xFF21, 0xFF3A, 1},
- { 0xFF41, 0xFF5A, 1},
- { 0xFF66, 0xFFBE, 1},
- { 0xFFC2, 0xFFC7, 1},
- { 0xFFCA, 0xFFCF, 1},
- { 0xFFD2, 0xFFD7, 1},
- { 0xFFDA, 0xFFDC, 1},
- {0x00010000, 0x0001000B, 1},
- {0x0001000D, 0x00010026, 1},
- {0x00010028, 0x0001003A, 1},
- {0x0001003C, 0x0001003D, 1},
- {0x0001003F, 0x0001004D, 1},
- {0x00010050, 0x0001005D, 1},
- {0x00010080, 0x000100FA, 1},
- {0x00010140, 0x00010174, 1},
- {0x00010280, 0x0001029C, 1},
- {0x000102A0, 0x000102D0, 1},
- {0x00010300, 0x0001031E, 1},
- {0x00010330, 0x0001034A, 1},
- {0x00010380, 0x0001039D, 1},
- {0x000103A0, 0x000103C3, 1},
- {0x000103C8, 0x000103CF, 1},
- {0x000103D1, 0x000103D5, 1},
- {0x00010400, 0x0001044F, 1},
- {0x00010450, 0x0001047F, 1},
- {0x00010480, 0x0001049D, 1},
- {0x000104A0, 0x000104A9, 1},
- {0x00010800, 0x00010805, 1},
- {0x00010808, 0, 0},
- {0x0001080A, 0x00010835, 1},
- {0x00010837, 0x00010838, 1},
- {0x0001083C, 0, 0},
- {0x0001083F, 0, 0},
- {0x00010900, 0x00010915, 1},
- {0x00010A00, 0, 0},
- {0x00010A10, 0x00010A13, 1},
- {0x00010A15, 0x00010A17, 1},
- {0x00010A19, 0x00010A33, 1},
- {0x00012000, 0x0001236E, 1},
- {0x00012400, 0x00012462, 1},
- {0x0001D400, 0x0001D454, 1},
- {0x0001D456, 0x0001D49C, 1},
- {0x0001D49E, 0x0001D49F, 1},
- {0x0001D4A2, 0, 0},
- {0x0001D4A5, 0x0001D4A6, 1},
- {0x0001D4A9, 0x0001D4AC, 1},
- {0x0001D4AE, 0x0001D4B9, 1},
- {0x0001D4BB, 0, 0},
- {0x0001D4BD, 0x0001D4C3, 1},
- {0x0001D4C5, 0x0001D505, 1},
- {0x0001D507, 0x0001D50A, 1},
- {0x0001D50D, 0x0001D514, 1},
- {0x0001D516, 0x0001D51C, 1},
- {0x0001D51E, 0x0001D539, 1},
- {0x0001D53B, 0x0001D53E, 1},
- {0x0001D540, 0x0001D544, 1},
- {0x0001D546, 0, 0},
- {0x0001D54A, 0x0001D550, 1},
- {0x0001D552, 0x0001D6A5, 1},
- {0x0001D6A8, 0x0001D6C0, 1},
- {0x0001D6C2, 0x0001D6DA, 1},
- {0x0001D6DC, 0x0001D6FA, 1},
- {0x0001D6FC, 0x0001D714, 1},
- {0x0001D716, 0x0001D734, 1},
- {0x0001D736, 0x0001D74E, 1},
- {0x0001D750, 0x0001D76E, 1},
- {0x0001D770, 0x0001D788, 1},
- {0x0001D78A, 0x0001D7A8, 1},
- {0x0001D7AA, 0x0001D7C2, 1},
- {0x0001D7C4, 0x0001D7CB, 1},
- {0x0001D7CE, 0x0001D7FF, 1},
- {0x00020000, 0x0002A6D6, 1},
- {0x0002F800, 0x0002FA1D, 1},
- { 0x0660, 0x0669, 1},
- { 0x06F0, 0x06F9, 1},
- { 0x0966, 0x096F, 1},
- { 0x09E6, 0x09EF, 1},
- { 0x0A66, 0x0A6F, 1},
- { 0x0AE6, 0x0AEF, 1},
- { 0x0B66, 0x0B6F, 1},
- { 0x0BE6, 0x0BEF, 1},
- { 0x0C66, 0x0C6F, 1},
- { 0x0C78, 0x0C7F, 1},
- { 0x0CE6, 0x0CEF, 1},
- { 0x0D66, 0x0D75, 1},
- { 0x0D70, 0x0D75, 1},
- { 0x0E50, 0x0E59, 1},
- { 0x0ED0, 0x0ED9, 1},
- { 0x0F20, 0x0F29, 1},
- { 0x1040, 0x1049, 1},
- { 0x17E0, 0x17E9, 1},
- { 0x1810, 0x1819, 1},
- { 0x1BB0, 0x1BB9, 1},
- { 0x1C40, 0x1C49, 1},
- { 0x1C50, 0x1C59, 1},
- { 0xA620, 0xA629, 1},
- { 0xA8D0, 0xA8D9, 1},
- { 0xA900, 0xA909, 1},
- { 0xAA50, 0xAA59, 1},
- { 0xFF10, 0xFF19, 1},
+static const utf8_range_t utf8_ranges[] = {
+ {0x00000041, 0x0000005A}, {0x00000061, 0x0000007A}, {0x000000C0, 0x000000D6},
+ {0x000000D8, 0x000000F6}, {0x000000F8, 0x000002C1}, {0x000002C6, 0x000002D1},
+ {0x000002E0, 0x000002E4}, {0x00000370, 0x00000374}, {0x00000376, 0x00000377},
+ {0x0000037A, 0x0000037D}, {0x00000388, 0x0000038A}, {0x0000038E, 0x000003A1},
+ {0x000003A3, 0x000003F5}, {0x000003F7, 0x00000481}, {0x0000048A, 0x0000052F},
+ {0x00000531, 0x00000556}, {0x00000561, 0x00000587}, {0x000005B0, 0x000005BD},
+ {0x000005C1, 0x000005C2}, {0x000005C4, 0x000005C5}, {0x000005D0, 0x000005EA},
+ {0x000005F0, 0x000005F2}, {0x00000610, 0x0000061A}, {0x00000620, 0x00000657},
+ {0x00000659, 0x00000669}, {0x0000066E, 0x000006D3}, {0x000006D5, 0x000006DC},
+ {0x000006E1, 0x000006E8}, {0x000006ED, 0x000006FC}, {0x00000710, 0x0000073F},
+ {0x0000074D, 0x000007B1}, {0x000007C0, 0x000007EA}, {0x000007F4, 0x000007F5},
+ {0x00000800, 0x00000817}, {0x0000081A, 0x0000082C}, {0x00000840, 0x00000858},
+ {0x00000860, 0x0000086A}, {0x000008A0, 0x000008B4}, {0x000008B6, 0x000008BD},
+ {0x000008D4, 0x000008DF}, {0x000008E3, 0x000008E9}, {0x000008F0, 0x0000093B},
+ {0x0000093D, 0x0000094C}, {0x0000094E, 0x00000950}, {0x00000955, 0x00000963},
+ {0x00000966, 0x0000096F}, {0x00000971, 0x00000983}, {0x00000985, 0x0000098C},
+ {0x0000098F, 0x00000990}, {0x00000993, 0x000009A8}, {0x000009AA, 0x000009B0},
+ {0x000009B6, 0x000009B9}, {0x000009BD, 0x000009C4}, {0x000009C7, 0x000009C8},
+ {0x000009CB, 0x000009CC}, {0x000009DC, 0x000009DD}, {0x000009DF, 0x000009E3},
+ {0x000009E6, 0x000009F1}, {0x00000A01, 0x00000A03}, {0x00000A05, 0x00000A0A},
+ {0x00000A0F, 0x00000A10}, {0x00000A13, 0x00000A28}, {0x00000A2A, 0x00000A30},
+ {0x00000A32, 0x00000A33}, {0x00000A35, 0x00000A36}, {0x00000A38, 0x00000A39},
+ {0x00000A3E, 0x00000A42}, {0x00000A47, 0x00000A48}, {0x00000A4B, 0x00000A4C},
+ {0x00000A59, 0x00000A5C}, {0x00000A66, 0x00000A75}, {0x00000A81, 0x00000A83},
+ {0x00000A85, 0x00000A8D}, {0x00000A8F, 0x00000A91}, {0x00000A93, 0x00000AA8},
+ {0x00000AAA, 0x00000AB0}, {0x00000AB2, 0x00000AB3}, {0x00000AB5, 0x00000AB9},
+ {0x00000ABD, 0x00000AC5}, {0x00000AC7, 0x00000AC9}, {0x00000ACB, 0x00000ACC},
+ {0x00000AE0, 0x00000AE3}, {0x00000AE6, 0x00000AEF}, {0x00000AF9, 0x00000AFC},
+ {0x00000B01, 0x00000B03}, {0x00000B05, 0x00000B0C}, {0x00000B0F, 0x00000B10},
+ {0x00000B13, 0x00000B28}, {0x00000B2A, 0x00000B30}, {0x00000B32, 0x00000B33},
+ {0x00000B35, 0x00000B39}, {0x00000B3D, 0x00000B44}, {0x00000B47, 0x00000B48},
+ {0x00000B4B, 0x00000B4C}, {0x00000B56, 0x00000B57}, {0x00000B5C, 0x00000B5D},
+ {0x00000B5F, 0x00000B63}, {0x00000B66, 0x00000B6F}, {0x00000B82, 0x00000B83},
+ {0x00000B85, 0x00000B8A}, {0x00000B8E, 0x00000B90}, {0x00000B92, 0x00000B95},
+ {0x00000B99, 0x00000B9A}, {0x00000B9E, 0x00000B9F}, {0x00000BA3, 0x00000BA4},
+ {0x00000BA8, 0x00000BAA}, {0x00000BAE, 0x00000BB9}, {0x00000BBE, 0x00000BC2},
+ {0x00000BC6, 0x00000BC8}, {0x00000BCA, 0x00000BCC}, {0x00000BE6, 0x00000BEF},
+ {0x00000C00, 0x00000C03}, {0x00000C05, 0x00000C0C}, {0x00000C0E, 0x00000C10},
+ {0x00000C12, 0x00000C28}, {0x00000C2A, 0x00000C39}, {0x00000C3D, 0x00000C44},
+ {0x00000C46, 0x00000C48}, {0x00000C4A, 0x00000C4C}, {0x00000C55, 0x00000C56},
+ {0x00000C58, 0x00000C5A}, {0x00000C60, 0x00000C63}, {0x00000C66, 0x00000C6F},
+ {0x00000C80, 0x00000C83}, {0x00000C85, 0x00000C8C}, {0x00000C8E, 0x00000C90},
+ {0x00000C92, 0x00000CA8}, {0x00000CAA, 0x00000CB3}, {0x00000CB5, 0x00000CB9},
+ {0x00000CBD, 0x00000CC4}, {0x00000CC6, 0x00000CC8}, {0x00000CCA, 0x00000CCC},
+ {0x00000CD5, 0x00000CD6}, {0x00000CE0, 0x00000CE3}, {0x00000CE6, 0x00000CEF},
+ {0x00000CF1, 0x00000CF2}, {0x00000D00, 0x00000D03}, {0x00000D05, 0x00000D0C},
+ {0x00000D0E, 0x00000D10}, {0x00000D12, 0x00000D3A}, {0x00000D3D, 0x00000D44},
+ {0x00000D46, 0x00000D48}, {0x00000D4A, 0x00000D4C}, {0x00000D54, 0x00000D57},
+ {0x00000D5F, 0x00000D63}, {0x00000D66, 0x00000D6F}, {0x00000D7A, 0x00000D7F},
+ {0x00000D82, 0x00000D83}, {0x00000D85, 0x00000D96}, {0x00000D9A, 0x00000DB1},
+ {0x00000DB3, 0x00000DBB}, {0x00000DC0, 0x00000DC6}, {0x00000DCF, 0x00000DD4},
+ {0x00000DD8, 0x00000DDF}, {0x00000DE6, 0x00000DEF}, {0x00000DF2, 0x00000DF3},
+ {0x00000E01, 0x00000E3A}, {0x00000E40, 0x00000E46}, {0x00000E50, 0x00000E59},
+ {0x00000E81, 0x00000E82}, {0x00000E87, 0x00000E88}, {0x00000E94, 0x00000E97},
+ {0x00000E99, 0x00000E9F}, {0x00000EA1, 0x00000EA3}, {0x00000EAA, 0x00000EAB},
+ {0x00000EAD, 0x00000EB9}, {0x00000EBB, 0x00000EBD}, {0x00000EC0, 0x00000EC4},
+ {0x00000ED0, 0x00000ED9}, {0x00000EDC, 0x00000EDF}, {0x00000F20, 0x00000F29},
+ {0x00000F40, 0x00000F47}, {0x00000F49, 0x00000F6C}, {0x00000F71, 0x00000F81},
+ {0x00000F88, 0x00000F97}, {0x00000F99, 0x00000FBC}, {0x00001000, 0x00001036},
+ {0x0000103B, 0x00001049}, {0x00001050, 0x00001062}, {0x00001065, 0x00001068},
+ {0x0000106E, 0x00001086}, {0x00001090, 0x00001099}, {0x0000109C, 0x0000109D},
+ {0x000010A0, 0x000010C5}, {0x000010D0, 0x000010FA}, {0x000010FC, 0x00001248},
+ {0x0000124A, 0x0000124D}, {0x00001250, 0x00001256}, {0x0000125A, 0x0000125D},
+ {0x00001260, 0x00001288}, {0x0000128A, 0x0000128D}, {0x00001290, 0x000012B0},
+ {0x000012B2, 0x000012B5}, {0x000012B8, 0x000012BE}, {0x000012C2, 0x000012C5},
+ {0x000012C8, 0x000012D6}, {0x000012D8, 0x00001310}, {0x00001312, 0x00001315},
+ {0x00001318, 0x0000135A}, {0x00001380, 0x0000138F}, {0x000013A0, 0x000013F5},
+ {0x000013F8, 0x000013FD}, {0x00001401, 0x0000166C}, {0x0000166F, 0x0000167F},
+ {0x00001681, 0x0000169A}, {0x000016A0, 0x000016EA}, {0x000016EE, 0x000016F8},
+ {0x00001700, 0x0000170C}, {0x0000170E, 0x00001713}, {0x00001720, 0x00001733},
+ {0x00001740, 0x00001753}, {0x00001760, 0x0000176C}, {0x0000176E, 0x00001770},
+ {0x00001772, 0x00001773}, {0x00001780, 0x000017B3}, {0x000017B6, 0x000017C8},
+ {0x000017E0, 0x000017E9}, {0x00001810, 0x00001819}, {0x00001820, 0x00001877},
+ {0x00001880, 0x000018AA}, {0x000018B0, 0x000018F5}, {0x00001900, 0x0000191E},
+ {0x00001920, 0x0000192B}, {0x00001930, 0x00001938}, {0x00001946, 0x0000196D},
+ {0x00001970, 0x00001974}, {0x00001980, 0x000019AB}, {0x000019B0, 0x000019C9},
+ {0x000019D0, 0x000019D9}, {0x00001A00, 0x00001A1B}, {0x00001A20, 0x00001A5E},
+ {0x00001A61, 0x00001A74}, {0x00001A80, 0x00001A89}, {0x00001A90, 0x00001A99},
+ {0x00001B00, 0x00001B33}, {0x00001B35, 0x00001B43}, {0x00001B45, 0x00001B4B},
+ {0x00001B50, 0x00001B59}, {0x00001B80, 0x00001BA9}, {0x00001BAC, 0x00001BE5},
+ {0x00001BE7, 0x00001BF1}, {0x00001C00, 0x00001C35}, {0x00001C40, 0x00001C49},
+ {0x00001C4D, 0x00001C7D}, {0x00001C80, 0x00001C88}, {0x00001CE9, 0x00001CEC},
+ {0x00001CEE, 0x00001CF3}, {0x00001CF5, 0x00001CF6}, {0x00001D00, 0x00001DBF},
+ {0x00001DE7, 0x00001DF4}, {0x00001E00, 0x00001F15}, {0x00001F18, 0x00001F1D},
+ {0x00001F20, 0x00001F45}, {0x00001F48, 0x00001F4D}, {0x00001F50, 0x00001F57},
+ {0x00001F5F, 0x00001F7D}, {0x00001F80, 0x00001FB4}, {0x00001FB6, 0x00001FBC},
+ {0x00001FC2, 0x00001FC4}, {0x00001FC6, 0x00001FCC}, {0x00001FD0, 0x00001FD3},
+ {0x00001FD6, 0x00001FDB}, {0x00001FE0, 0x00001FEC}, {0x00001FF2, 0x00001FF4},
+ {0x00001FF6, 0x00001FFC}, {0x00002090, 0x0000209C}, {0x0000210A, 0x00002113},
+ {0x00002119, 0x0000211D}, {0x0000212A, 0x0000212D}, {0x0000212F, 0x00002139},
+ {0x0000213C, 0x0000213F}, {0x00002145, 0x00002149}, {0x00002160, 0x00002188},
+ {0x000024B6, 0x000024E9}, {0x00002C00, 0x00002C2E}, {0x00002C30, 0x00002C5E},
+ {0x00002C60, 0x00002CE4}, {0x00002CEB, 0x00002CEE}, {0x00002CF2, 0x00002CF3},
+ {0x00002D00, 0x00002D25}, {0x00002D30, 0x00002D67}, {0x00002D80, 0x00002D96},
+ {0x00002DA0, 0x00002DA6}, {0x00002DA8, 0x00002DAE}, {0x00002DB0, 0x00002DB6},
+ {0x00002DB8, 0x00002DBE}, {0x00002DC0, 0x00002DC6}, {0x00002DC8, 0x00002DCE},
+ {0x00002DD0, 0x00002DD6}, {0x00002DD8, 0x00002DDE}, {0x00002DE0, 0x00002DFF},
+ {0x00003005, 0x00003007}, {0x00003021, 0x00003029}, {0x00003031, 0x00003035},
+ {0x00003038, 0x0000303C}, {0x00003041, 0x00003096}, {0x0000309D, 0x0000309F},
+ {0x000030A1, 0x000030FA}, {0x000030FC, 0x000030FF}, {0x00003105, 0x0000312E},
+ {0x00003131, 0x0000318E}, {0x000031A0, 0x000031BA}, {0x000031F0, 0x000031FF},
+ {0x00003400, 0x00004DB5}, {0x00004E00, 0x00009FEA}, {0x0000A000, 0x0000A48C},
+ {0x0000A4D0, 0x0000A4FD}, {0x0000A500, 0x0000A60C}, {0x0000A610, 0x0000A62B},
+ {0x0000A640, 0x0000A66E}, {0x0000A674, 0x0000A67B}, {0x0000A67F, 0x0000A6EF},
+ {0x0000A717, 0x0000A71F}, {0x0000A722, 0x0000A788}, {0x0000A78B, 0x0000A7AE},
+ {0x0000A7B0, 0x0000A7B7}, {0x0000A7F7, 0x0000A801}, {0x0000A803, 0x0000A805},
+ {0x0000A807, 0x0000A80A}, {0x0000A80C, 0x0000A827}, {0x0000A840, 0x0000A873},
+ {0x0000A880, 0x0000A8C3}, {0x0000A8D0, 0x0000A8D9}, {0x0000A8F2, 0x0000A8F7},
+ {0x0000A900, 0x0000A92A}, {0x0000A930, 0x0000A952}, {0x0000A960, 0x0000A97C},
+ {0x0000A980, 0x0000A9B2}, {0x0000A9B4, 0x0000A9BF}, {0x0000A9CF, 0x0000A9D9},
+ {0x0000A9E0, 0x0000A9E4}, {0x0000A9E6, 0x0000A9FE}, {0x0000AA00, 0x0000AA36},
+ {0x0000AA40, 0x0000AA4D}, {0x0000AA50, 0x0000AA59}, {0x0000AA60, 0x0000AA76},
+ {0x0000AA7E, 0x0000AABE}, {0x0000AADB, 0x0000AADD}, {0x0000AAE0, 0x0000AAEF},
+ {0x0000AAF2, 0x0000AAF5}, {0x0000AB01, 0x0000AB06}, {0x0000AB09, 0x0000AB0E},
+ {0x0000AB11, 0x0000AB16}, {0x0000AB20, 0x0000AB26}, {0x0000AB28, 0x0000AB2E},
+ {0x0000AB30, 0x0000AB5A}, {0x0000AB5C, 0x0000AB65}, {0x0000AB70, 0x0000ABEA},
+ {0x0000ABF0, 0x0000ABF9}, {0x0000AC00, 0x0000D7A3}, {0x0000D7B0, 0x0000D7C6},
+ {0x0000D7CB, 0x0000D7FB}, {0x0000F900, 0x0000FA6D}, {0x0000FA70, 0x0000FAD9},
+ {0x0000FB00, 0x0000FB06}, {0x0000FB13, 0x0000FB17}, {0x0000FB1D, 0x0000FB28},
+ {0x0000FB2A, 0x0000FB36}, {0x0000FB38, 0x0000FB3C}, {0x0000FB40, 0x0000FB41},
+ {0x0000FB43, 0x0000FB44}, {0x0000FB46, 0x0000FBB1}, {0x0000FBD3, 0x0000FD3D},
+ {0x0000FD50, 0x0000FD8F}, {0x0000FD92, 0x0000FDC7}, {0x0000FDF0, 0x0000FDFB},
+ {0x0000FE70, 0x0000FE74}, {0x0000FE76, 0x0000FEFC}, {0x0000FF10, 0x0000FF19},
+ {0x0000FF21, 0x0000FF3A}, {0x0000FF41, 0x0000FF5A}, {0x0000FF66, 0x0000FFBE},
+ {0x0000FFC2, 0x0000FFC7}, {0x0000FFCA, 0x0000FFCF}, {0x0000FFD2, 0x0000FFD7},
+ {0x0000FFDA, 0x0000FFDC}, {0x00010000, 0x0001000B}, {0x0001000D, 0x00010026},
+ {0x00010028, 0x0001003A}, {0x0001003C, 0x0001003D}, {0x0001003F, 0x0001004D},
+ {0x00010050, 0x0001005D}, {0x00010080, 0x000100FA}, {0x00010140, 0x00010174},
+ {0x00010280, 0x0001029C}, {0x000102A0, 0x000102D0}, {0x00010300, 0x0001031F},
+ {0x0001032D, 0x0001034A}, {0x00010350, 0x0001037A}, {0x00010380, 0x0001039D},
+ {0x000103A0, 0x000103C3}, {0x000103C8, 0x000103CF}, {0x000103D1, 0x000103D5},
+ {0x00010400, 0x0001049D}, {0x000104A0, 0x000104A9}, {0x000104B0, 0x000104D3},
+ {0x000104D8, 0x000104FB}, {0x00010500, 0x00010527}, {0x00010530, 0x00010563},
+ {0x00010600, 0x00010736}, {0x00010740, 0x00010755}, {0x00010760, 0x00010767},
+ {0x00010800, 0x00010805}, {0x0001080A, 0x00010835}, {0x00010837, 0x00010838},
+ {0x0001083F, 0x00010855}, {0x00010860, 0x00010876}, {0x00010880, 0x0001089E},
+ {0x000108E0, 0x000108F2}, {0x000108F4, 0x000108F5}, {0x00010900, 0x00010915},
+ {0x00010920, 0x00010939}, {0x00010980, 0x000109B7}, {0x000109BE, 0x000109BF},
+ {0x00010A00, 0x00010A03}, {0x00010A05, 0x00010A06}, {0x00010A0C, 0x00010A13},
+ {0x00010A15, 0x00010A17}, {0x00010A19, 0x00010A33}, {0x00010A60, 0x00010A7C},
+ {0x00010A80, 0x00010A9C}, {0x00010AC0, 0x00010AC7}, {0x00010AC9, 0x00010AE4},
+ {0x00010B00, 0x00010B35}, {0x00010B40, 0x00010B55}, {0x00010B60, 0x00010B72},
+ {0x00010B80, 0x00010B91}, {0x00010C00, 0x00010C48}, {0x00010C80, 0x00010CB2},
+ {0x00010CC0, 0x00010CF2}, {0x00011000, 0x00011045}, {0x00011066, 0x0001106F},
+ {0x00011082, 0x000110B8}, {0x000110D0, 0x000110E8}, {0x000110F0, 0x000110F9},
+ {0x00011100, 0x00011132}, {0x00011136, 0x0001113F}, {0x00011150, 0x00011172},
+ {0x00011180, 0x000111BF}, {0x000111C1, 0x000111C4}, {0x000111D0, 0x000111DA},
+ {0x00011200, 0x00011211}, {0x00011213, 0x00011234}, {0x00011280, 0x00011286},
+ {0x0001128A, 0x0001128D}, {0x0001128F, 0x0001129D}, {0x0001129F, 0x000112A8},
+ {0x000112B0, 0x000112E8}, {0x000112F0, 0x000112F9}, {0x00011300, 0x00011303},
+ {0x00011305, 0x0001130C}, {0x0001130F, 0x00011310}, {0x00011313, 0x00011328},
+ {0x0001132A, 0x00011330}, {0x00011332, 0x00011333}, {0x00011335, 0x00011339},
+ {0x0001133D, 0x00011344}, {0x00011347, 0x00011348}, {0x0001134B, 0x0001134C},
+ {0x0001135D, 0x00011363}, {0x00011400, 0x00011441}, {0x00011443, 0x00011445},
+ {0x00011447, 0x0001144A}, {0x00011450, 0x00011459}, {0x00011480, 0x000114C1},
+ {0x000114C4, 0x000114C5}, {0x000114D0, 0x000114D9}, {0x00011580, 0x000115B5},
+ {0x000115B8, 0x000115BE}, {0x000115D8, 0x000115DD}, {0x00011600, 0x0001163E},
+ {0x00011650, 0x00011659}, {0x00011680, 0x000116B5}, {0x000116C0, 0x000116C9},
+ {0x00011700, 0x00011719}, {0x0001171D, 0x0001172A}, {0x00011730, 0x00011739},
+ {0x000118A0, 0x000118E9}, {0x00011A00, 0x00011A32}, {0x00011A35, 0x00011A3E},
+ {0x00011A50, 0x00011A83}, {0x00011A86, 0x00011A97}, {0x00011AC0, 0x00011AF8},
+ {0x00011C00, 0x00011C08}, {0x00011C0A, 0x00011C36}, {0x00011C38, 0x00011C3E},
+ {0x00011C50, 0x00011C59}, {0x00011C72, 0x00011C8F}, {0x00011C92, 0x00011CA7},
+ {0x00011CA9, 0x00011CB6}, {0x00011D00, 0x00011D06}, {0x00011D08, 0x00011D09},
+ {0x00011D0B, 0x00011D36}, {0x00011D3C, 0x00011D3D}, {0x00011D3F, 0x00011D41},
+ {0x00011D46, 0x00011D47}, {0x00011D50, 0x00011D59}, {0x00012000, 0x00012399},
+ {0x00012400, 0x0001246E}, {0x00012480, 0x00012543}, {0x00013000, 0x0001342E},
+ {0x00014400, 0x00014646}, {0x00016800, 0x00016A38}, {0x00016A40, 0x00016A5E},
+ {0x00016A60, 0x00016A69}, {0x00016AD0, 0x00016AED}, {0x00016B00, 0x00016B36},
+ {0x00016B40, 0x00016B43}, {0x00016B50, 0x00016B59}, {0x00016B63, 0x00016B77},
+ {0x00016B7D, 0x00016B8F}, {0x00016F00, 0x00016F44}, {0x00016F50, 0x00016F7E},
+ {0x00016F93, 0x00016F9F}, {0x00016FE0, 0x00016FE1}, {0x00017000, 0x000187EC},
+ {0x00018800, 0x00018AF2}, {0x0001B000, 0x0001B11E}, {0x0001B170, 0x0001B2FB},
+ {0x0001BC00, 0x0001BC6A}, {0x0001BC70, 0x0001BC7C}, {0x0001BC80, 0x0001BC88},
+ {0x0001BC90, 0x0001BC99}, {0x0001D400, 0x0001D454}, {0x0001D456, 0x0001D49C},
+ {0x0001D49E, 0x0001D49F}, {0x0001D4A5, 0x0001D4A6}, {0x0001D4A9, 0x0001D4AC},
+ {0x0001D4AE, 0x0001D4B9}, {0x0001D4BD, 0x0001D4C3}, {0x0001D4C5, 0x0001D505},
+ {0x0001D507, 0x0001D50A}, {0x0001D50D, 0x0001D514}, {0x0001D516, 0x0001D51C},
+ {0x0001D51E, 0x0001D539}, {0x0001D53B, 0x0001D53E}, {0x0001D540, 0x0001D544},
+ {0x0001D54A, 0x0001D550}, {0x0001D552, 0x0001D6A5}, {0x0001D6A8, 0x0001D6C0},
+ {0x0001D6C2, 0x0001D6DA}, {0x0001D6DC, 0x0001D6FA}, {0x0001D6FC, 0x0001D714},
+ {0x0001D716, 0x0001D734}, {0x0001D736, 0x0001D74E}, {0x0001D750, 0x0001D76E},
+ {0x0001D770, 0x0001D788}, {0x0001D78A, 0x0001D7A8}, {0x0001D7AA, 0x0001D7C2},
+ {0x0001D7C4, 0x0001D7CB}, {0x0001D7CE, 0x0001D7FF}, {0x0001E000, 0x0001E006},
+ {0x0001E008, 0x0001E018}, {0x0001E01B, 0x0001E021}, {0x0001E023, 0x0001E024},
+ {0x0001E026, 0x0001E02A}, {0x0001E800, 0x0001E8C4}, {0x0001E900, 0x0001E943},
+ {0x0001E950, 0x0001E959}, {0x0001EE00, 0x0001EE03}, {0x0001EE05, 0x0001EE1F},
+ {0x0001EE21, 0x0001EE22}, {0x0001EE29, 0x0001EE32}, {0x0001EE34, 0x0001EE37},
+ {0x0001EE4D, 0x0001EE4F}, {0x0001EE51, 0x0001EE52}, {0x0001EE61, 0x0001EE62},
+ {0x0001EE67, 0x0001EE6A}, {0x0001EE6C, 0x0001EE72}, {0x0001EE74, 0x0001EE77},
+ {0x0001EE79, 0x0001EE7C}, {0x0001EE80, 0x0001EE89}, {0x0001EE8B, 0x0001EE9B},
+ {0x0001EEA1, 0x0001EEA3}, {0x0001EEA5, 0x0001EEA9}, {0x0001EEAB, 0x0001EEBB},
+ {0x0001F130, 0x0001F149}, {0x0001F150, 0x0001F169}, {0x0001F170, 0x0001F189},
+ {0x00020000, 0x0002A6D6}, {0x0002A700, 0x0002B734}, {0x0002B740, 0x0002B81D},
+ {0x0002B820, 0x0002CEA1}, {0x0002CEB0, 0x0002EBE0}, {0x0002F800, 0x0002FA1D}
+};
-/* END::UTF8TABLE */
+static const unsigned utf8_chars[] = {
+ 0x000000AA, 0x000000B5, 0x000000BA, 0x000002EC, 0x000002EE, 0x00000345,
+ 0x0000037F, 0x00000386, 0x0000038C, 0x00000559, 0x000005BF, 0x000005C7,
+ 0x000006FF, 0x000007FA, 0x000009B2, 0x000009CE, 0x000009D7, 0x000009FC,
+ 0x00000A51, 0x00000A5E, 0x00000AD0, 0x00000B71, 0x00000B9C, 0x00000BD0,
+ 0x00000BD7, 0x00000CDE, 0x00000D4E, 0x00000DBD, 0x00000DD6, 0x00000E4D,
+ 0x00000E84, 0x00000E8A, 0x00000E8D, 0x00000EA5, 0x00000EA7, 0x00000EC6,
+ 0x00000ECD, 0x00000F00, 0x00001038, 0x0000108E, 0x000010C7, 0x000010CD,
+ 0x00001258, 0x000012C0, 0x0000135F, 0x000017D7, 0x000017DC, 0x00001AA7,
+ 0x00001F59, 0x00001F5B, 0x00001F5D, 0x00001FBE, 0x00002071, 0x0000207F,
+ 0x00002102, 0x00002107, 0x00002115, 0x00002124, 0x00002126, 0x00002128,
+ 0x0000214E, 0x00002D27, 0x00002D2D, 0x00002D6F, 0x00002E2F, 0x0000A8C5,
+ 0x0000A8FB, 0x0000A8FD, 0x0000AA7A, 0x0000AAC0, 0x0000AAC2, 0x0000FB3E,
+ 0x00010808, 0x0001083C, 0x00011176, 0x000111DC, 0x00011237, 0x0001123E,
+ 0x00011288, 0x00011350, 0x00011357, 0x000114C7, 0x00011640, 0x00011644,
+ 0x000118FF, 0x00011C40, 0x00011D3A, 0x00011D43, 0x0001BC9E, 0x0001D4A2,
+ 0x0001D4BB, 0x0001D546, 0x0001E947, 0x0001EE24, 0x0001EE27, 0x0001EE39,
+ 0x0001EE3B, 0x0001EE42, 0x0001EE47, 0x0001EE49, 0x0001EE4B, 0x0001EE54,
+ 0x0001EE57, 0x0001EE59, 0x0001EE5B, 0x0001EE5D, 0x0001EE5F, 0x0001EE64,
+ 0x0001EE7E
};
+/* END::UTF8TABLE */
+
static inline size_t utf8towc(unsigned *wc, const unsigned char *uc, size_t len)
{
unsigned char ub = utf8_mblen[*uc];
static inline zend_bool isualpha(unsigned ch)
{
- unsigned i = 0, j;
+ unsigned hi = sizeof(utf8_ranges)/sizeof(utf8_ranges[0])-1,
+ cur = hi/2, lo = 0, prev;
+
+#undef u
+#define u (utf8_ranges[cur])
- PHP_HTTP_DUFF(sizeof(utf8_ranges)/sizeof(utf8_range_t),
- if (utf8_ranges[i].start == ch) {
+ do {
+#if 0
+ fprintf(stderr, "=> cur=%u lo=%u hi=%u (%u in %u-%u)\n", cur, lo, hi, ch, u.start, u.end);
+#endif
+ if (u.start <= ch && u.end >= ch) {
return 1;
- } else if (utf8_ranges[i].start <= ch && utf8_ranges[i].end >= ch) {
- if (utf8_ranges[i].step == 1) {
- return 1;
- }
- for (j = utf8_ranges[i].start; j <= utf8_ranges[i].end; j+= utf8_ranges[i].step) {
- if (ch == j) {
- return 1;
- }
- }
- return 0;
}
- ++i;
- );
+
+ prev = cur;
+
+ if (u.start > ch) {
+ hi = cur;
+ cur -= (cur - lo) / 2;
+ } else if ((u.end && u.end < ch) || (!u.end && u.start < ch)) {
+ lo = cur;
+ cur += (hi - cur) / 2;
+ } else {
+ break;
+ }
+
+ } while (cur != prev);
+
+#undef u
+#define u (utf8_chars[cur])
+
+ hi = sizeof(utf8_chars)/sizeof(utf8_chars[0]);
+ cur = hi/2;
+ lo = 0;
+
+ do {
+#if 0
+ fprintf(stderr, "=> cur=%u lo=%u hi=%u (%u is %u)\n", cur, lo, hi, ch, u);
+#endif
+ if (u == ch) {
+ return 1;
+ }
+
+ prev = cur;
+
+ if (u > ch) {
+ hi = cur;
+ cur -= (cur - lo) / 2;
+ } else {
+ lo = cur;
+ cur += (hi - cur) / 2;
+ }
+ } while (cur != prev);
+
+#undef u
+
return 0;
}
'Content-Length' => 0
)
);
+ $client->setOptions(["timeout" => 30]);
$client->enqueue($request);
echo $client->send()->getResponse()->getResponseCode();
});
{
function update(SplSubject $client, http\Client\Request $request = null, StdClass $progress = null) {
echo "P";
- if ($client->getProgressInfo($request) != $progress) {
+ if ($progress->info !== "prepare" && $client->getProgressInfo($request) != $progress) {
var_dump($progress);
}
}
include "skipif.inc";
skip_online_test();
skip_client_test();
+skip_curl_test("7.34.0");
?>
--FILE--
<?php
) === $client->getSslOptions()
);
+$client->attach($observer = new class implements SplObserver {
+ public $data = [];
+ function update(SplSubject $client, $req = null, $progress = null) {
+ $ti = $client->getTransferInfo($req);
+ if (isset($ti->tls_session["internals"])) {
+ foreach ((array) $ti->tls_session["internals"] as $key => $val) {
+ if (!isset($this->data[$key]) || $this->data[$key] < $val) {
+ $this->data[$key] = $val;
+ }
+ }
+ }
+ }
+});
+
$client->enqueue($req = new http\Client\Request("GET", "https://twitter.com/"));
$client->send();
-$ti = (array) $client->getTransferInfo($req);
-var_dump(array_key_exists("ssl_engines", $ti));
-var_dump(0 < count($ti["ssl_engines"]) || $ti["tls_session"]["backend"] != "openssl");
+switch ($client->getTransferInfo($req)->tls_session["backend"]) {
+ case "openssl":
+ case "gnutls":
+ if (count($observer->data) < 1) {
+ die("failed count(ssl.internals) >= 1\n");
+ }
+ break;
+ default:
+ break;
+}
?>
Done
--EXPECTF--
Test
bool(true)
-bool(true)
-bool(true)
Done
$o3 = new CallbackObserver(
function ($c, $r) {
$p = (array) $c->getProgressInfo($r);
+ if (!$p) {
+ return;
+ }
var_dump(array_key_exists("started", $p));
var_dump(array_key_exists("finished", $p));
var_dump(array_key_exists("dlnow", $p));
--EXPECTREGEX--
Test
[ST][WST]*([OWST]*)+U+int\(200\)
-===DONE===
+O*===DONE===
--- /dev/null
+--TEST--
+encoding stream brotli static
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli", false) or die("SKIP need brotli support");
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$file = file_get_contents(__FILE__);
+var_dump($file ===
+ http\Encoding\Stream\Debrotli::decode(
+ http\Encoding\Stream\Enbrotli::encode(
+ $file, http\Encoding\Stream\Enbrotli::MODE_GENERIC
+ )
+ )
+);
+var_dump($file ===
+ http\Encoding\Stream\Debrotli::decode(
+ http\Encoding\Stream\Enbrotli::encode(
+ $file, http\Encoding\Stream\Enbrotli::MODE_TEXT
+ )
+ )
+);
+var_dump($file ===
+ http\Encoding\Stream\Debrotli::decode(
+ http\Encoding\Stream\Enbrotli::encode(
+ $file, http\Encoding\Stream\Enbrotli::MODE_FONT
+ )
+ )
+);
+
+?>
+DONE
+--EXPECT--
+Test
+bool(true)
+bool(true)
+bool(true)
+DONE
--- /dev/null
+--TEST--
+encoding stream brotli auto flush
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli") or die("SKIP need brotli support");
+
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$defl = new http\Encoding\Stream\Enbrotli(http\Encoding\Stream::FLUSH_FULL);
+$infl = new http\Encoding\Stream\Debrotli;
+
+for ($f = fopen(__FILE__, "rb"); !feof($f); $data = fread($f, 0x100)) {
+ if (isset($data)) {
+ if ($data !== $d=$infl->update($defl->update($data))) {
+ printf("uh-oh »%s« != »%s«\n", $data, $d);
+ }
+ }
+}
+
+echo $infl->update($defl->finish());
+echo $infl->finish();
+
+var_dump($infl->done(), $defl->done());
+?>
+DONE
+--EXPECT--
+Test
+bool(true)
+bool(true)
+DONE
--- /dev/null
+--TEST--
+encoding stream brotli without flush
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli") or die("SKIP need brotli support");
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$defl = new http\Encoding\Stream\Enbrotli;
+$infl = new http\Encoding\Stream\Debrotli;
+$file = file(__FILE__);
+$data = "";
+foreach ($file as $line) {
+ if (strlen($temp = $defl->update($line))) {
+ foreach(str_split($temp) as $byte) {
+ $data .= $infl->update($byte);
+ }
+ }
+}
+if (strlen($temp = $defl->finish())) {
+ $data .= $infl->update($temp);
+}
+$data .= $infl->finish();
+var_dump(implode("", $file) === $data);
+?>
+DONE
+--EXPECT--
+Test
+bool(true)
+DONE
--- /dev/null
+--TEST--
+encoding stream brotli with explicit flush
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli") or die("SKIP need brotli support");
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$enc = new http\Encoding\Stream\Enbrotli;
+$dec = new http\Encoding\Stream\Debrotli;
+$file = file(__FILE__);
+$data = "";
+foreach ($file as $line) {
+ $data .= $dec->flush();
+ if (strlen($temp = $enc->update($line))) {
+ $data .= $dec->update($temp);
+ $data .= $dec->flush();
+ }
+ if (strlen($temp = $enc->flush())) {
+ $data .= $dec->update($temp);
+ $data .= $dec->flush();
+ }
+}
+if (strlen($temp = $enc->finish())) {
+ $data .= $dec->update($temp);
+}
+var_dump($enc->done());
+$data .= $dec->finish();
+var_dump($dec->done());
+var_dump(implode("", $file) === $data);
+
+?>
+DONE
+--EXPECT--
+Test
+bool(true)
+bool(true)
+bool(true)
+DONE
--- /dev/null
+--TEST--
+encoding stream brotli error
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli") or die("SKIP need brotli support");
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+var_dump(http\Encoding\Stream\Debrotli::decode("if this goes through, something's pretty wrong"));
+
+?>
+DONE
+--EXPECTF--
+Test
+
+Warning: http\Encoding\Stream\Debrotli::decode(): Could not brotli decode data: %s in %s on line %d
+bool(false)
+DONE
$r->send();
?>
---EXPECTHEADERSF--
-Content-Type: text/plain%s
+--EXPECTHEADERS--
+Content-Range: bytes 2-4/248
--EXPECTF--
php
--- /dev/null
+--TEST--
+brotli filter
+--SKIPIF--
+<?php
+include "skipif.inc";
+class_exists("http\\Encoding\\Stream\\Enbrotli", false) or die("SKIP need brotli support");
+?>
+--FILE--
+<?php
+list($in, $out) = stream_socket_pair(
+ STREAM_PF_UNIX,
+ STREAM_SOCK_STREAM,
+ STREAM_IPPROTO_IP
+);
+stream_filter_append($in, "http.brotli_decode", STREAM_FILTER_READ);
+stream_filter_append($out, "http.brotli_encode", STREAM_FILTER_WRITE,
+ http\Encoding\Stream\Enbrotli::LEVEL_MAX);
+
+$file = file(__FILE__);
+foreach ($file as $line) {
+ fwrite($out, $line);
+ fflush($out);
+}
+fclose($out);
+if (implode("",$file) !== ($read = fread($in, filesize(__FILE__)))) {
+ echo "got: $read\n";
+}
+fclose($in);
+?>
+DONE
+--EXPECT--
+DONE
foreach (array("raphf", "propro", "http") as $ext) {
if (!extension_loaded($ext)) {
- switch (PHP_SHLIB_SUFFIX) {
- case "dll":
- dl("php_$ext.dll");
- break;
- default:
- dl($ext .".". PHP_SHLIB_SUFFIX);
+ dl(ext_lib_name($ext));
+ }
+}
+
+function get_extension_load_arg($bin, $args, $ext) {
+ $bin = escapeshellcmd($bin);
+ $args = implode(' ', array_map('escapeshellarg', $args));
+
+ // check if php will load the extension with the existing args
+ exec(sprintf('%s %s -m', $bin, $args), $output);
+
+ foreach ($output as $line ) {
+ if (trim($line) === $ext) {
+ return null;
+ }
+ }
+
+ // try to load the extension with an arg
+ $arg = '-dextension=' . ini_get('extension_dir') . '/' . ext_lib_name($ext);
+ exec(sprintf('%s %s %s -m', $bin, $args, escapeshellarg($arg)), $output);
+
+ foreach ($output as $line ) {
+ if (trim($line) === $ext) {
+ return $arg;
}
}
+
+ // check if the child will be able to dl() the extension
+ $success = shell_exec(sprintf('%s %s -r "echo (int)dl(%s);', $bin, $args, var_export(ext_lib_name($ext), true)));
+ if ($success) {
+ return null;
+ }
+
+ echo "Unable to load extension '{$ext}' in child process";
+ exit(1);
+}
+
+function ext_lib_name($ext) {
+ if (PHP_SHLIB_SUFFIX === 'dll') {
+ return "php_{$ext}.dll";
+ }
+
+ return $ext . "." . PHP_SHLIB_SUFFIX;
}
function serve($cb) {
}
function server($handler, $cb) {
- $args = explode(' ', getenv('TEST_PHP_ARGS'));
- $args[] = __DIR__."/$handler";
- foreach ($args as $k => $v) {
- if (!$v) unset($args[$k]);
+ $args = [];
+ $argList = preg_split('#\s+#', getenv('TEST_PHP_ARGS'), -1, PREG_SPLIT_NO_EMPTY);
+ for ($i = 0; isset($argList[$i]); $i++) {
+ if ($argList[$i] === '-c') {
+ array_push($args, '-c', $argList[++$i]);
+ continue;
+ }
+ if ($argList[$i] === '-n') {
+ $args[] = '-n';
+ continue;
+ }
+ if ($argList[$i] === '-d') {
+ $args[] = '-d' . $args[++$i];
+ continue;
+ }
+ if (substr($argList[$i], 0, 2) === '-d') {
+ $args[] = $argList[$i];
+ }
}
+ foreach (['raphf', 'propro', 'http'] as $ext) {
+ if (null !== $arg = get_extension_load_arg(PHP_BIN, $args, $ext)) {
+ $args[] = $arg;
+ }
+ }
+ $args[] = __DIR__ . '/' . $handler;
proc(PHP_BIN, $args, $cb);
}
$stdout = $pipes[1];
$stderr = $pipes[2];
- usleep(50000);
+ sleep(1);
$status = proc_get_status($proc);
-
+ logger("nghttpd: %s", new http\Params($status));
if (!$status["running"]) {
continue;
}
function proc($bin, $args, $cb) {
$spec = array(array("pipe","r"), array("pipe","w"), array("pipe","w"));
$comm = escapeshellcmd($bin) . " ". implode(" ", array_map("escapeshellarg", $args));
+ logger("proc: %s %s", $bin, implode(" ", $args));
if (($proc = proc_open($comm, $spec, $pipes, __DIR__))) {
$stdin = $pipes[0];
$stdout = $pipes[1];
<?php
class m extends http\Message {
- function test() {
+ function test1() {
$this->headers["bykey"] = 1;
var_dump($this->headers);
-
+ }
+ function test2() {
$h = &$this->headers;
$h["by1ref"] = 2;
var_dump($this->headers);
-
+ }
+ function test3() {
$x = &$this->headers["byXref"];
$h = &$this->headers["by2ref"];
$x = 2;
var_dump($this->headers);
-
+ }
+ function test4() {
$this->headers["bynext"][] = 1;
$this->headers["bynext"][] = 2;
$this->headers["bynext"][] = 3;
}
$m=new m;
-$m->test();
+$m->test1();
+$m->test2();
+$m->test3();
+$m->test4();
echo $m,"\n";
?>
<?php
-function _ext($ext) { extension_loaded($ext) or die("skip $ext extension needed\n"); }
_ext("http");
+function _ext($ext) {
+ if (!extension_loaded($ext)) {
+ die("skip $ext extension needed\n");
+ }
+}
+
+function utf8locale() {
+ if (stristr(setlocale(LC_CTYPE, "C.UTF-8"), "utf")) {
+ return true;
+ }
+ $locale = setlocale(LC_CTYPE, null);
+ if (stristr($locale, "utf") && substr($locale, -1) === "8") {
+ return true;
+ }
+ return false;
+}
+
function skip_online_test($message = "skip test requiring internet connection\n") {
if (getenv("SKIP_ONLINE_TESTS")) {
die($message);
}
}
+function skip_curl_test($version) {
+ if (!version_compare(http\Client\Curl\Versions\CURL, $version, "<=")) {
+ die("need at least libcurl version $version\n");
+ }
+}
+
function skip_http2_test($message = "skip need http2 support") {
if (!defined("http\\Client\\Curl\\HTTP_VERSION_2_0")) {
die("$message (HTTP_VERSION_2_0)\n");
}
}
die("$message (nghttpd in PATH)\n");
-}
\ No newline at end of file
+}
<?php
include "skipif.inc";
if (!defined("http\\Url::PARSE_MBLOC") or
- !stristr(setlocale(LC_CTYPE, "C.UTF-8"), "utf")) {
+ !utf8locale()) {
die("skip need http\\Url::PARSE_MBLOC support and LC_CTYPE=*.UTF-8");
}
?>
include "skipif.inc";
if (!defined("http\\Url::PARSE_MBLOC") or
!defined("http\\Url::PARSE_TOIDN_2003") or
- !stristr(setlocale(LC_CTYPE, "C.UTF-8"), ".utf")) {
+ !utf8locale()) {
die("skip need http\\Url::PARSE_MBLOC|http\\Url::PARSE_TOIDN_2003 support and LC_CTYPE=*.UTF-8");
}
?>
<?php
include "skipif.inc";
if (!defined("http\\Url::PARSE_MBLOC") or
- !stristr(setlocale(LC_CTYPE, "C.UTF-8"), ".utf")) {
+ !utf8locale()) {
die("skip need http\\Url::PARSE_MBLOC support and LC_CTYPE=*.UTF-8");
}
include "skipif.inc";
if (!defined("http\\Url::PARSE_MBLOC") or
!defined("http\\Url::PARSE_TOIDN") or
- !stristr(setlocale(LC_CTYPE, "C.UTF-8"), ".utf")) {
+ !utf8locale()) {
die("skip need http\\Url::PARSE_MBLOC|http\Url::PARSE_TOIDN support and LC_CTYPE=*.UTF-8");
}
--SKIPIF--
<?php
include "skipif.inc";
-if (!defined("http\\Url::PARSE_TOIDN") or
+defined("http\\Url::PARSE_TOIDN") or
die("skip need http\\Url::PARSE_TOIDN support");
-}
?>
--FILE--
<?php
--- /dev/null
+#!/bin/bash
+
+BROTLI_DIR="$with_http_libbrotli_dir"
+BROTLI_SRC="$BROTLI_DIR.git"
+
+if test -n "$BROTLI_DIR" && test "$BROTLI_DIR" != "no"; then
+ if test -d "$BROTLI_SRC"; then
+ cd "$BROTLI_SRC"
+ git pull
+ else
+ git clone https://github.com/google/brotli.git "$BROTLI_SRC"
+ cd "$BROTLI_SRC"
+ fi
+ git checkout $1
+ ./bootstrap
+ ./configure -C --prefix="$BROTLI_DIR"
+ make -j ${JOBS:2}
+ make install INSTALL=install
+fi
-Subproject commit 79de9c8e52f16a2e06324683cf4c00c91df1b6c1
+Subproject commit dd0a2e61211836ac7b24a271a5bd68af99dee3d6