From: Michael Wallner Date: Mon, 5 Feb 2024 19:36:16 +0000 (+0100) Subject: prepare v4.2.5 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=refs%2Fheads%2Fmaster;hp=c17987e25b6558974e60d20c4c10be9fd5221094 prepare v4.2.5 * Fix incompatible pointer types (32-bit) (see gh issue #134) * Fix glitch in CURL_VERSION_TLSAUTH_SRP autoconf probe (see gh issue #133) --- diff --git a/.github/Makefile b/.github/Makefile new file mode 100644 index 0000000..29166f3 --- /dev/null +++ b/.github/Makefile @@ -0,0 +1,8 @@ +.PHONY: all +all: workflows/ci.yml +all: workflows/curl-matrix.yml + +workflows/%.yml: ../scripts/gen_github_workflow_%.php + $<>$@ + +workflows/curl-matrix.yml: ../scripts/curlver.dist diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e04f594 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,456 @@ +# generated file; do not edit! + +name: ci +on: + workflow_dispatch: + push: + pull_request: + +jobs: + next-0: + name: "next-0 (master)" + continue-on-error: true + env: + PHP: "master" + enable_debug: "yes" + enable_zts: "yes" + enable_iconv: "yes" + TEST_PHP_ARGS: "-d error_reporting=24575" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + old-0: + name: "old-0 (8.1)" + env: + PHP: "8.1" + enable_debug: "yes" + enable_zts: "yes" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + old-1: + name: "old-1 (8.0)" + env: + PHP: "8.0" + enable_debug: "yes" + enable_zts: "yes" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-none-0: + name: "cur-none-0 (8.2)" + env: + PHP: "8.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" + with_http_libbrotli_dir: "no" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-dbg-zts-0: + name: "cur-dbg-zts-0 (8.2)" + env: + PHP: "8.2" + enable_debug: "yes" + enable_zts: "yes" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-dbg-zts-1: + name: "cur-dbg-zts-1 (8.2)" + env: + PHP: "8.2" + enable_debug: "no" + enable_zts: "yes" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-dbg-zts-2: + name: "cur-dbg-zts-2 (8.2)" + env: + PHP: "8.2" + enable_debug: "yes" + enable_zts: "no" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-dbg-zts-3: + name: "cur-dbg-zts-3 (8.2)" + env: + PHP: "8.2" + enable_debug: "no" + enable_zts: "no" + enable_iconv: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + cur-cov-0: + name: "cur-cov-0 (8.2)" + env: + CFLAGS: "-O0 -g --coverage" + CXXFLAGS: "-O0 -g --coverage" + PHP: "8.2" + enable_iconv: "yes" + with_http_libicu_dir: "yes" + with_http_libidn_dir: "no" + with_http_libidn2_dir: "no" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + - name: Coverage + if: success() + run: | + cd src/.libs + bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy + + cur-cov-1: + name: "cur-cov-1 (8.2)" + env: + CFLAGS: "-O0 -g --coverage" + CXXFLAGS: "-O0 -g --coverage" + PHP: "8.2" + enable_iconv: "yes" + with_http_libicu_dir: "no" + with_http_libidn_dir: "yes" + with_http_libidn2_dir: "no" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + - name: Coverage + if: success() + run: | + cd src/.libs + bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy + + cur-cov-2: + name: "cur-cov-2 (8.2)" + env: + CFLAGS: "-O0 -g --coverage" + CXXFLAGS: "-O0 -g --coverage" + PHP: "8.2" + enable_iconv: "yes" + with_http_libicu_dir: "no" + with_http_libidn_dir: "no" + with_http_libidn2_dir: "yes" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + - name: Coverage + if: success() + run: | + cd src/.libs + bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy + diff --git a/.github/workflows/curl-matrix.yml b/.github/workflows/curl-matrix.yml new file mode 100644 index 0000000..a37e548 --- /dev/null +++ b/.github/workflows/curl-matrix.yml @@ -0,0 +1,877 @@ +# generated file; do not edit! + +name: curl-matrix +on: + workflow_dispatch: + push: + +jobs: + curl-master: + name: curl-master + continue-on-error: true + env: + PHP: "8.2" + CURL: "master" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-8_1_1: + name: curl-8_1_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "8_1_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-8_1_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-8_0_1: + name: curl-8_0_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "8_0_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-8_0_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_88_1: + name: curl-7_88_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_88_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_88_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_87_0: + name: curl-7_87_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_87_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_87_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_85_0: + name: curl-7_85_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_85_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_85_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_81_0: + name: curl-7_81_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_81_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_81_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_78_0: + name: curl-7_78_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_78_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_78_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_74_0: + name: curl-7_74_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_74_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_74_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_61_1: + name: curl-7_61_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_61_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_61_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_49_1: + name: curl-7_49_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_49_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_49_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_31_0: + name: curl-7_31_0 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_31_0" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_31_0 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_20_1: + name: curl-7_20_1 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_20_1" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_20_1 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_19_7: + name: curl-7_19_7 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_19_7" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_19_7 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + curl-7_18_2: + name: curl-7_18_2 + continue-on-error: true + env: + PHP: "8.2" + CURL: "7_18_2" + enable_debug: "yes" + enable_iconv: "yes" + with_http_libcurl_dir: "/opt" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + ref: curl-7_18_2 # + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + diff --git a/.gitignore b/.gitignore index 95f72a2..99028c9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ .cproject .deps +*.dep .libs/ .project -Makefile +/Makefile Makefile.fragments Makefile.global Makefile.objects @@ -10,6 +11,7 @@ acinclude.m4 aclocal.m4 autom4te.cache/ build/ +config.cache config.guess config.h config.h.in @@ -18,6 +20,7 @@ config.nice config.status config.sub configure +configure.ac configure.in http.la install-sh @@ -81,3 +84,4 @@ vendor/ /tests/helper/server.log *gcov *lcov +.vscode diff --git a/.gitmodules b/.gitmodules index e53f88c..72fd52f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ -[submodule "travis-pecl"] - path = travis/pecl - url = https://github.com/m6w6/travis-pecl.git - branch = master +[submodule "scripts/ci"] + path = scripts/ci + url = https://github.com/m6w6/pecl-ci.git diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1f1f111..0000000 --- a/.travis.yml +++ /dev/null @@ -1,81 +0,0 @@ -# autogenerated file; do not edit -language: c - -addons: - apt: - packages: - - php-cli - - php-pear - - libcurl4-openssl-dev - - libidn11-dev - - libidn2-0-dev - - libicu-dev - - libevent-dev - - libbrotli-dev - -dist: xenial - -cache: - apt: true - directories: - - $HOME/cache -before_cache: - - find $HOME/cache -name '*.gcda' -o -name '*.gcno' -delete - -env: - - PHP=7.0 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.1 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.2 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.3 enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.4 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 with_http_libbrotli_dir=no - - PHP=7.4 PECLs=event enable_sockets=yes enable_debug=no enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.4 PECLs=event enable_sockets=yes enable_debug=yes enable_maintainer_zts=no enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.4 PECLs=event enable_sockets=yes enable_debug=no enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - PHP=7.4 PECLs=event enable_sockets=yes enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - - CFLAGS='-O0 -g --coverage' CXXFLAGS='-O0 -g --coverage' PHP=7.4 PECLs=event enable_sockets=yes enable_json=yes enable_hash=yes enable_iconv=yes 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.4 PECLs=event enable_sockets=yes enable_json=yes enable_hash=yes enable_iconv=yes 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.4 PECLs=event enable_sockets=yes enable_json=yes enable_hash=yes enable_iconv=yes with_http_libidn2_dir=yes with_http_libicu_dir=no with_http_libidn_dir=no - -matrix: - fast_finish: true - allow_failures: - - env: PHP=master enable_debug=yes enable_maintainer_zts=yes enable_json=yes enable_hash=yes enable_iconv=yes - -install: - - | - 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 - - | - if test -n "$PECLs"; then \ - IFS=$','; \ - for pecl in $PECLs; do \ - make -f travis/pecl/Makefile pecl PECL=$pecl; \ - done; \ - unset IFS; \ - fi - -script: - - make -f travis/pecl/Makefile ext PECL=http - - make -f travis/pecl/Makefile test - -after_script: - - make -f travis/pecl/Makefile cppcheck -after_failure: - - test -e tests/helper/server.log && cat tests/helper/server.log -after_success: - - test -n "$CFLAGS" && cd src/.libs && bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy - -notifications: - webhooks: - urls: - - https://webhooks.gitter.im/e/28d35158ac7e385bd14d - on_success: change - on_failure: always - on_start: never diff --git a/BUGS b/BUGS index 4c2ad80..0b98179 100644 --- a/BUGS +++ b/BUGS @@ -2,15 +2,13 @@ Known Issues ============ Windows: - If you keep getting "SSL connect error" when trying to issue + If you keep getting "SSL connect error" when trying to issue requests, try another (newer) libeay32.dll/ssleay32.dll pair. Internals: Inflating raw deflated data causes a re-initialization of the inflate stream where the corresponding window bits are modified to tell libz to not check for zlib header bytes. This is not preventable AFAICS. - LFS dependant parts of libcurl are left out because of off_t, - respectively off64_t confusion. Persistent handles and "cookiestore" request option do interfere, as libcurl saves the cookies to the file on curl_easy_destroy(), cookies are not saved until the CURL handle will be recycled. diff --git a/CHANGELOG.md b/CHANGELOG.md index ef31dc3..47ec2a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,175 +1,88 @@ -# ChangeLog v3 - -## 3.2.1, 2019-06-07 - -* Fixed gh-issue #88: Unable to run test suite (Remi Collet) -* Fixed gh-issue #86: test failure with curl 7.64 -* Fixed gh-issue #85: [-Wformat-extra-args] build warnings -* Fixed gh-issue #84: segfault and build failure since curl 7.62 -* Fixed gh-issue #82: Test harness improvements (Chris Wright) -* Fixed gh-issue #64: compress and connecttimeout interfere with low_speed_limit (@rcanavan) -* Fixed http\QueryString::getGlobalInstance() -* Fixed missing 2nd reflection argument info of http\Client::notify() -* Fixed PHP-7.4 compatibility - -## 3.2.0, 2018-07-19 - -* PHP-7.2 compatibility -* Fixed gh-issue #73: build fails with libidn and libidn2 -+ Added brotli compression support -+ Implemented gh-issue #58: Notify observers before any request is built - -Changes from RC1: -* Fixed gh-issue #78: PHP-7.3 build crashes - -## 3.2.0RC1, 2018-04-09 - -* PHP-7.2 compatibility -* Fixed gh-issue #73: build fails with libidn and libidn2 -+ Added brotli compression support -+ Implemented gh-issue #58: Notify observers before any request is built - -## 3.1.0, 2016-12-12 - -+ Added http\Client\Curl\User interface for userland event loops -+ Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS -+ Added http\Client::setDebug(callable $debug) -+ Added http\Client\Curl\FEATURES constants and namespace -+ Added http\Client\Curl\VERSIONS constants and namespace -+ Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() -+ http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests -+ Improved configure checks for default CA bundles -+ Improved negotiation precision -* Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. -* Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) -* Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) -* Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) -* Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) -* Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) -* Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) -* Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) -* Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) -* Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) -* Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) -* Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) -* Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) -* Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) +# ChangeLog v4 + +## 4.2.5, 2024-02-05 + +* Fix incompatible pointer types (32-bit) (see gh issue #134) +* Fix glitch in CURL_VERSION_TLSAUTH_SRP autoconf probe (see gh issue #133) + +## 4.2.4, 2023-10-02 + +* Fix Error using ssl array in options : Could not set option tlsauthtype + (see gh issue #131) +* Fix arginfo wargnings of the internal curl client user handler +* Disable libidn support for v1.36-v1.38 due to broken locale detection + +## 4.2.3, 2022-06-10 + +* Fix http\Client::requeue() not updating response callback + +## 4.2.2, 2022-02-25 + +* Fixed gh-issue #123: Segfault with libcurl 7.81 + +## 4.2.1, 2021-09-13 + +* Fixed failing tests with PHP-8.1 (see gh issue #120) +* Fixed configure reliably finding the right libcurl features available +* Fixed cookie handling with libcurl 7.77+ and consistently across all + supported libcurl versions (follow-up to gh issue #116) + +## 4.2.0, 2021-08-30 + +* Fixed PHP-8.1 compatibility (see gh issues #114, #115 and #118) +* Fixed cookies failing with libcurl >= 7.77 (see gh issue #116) +* Fixed tests using $_ENV instead of getenv() to find executables in PATH (see gh issue #113) +* Added http\Env::reset(): resets internal HTTP request cache (see gh issue #90) + +## 4.1.0, 2021-04-21 + +* Added request options: + * http\Client\Curl::$abstract_unix_socket + * http\Client\Curl::$altsvc + * http\Client\Curl::$altsvc_ctrl + * http\Client\Curl::$aws_sigv4 + * http\Client\Curl::$doh_url + * http\Client\Curl::$dns_shuffle_addresses + * http\Client\Curl::$haproxy_protocol + * http\Client\Curl::$hsts + * http\Client\Curl::$hsts_ctrl + * http\Client\Curl::$http09_allowed + * http\Client\Curl::$maxage_conn + * http\Client\Curl::$pinned_publickey + * http\Client\Curl::$proxy_ssl + * http\Client\Curl::$socks5_auth + * http\Client\Curl::$tcp_fastopen + * http\Client\Curl::$tls13_ciphers + * http\Client\Curl::$xoauth2_bearer +* Added request option constants: + * http\Client\Curl\AUTH_AWS_SIGV4 + * http\Client\Curl\AUTH_BEARER + * http\Client\Curl\AUTH_NONE + * http\Client\Curl\HTTP_VERSION_2_PRIOR_KNOWLEDGE + * http\Client\Curl\HTTP_VERSION_3 + * http\Client\Curl\SSL_VERSION_MAX_* + * http\Client\Curl\SSL_VERSION_TLSv1_3 +* Added library version constants: + * http\Client\Curl\Versions\BROTLI + * http\Client\Curl\Versions\CAINFO + * http\Client\Curl\Versions\CAPATH + * http\Client\Curl\Versions\HYPER + * http\Client\Curl\Versions\ICONV + * http\Client\Curl\Versions\NGHTTP2 + * http\Client\Curl\Versions\QUIC + * http\Client\Curl\Versions\ZSTD + +## 4.0.0, 2021-01-13 Changes from beta1: -* Fixed recursive calls to the event loop dispatcher - -Changes from beta2: -+ Improved configure checks for IDNA libraries (added --with-http-libicu-dir, --with-http-libidnkit{,2}-dir, --with-http-libidn2-dir) -* Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) -* Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) (CVE-2016-7961) -* Fix HTTP/2 version parser for older libcurl versions (Mike) -* Fix gh-issue #52: Underscores in host names: libidn Failed to parse IDN (Mike, @canavan) - -## 3.1.0RC1, 2016-10-04 - -+ Added http\Client\Curl\User interface for userland event loops -+ Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS -+ Added http\Client::setDebug(callable $debug) -+ Added http\Client\Curl\FEATURES constants and namespace -+ Added http\Client\Curl\VERSIONS constants and namespace -+ Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() -+ http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests -+ Improved configure checks for default CA bundles -+ Improved negotiation precision -* Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. -* Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) -* Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) -* Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) -* Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) -* Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) -* Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) -* Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) -* Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) -* Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) -* Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) -* Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) -* Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) -* Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) +* Fixed configure on systems which do not provide icu-config +* Fixed gh-issue #89: Cookie handling cannot be disabled since v3.2.1 -Changes from beta1: -* Fixed recursive calls to the event loop dispatcher - -Changes from beta2: -+ Improved configure checks for IDNA libraries (added --with-http-libicu-dir, --with-http-libidnkit{,2}-dir, --with-http-libidn2-dir) -* Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) -* Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) (CVE-2016-7961) -* Fix HTTP/2 version parser for older libcurl versions (Mike) -* Fix gh-issue #52: Underscores in host names: libidn Failed to parse IDN (Mike, @canavan) - -## 3.1.0beta2, 2016-09-07 - -+ Added http\Client\Curl\User interface for userland event loops -+ Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS -+ Added http\Client::setDebug(callable $debug) -+ Added http\Client\Curl\FEATURES constants and namespace -+ Added http\Client\Curl\VERSIONS constants and namespace -+ Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() -+ http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests -+ Improved configure checks for default CA bundles -+ Improved negotiation precision -* Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. -* Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) -* Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) -* Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) -* Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) -* Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) -* Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) -* Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) -* Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) -* Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) -* Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) -* Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) -* Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) -* Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) - -Changes from beta1: -* Fixed recursive calls to the event loop dispatcher - -## 3.1.0beta1, 2016-08-22 - -+ Added http\Client\Curl\User interface for userland event loops -+ Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS -+ Added http\Client::setDebug(callable $debug) -+ Added http\Client\Curl\FEATURES constants and namespace -+ Added http\Client\Curl\VERSIONS constants and namespace -+ Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() -+ http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests -+ Improved configure checks for default CA bundles -+ Improved negotiation precision -* Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. -* Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) -* Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) -* Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) -* Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) -* Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) -* Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) -* Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) -* Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) -* Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) -* Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) -* Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) -* Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) -* Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) - -## 3.0.1, 2016-03-09 - -* Fix php-bug #71719: Buffer overflow in HTTP url parsing functions (Mike, rc0r) -* Fix gh-issue #28: Possible null pointer dereference in php_http_url_mod() (rc0r) -* Fix gh-issue #21: Fix PHP7 config.w32 (Jan Ehrhardt) -* Fix gh-issue #20: setSslOptions notice with curl 7.43 (Mike, Vitaliy Demidov) - -## 3.0.0, 2016-01-19 - -PHP7 compatible release based on the 2.5.x series with the following backwards incompatible changes: -- removed http\Url::FROM_ENV from the default flags of the http\Url constructor, use http\Env\Url instead - -## 3.0.0RC1, 2015-12-07 - -PHP7 compatible release based on the 2.5.x series with the following backwards incompatible changes: -- removed http\Url::FROM_ENV from the default flags of the http\Url constructor, use http\Env\Url instead +## 4.0.0beta1, 2020-09-23 +* PHP 8 compatibility + - Drop ext-propro support: + PHP 8 removes the object get/set API from the ZendEngine, which renders + that extension dysfunctional. As a consequence, the header property of + http\Message and derived classes cannot be modified in place, and thus + by reference. diff --git a/README.md b/README.md index 8bd6c0a..d4fb448 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ # ext-http -[![Build Status](https://travis-ci.org/m6w6/ext-http.svg?branch=master)](https://travis-ci.org/m6w6/ext-http) +[![Build Status](https://github.com/m6w6/ext-http/workflows/ci/badge.svg?branch=master)](https://github.com/m6w6/ext-http/actions?query=workflow%3Aci+branch%3Amaster) [![Coverity Scan Build Status](https://scan.coverity.com/projects/8711/badge.svg)](https://scan.coverity.com/projects/m6w6-ext-http) [![codecov](https://codecov.io/gh/m6w6/ext-http/branch/master/graph/badge.svg)](https://codecov.io/gh/m6w6/ext-http) -[![Join the chat at https://gitter.im/m6w6/ext-http](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/m6w6/ext-http) -Extended HTTP support. Again. +Extended HTTP support for PHP. + +## Branches and Versions: + +> **NOTE:** + Use `v3.x` branch, and resp. v3 releases, for PHP-7. `master` and v4 releases are only for PHP-8. + ## Documentation @@ -13,7 +18,7 @@ See the [online markdown reference](https://mdref.m6w6.name/http). Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO). -## Installing +## Install ### PECL diff --git a/autoconf/pecl/libbrotli.m4 b/autoconf/pecl/libbrotli.m4 index f8916e2..aee9483 100644 --- a/autoconf/pecl/libbrotli.m4 +++ b/autoconf/pecl/libbrotli.m4 @@ -6,7 +6,7 @@ AC_DEFUN([PECL_CHECK_LIBBROTLI], [ 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 @@ -14,11 +14,16 @@ AC_DEFUN([PECL_CHECK_LIBBROTLI], [ else PECL_VAR([HAVE_LIBBROTLI])=false fi + dnl config.m4 calls PECL_CHECK_DONE once more + PECL_COUNT_CHECKS([+1]) + PECL_SAVE_ENV([CPPFLAGS], [libbrotli]) + PECL_SAVE_ENV([LDFLAGS], [libbrotli]) + PECL_SAVE_ENV([LIBS], [libbrotli]) ]) 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 ], [ @@ -28,7 +33,7 @@ AC_DEFUN([PECL_CHECK_LIBBROTLI_COMMON], [ 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 ], [ @@ -38,7 +43,7 @@ AC_DEFUN([PECL_CHECK_LIBBROTLI_DEC], [ 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 ], [ diff --git a/autoconf/pecl/libcurl.m4 b/autoconf/pecl/libcurl.m4 index fce6437..fd0e711 100644 --- a/autoconf/pecl/libcurl.m4 +++ b/autoconf/pecl/libcurl.m4 @@ -7,7 +7,7 @@ dnl AC_DEFUN([PECL_HAVE_LIBCURL_FEATURE], [dnl AC_REQUIRE([PECL_PROG_EGREP])dnl AC_CACHE_CHECK([for $1 feature in libcurl], PECL_CACHE_VAR([HAVE_LIBCURL_FEATURE_$1]), [ - if $CURL_CONFIG --feature | $EGREP -q $1; then + if $CURL_CONFIG --feature | $EGREP -qi $1; then PECL_CACHE_VAR([HAVE_LIBCURL_FEATURE_$1])=yes else PECL_CACHE_VAR([HAVE_LIBCURL_FEATURE_$1])=no @@ -126,40 +126,66 @@ AC_DEFUN([PECL_HAVE_LIBCURL_SSL], [dnl ;; esac - PECL_HAVE_CONST([curl/curl.h], [CURLOPT_TLSAUTH_TYPE], int, [ - AC_CACHE_CHECK([whether CURLOPT_TLSAUTH_TYPE expects CURL_TLSAUTH_SRP], PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP]), [ - PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])= + PECL_HAVE_CONST([curl/curl.h], [CURL_VERSION_TLSAUTH_SRP], int, [ + AC_CACHE_CHECK([for CURLOPT_TLSAUTH_TYPE SRP support], PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP]), [ + PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])=no AC_TRY_RUN([ #include int main(int argc, char *argv[]) { - CURL *ch = curl_easy_init(); - return curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, CURL_TLSAUTH_SRP); + int has_feature = curl_version_info(CURLVERSION_NOW)->features & CURL_VERSION_TLSAUTH_SRP; + int set_failure = curl_easy_setopt(curl_easy_init(), CURLOPT_TLSAUTH_TYPE, "SRP"); + return !has_feature || set_failure; } ], [ PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])=yes + ]) + ]) + if test "$PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])" = "yes"; then + PECL_DEFINE([HAVE_LIBCURL_TLSAUTH_TYPE]) + fi + ]) + + PECL_HAVE_CONST([curl/curl.h], [CURL_LOCK_DATA_SSL_SESSION], int, [ + AC_CACHE_CHECK([whether curl_share accepts CURL_LOCK_DATA_SSL_SESSION], PECL_CACHE_VAR([LIBCURL_SHARE_SSL]), [ + PECL_CACHE_VAR([LIBCURL_SHARE_SSL])= + AC_TRY_RUN([ + #include + int main(int argc, char *argv[]) { + CURLSH *ch = curl_share_init(); + return curl_share_setopt(ch, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + } + ], [ + PECL_CACHE_VAR([LIBCURL_SHARE_SSL])=yes ], [ + PECL_CACHE_VAR([LIBCURL_SHARE_SSL])=no + ]) + ]) + if test "$PECL_CACHE_VAR([LIBCURL_SHARE_SSL])" = yes; then + PECL_DEFINE([HAVE_LIBCURL_SHARE_SSL], [1]) + fi + ]) + + if test "$PECL_VAR([LIBCURL_SSLLIB])" == "OpenSSL"; then + PECL_HAVE_CONST([curl/curl.h], [CURLOPT_TLS13_CIPHERS], int, [ + AC_CACHE_CHECK([whether curl_easy_setopt accepts CURLOPT_TLS13_CIPHERS], PECL_CACHE_VAR([LIBCURL_TLS13_CIPHERS]), [ + PECL_CACHE_VAR([LIBCURL_TLS13_CIPHERS])= AC_TRY_RUN([ #include int main(int argc, char *argv[]) { CURL *ch = curl_easy_init(); - return curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, "SRP"); + return curl_easy_setopt(ch, CURLSHOPT_TLS13_CIPHERS, ""); } ], [ - PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])=no + PECL_CACHE_VAR([LIBCURL_TLS13_CIPHERS])=yes + ], [ + PECL_CACHE_VAR([LIBCURL_TLS13_CIPHERS])=no ]) ]) - ]) - if test -n "$PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP])"; then - PECL_DEFINE([HAVE_LIBCURL_TLSAUTH_TYPE]) - if $PECL_CACHE_VAR([LIBCURL_TLSAUTH_SRP]); then - PECL_DEFINE([LIBCURL_TLSAUTH_SRP], [CURL_TLSAUTH_SRP]) - PECL_DEFINE([LIBCURL_TLSAUTH_DEF], [CURL_TLSAUTH_NONE]) - else - PECL_DEFINE([LIBCURL_TLSAUTH_SRP], ["SRP"]) - PECL_DEFINE([LIBCURL_TLSAUTH_DEF], [""]) + if test "$PECL_CACHE_VAR([LIBCURL_TLS13_CIPHERS])" = yes; then + PECL_DEFINE([HAVE_LIBCURL_TLS13_CIPHERS], [1]) fi - fi - ]) + ]) + fi ]) ]) dnl @@ -225,4 +251,4 @@ AC_DEFUN([PECL_CHECK_LIBCURL], [dnl ifelse([$2],,,[ PECL_HAVE_VERSION([libcurl], [$2]) ]) -]) \ No newline at end of file +]) diff --git a/autoconf/pecl/pecl.m4 b/autoconf/pecl/pecl.m4 index ffa45ac..cb2bb70 100644 --- a/autoconf/pecl/pecl.m4 +++ b/autoconf/pecl/pecl.m4 @@ -70,6 +70,12 @@ AC_DEFUN([PECL_RESTORE_ENV], [ $1=$PECL_SAVE_VAR([$2_$1]) ]) dnl +dnl PECL_COUNT_CHECKS(incdec) +dnl +AC_DEFUN([PECL_COUNT_CHECKS], [ + PECL_VAR([_checks])=$(($PECL_VAR([_checks])$1)) +]) +dnl dnl PECL_EVAL_LIBLINE(libline) dnl AC_DEFUN([PECL_EVAL_LIBLINE], [ @@ -244,6 +250,7 @@ dnl dnl PECL_CHECK_CUSTOM(name, path, header, lib, version) dnl AC_DEFUN([PECL_CHECK_CUSTOM], [ + PECL_COUNT_CHECKS([+1]) PECL_SAVE_ENV([CPPFLAGS], [$1]) PECL_SAVE_ENV([LDFLAGS], [$1]) PECL_SAVE_ENV([LIBS], [$1]) @@ -260,11 +267,11 @@ AC_DEFUN([PECL_CHECK_CUSTOM], [ done ]) if test -n "$PECL_CACHE_VAR([$1_prefix])"; then - CPPFLAGS="-I$PECL_CACHE_VAR([$1_prefix])/include" - LDFLAGS="-L$PECL_CACHE_VAR([$1_prefix])/$PHP_LIBDIR" - LIBS="-l$4" - PECL_EVAL_LIBLINE([$LDFLAGS $LIBS]) - + CPPFLAGS="$CPPFLAGS -I$PECL_CACHE_VAR([$1_prefix])/include" + LDFLAGS="$LDFLAGS -L$PECL_CACHE_VAR([$1_prefix])/$PHP_LIBDIR" + LIBS="$LIBS -l$4" + dnl PECL_EVAL_LIBLINE([$LDFLAGS $LIBS]) + AC_CACHE_VAL(PECL_CACHE_VAR([$1_version]), [ pushd $PECL_CACHE_VAR([$1_prefix]) >/dev/null PECL_CACHE_VAR([$1_version])=$5 @@ -274,7 +281,6 @@ AC_DEFUN([PECL_CHECK_CUSTOM], [ if test -n "$PECL_CHECKED_VERSION([$1])"; then PECL_VAR([HAVE_$1])=true - PECL_DEFINE([HAVE_$1]) PECL_DEFINE_UQ($1[_VERSION], "$PECL_CHECKED_VERSION([$1])") else PECL_VAR([HAVE_$1])=false @@ -288,11 +294,11 @@ dnl dnl PECL_CHECK_CONFIG(name, prog-config, version-flag, cppflags-flag, ldflags-flag, libs-flag) dnl AC_DEFUN([PECL_CHECK_CONFIG], [ + PECL_COUNT_CHECKS([+1]) PECL_SAVE_ENV([CPPFLAGS], [$1]) PECL_SAVE_ENV([LDFLAGS], [$1]) PECL_SAVE_ENV([LIBS], [$1]) - AC_MSG_CHECKING([for $1]) ifelse($2, [$PKG_CONFIG $1], [ AC_CACHE_VAL(PECL_CACHE_VAR([$1_exists]), [ @@ -311,29 +317,28 @@ AC_DEFUN([PECL_CHECK_CONFIG], [ AC_CACHE_VAL(PECL_CACHE_VAR([$1_cppflags]), [ PECL_CACHE_VAR([$1_cppflags])=$($2 $4) ]) - CPPFLAGS=$PECL_CACHE_VAR([$1_cppflags]) + CPPFLAGS="$CPPFLAGS $PECL_CACHE_VAR([$1_cppflags])" AC_CACHE_VAL(PECL_CACHE_VAR([$1_ldflags]), [ PECL_CACHE_VAR([$1_ldflags])=$($2 $5) ]) - LDFLAGS=$PECL_CACHE_VAR([$1_ldflags]) + LDFLAGS="$LDFLAGS $PECL_CACHE_VAR([$1_ldflags])" AC_CACHE_VAL(PECL_CACHE_VAR([$1_libs]), [ PECL_CACHE_VAR([$1_libs])=$($2 $6) ]) - LIBS=$PECL_CACHE_VAR([$1_libs]) - PECL_EVAL_LIBLINE([$LDFLAGS $LIBS]) + LIBS="$LIBS $PECL_CACHE_VAR([$1_libs])" + dnl PECL_EVAL_LIBLINE([$LDFLAGS $LIBS]) ifelse($2, [$PKG_CONFIG $1], [ fi ]) + AC_MSG_RESULT([${PECL_CHECKED_VERSION([$1]):-no}]) + if test -n "$PECL_CHECKED_VERSION([$1])"; then PECL_VAR([HAVE_$1])=true - PECL_DEFINE([HAVE_$1]) PECL_DEFINE_UQ([$1_VERSION], "$PECL_CHECKED_VERSION([$1])") else PECL_VAR([HAVE_$1])=false fi - - AC_MSG_RESULT([${PECL_CHECKED_VERSION([$1]):-no}]) ]) dnl dnl PECL_CHECK_PKGCONFIG(pkg[, additional-pkg-config-path]) @@ -355,9 +360,25 @@ dnl dnl PECL_CHECK_DONE(name, success[, incline, libline]) dnl AC_DEFUN([PECL_CHECK_DONE], [ - if $2; then - incline=$CPPFLAGS - libline="$LDFLAGS $LIBS" + PECL_COUNT_CHECKS([-1]) + success=$2 + if $success && test -n "$LDFLAGS$LIBS"; then + AC_MSG_CHECKING([whether $1 can be linked]) + AC_TRY_LINK([], [], [success=yes], [success=no]) + AC_MSG_RESULT([$success]) + if ! $success; then + AC_MSG_WARN([$1 was found, but fails to link with:]) + AC_MSG_WARN([ LDFLAGS='$LDFLAGS']) + AC_MSG_WARN([ LIBS='$LIBS']) + AC_MSG_WARN([Missing or updated library paths?]) + fi + fi + if $success; then + _cppflags=$PECL_SAVE_VAR([$1_CPPFLAGS]) + _ldflags=$PECL_SAVE_VAR([$1_LDFLAGS]) + _libs=$PECL_SAVE_VAR([$1_LIBS]) + incline=${CPPFLAGS:${#_cppflags}} + libline=["${LDFLAGS:${#_ldflags}} ${LIBS:${#_libs}}"] PECL_DEFINE([HAVE_$1]) else incline=$3 diff --git a/config.w32 b/config.w32 index c37c61b..3cc4069 100644 --- a/config.w32 +++ b/config.w32 @@ -123,15 +123,14 @@ if (PHP_HTTP != "no") { CHECK_LIB("normaliz.lib", "http", PHP_HTTP) && CHECK_LIB("libssl.lib;ssleay32.lib", "http", PHP_HTTP) && CHECK_LIB("libcrypto.lib;libeay32.lib", "http", PHP_HTTP) && + CHECK_LIB("crypt32.lib;libeay32.lib", "http", PHP_HTTP) && CHECK_LIB("zlib.lib;zlib_a.lib", "http", PHP_HTTP) && - ADD_EXTENSION_DEP("http", "propro", true) && ADD_EXTENSION_DEP("http", "raphf", true) && CHECK_LIB("winmm.lib", "http", PHP_HTTP)) { AC_DEFINE("PHP_HTTP_HAVE_LIBCURL", 1, "Have CURL library"); AC_DEFINE("PHP_HTTP_HAVE_SSL", 1, "Have SSL"); AC_DEFINE("PHP_HTTP_HAVE_LIBCURL_SSL", 1); AC_DEFINE("PHP_HTTP_HAVE_LIBCURL_OPENSSL", 1); - AC_DEFINE("PHP_HTTP_HAVE_EXT_PROPRO", 1, ""); AC_DEFINE("PHP_HTTP_HAVE_EXT_RAPHF", 1, ""); AC_DEFINE("PHP_HTTP_HAVE_CLIENT", 1, "Have HTTP client support"); AC_DEFINE("PHP_HAVE_CURL_MULTI_STRERROR", 1, ""); diff --git a/config9.m4 b/config9.m4 index 897b92f..35f1af1 100644 --- a/config9.m4 +++ b/config9.m4 @@ -25,25 +25,29 @@ if test "$PHP_HTTP" != "no"; then ]) AC_CHECK_FUNCS(mbrtowc mbtowc iswalnum inet_pton) + CFLAGS="$CFLAGS -Wno-strict-prototypes" + dnl ZLIB PHP_ARG_WITH([http-zlib-dir], [whether/where to check for zlib], - [ --with-http-zlib-dir[=DIR] HTTP: where to find zlib], $PHP_HTTP, no) + [ --with-http-zlib-dir[=DIR] HTTP: where to find zlib], $PHP_HTTP) 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) + [ --with-http-libbrotli-dir[=DIR] HTTP: where to find libbrotli], $PHP_HTTP) 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], - [ --with-http-libcurl-dir[=DIR] HTTP: where to find libcurl], $PHP_HTTP, no) + [ --with-http-libcurl-dir[=DIR] HTTP: where to find libcurl], $PHP_HTTP) if test "$PHP_HTTP_LIBCURL_DIR" != "no"; then PECL_CHECK_LIBCURL([$PHP_HTTP_LIBCURL_DIR], [7.18.2]) PECL_HAVE_LIBCURL_PROTOCOL([HTTP], [ PECL_HAVE_LIBCURL_FEATURE([HTTP2]) + PECL_HAVE_LIBCURL_FEATURE([ALT-SVC]) + PECL_HAVE_LIBCURL_FEATURE([HSTS]) PECL_HAVE_LIBCURL_ARES PECL_HAVE_LIBCURL_SSL PECL_HAVE_LIBCURL_CA @@ -76,7 +80,16 @@ if test "$PHP_HTTP" != "no"; then if test "$PHP_HTTP_LIBIDN_DIR" != "no"; then PECL_CHECK_PKGCONFIG(libidn, [$PHP_HTTP_LIBIDN_DIR]) if $PECL_VAR([HAVE_LIBIDN]); then - PECL_DEFINE([HAVE_IDNA2003]) + PECL_HAVE_VERSION(libidn, 1.36, [ + PECL_HAVE_VERSION(libidn, 1.39, [ + PECL_DEFINE([HAVE_IDNA2003]) + ], [ + PECL_VAR([HAVE_LIBIDN])=false + AC_MSG_WARN([libidn locale detection broken; disabling libidn support]) + ]) + ], [ + PECL_DEFINE([HAVE_IDNA2003]) + ]) fi PECL_CHECK_DONE(libidn, $PECL_VAR([HAVE_LIBIDN])) fi @@ -87,7 +100,11 @@ if test "$PHP_HTTP" != "no"; then if test "$PHP_HTTP_LIBICU_DIR" != "no"; then AC_PATH_PROG(ICU_CONFIG, icu-config, false, [$PHP_HTTP_LIBICU_DIR/bin:$PATH:/usr/local/bin]) - PECL_CHECK_CONFIG(libicu, [$ICU_CONFIG], [--version], [--cppflags], [--ldflags-searchpath], [--ldflags-libsonly]) + if $ICU_CONFIG --exists >/dev/null 2>/dev/null; then + PECL_CHECK_CONFIG(libicu, [$ICU_CONFIG], [--version], [--cppflags], [--ldflags-searchpath], [--ldflags-libsonly]) + else + PECL_CHECK_PKGCONFIG(icu-i18n, [$PHP_HTTP_LIBICU_DIR]) + fi AC_CACHE_CHECK([for uidna_IDNToASCII], PECL_CACHE_VAR([HAVE_UIDNA_IDNToASCII]), [ if printf "%s" "$CFLAGS" | $EGREP -q "(^|\s)-Werror\b"; then if ! printf "%s" "$CFLAGS" | $EGREP -q "(^|\s)-Wno-error=deprecated-declarations\b"; then @@ -161,12 +178,6 @@ if test "$PHP_HTTP" != "no"; then ], [ AC_MSG_ERROR([please install and enable pecl/raphf]) ]) - PECL_HAVE_PHP_EXT([propro], [ - PECL_HAVE_PHP_EXT_HEADER([propro]) - ], [ - AC_MSG_ERROR([please install and enable pecl/propro]) - ]) - PECL_HAVE_PHP_EXT([hash]) PECL_HAVE_PHP_EXT([iconv]) dnl DONE @@ -196,7 +207,6 @@ if test "$PHP_HTTP" != "no"; then fi fi PHP_ADD_EXTENSION_DEP([http], [raphf], true) - PHP_ADD_EXTENSION_DEP([http], [propro], true) PHP_SUBST(PECL_VAR([HEADERS])) PHP_SUBST(PECL_VAR([SOURCES])) diff --git a/package.xml b/package.xml index 866ba0c..5daf785 100644 --- a/package.xml +++ b/package.xml @@ -31,10 +31,10 @@ https://mdref.m6w6.name/http mike@php.net yes - 2019-10-29 + 2024-02-05 - 3.2.3 - 3.2.0 + 4.2.5 + 4.2.0 stable @@ -42,7 +42,8 @@ https://mdref.m6w6.name/http BSD-2-Clause @@ -250,6 +251,7 @@ https://mdref.m6w6.name/http + @@ -286,6 +288,7 @@ https://mdref.m6w6.name/http + @@ -305,7 +308,6 @@ https://mdref.m6w6.name/http - @@ -347,8 +349,6 @@ https://mdref.m6w6.name/http - - @@ -376,9 +376,11 @@ https://mdref.m6w6.name/http + - + + @@ -386,7 +388,7 @@ https://mdref.m6w6.name/http - 7.0.0 + 8.0.0 1.4.1 @@ -397,12 +399,6 @@ https://mdref.m6w6.name/http 2.0.0dev raphf - - propro - pecl.php.net - 2.0.0dev - propro - hash diff --git a/php_http.h b/php_http.h index 19d67f9..f8cede2 100644 --- a/php_http.h +++ b/php_http.h @@ -13,14 +13,14 @@ #ifndef PHP_EXT_HTTP_H #define PHP_EXT_HTTP_H -#define PHP_PECL_HTTP_VERSION "3.2.3" +#define PHP_PECL_HTTP_VERSION "4.2.5" extern zend_module_entry http_module_entry; #define phpext_http_ptr &http_module_entry extern int http_module_number; -#endif /* PHP_EXT_HTTP_H */ +#endif /* PHP_EXT_HTTP_H */ /* * Local variables: diff --git a/scripts/check_package-xml.php b/scripts/check_package-xml.php index e422c6a..4ff8e4a 100755 --- a/scripts/check_package-xml.php +++ b/scripts/check_package-xml.php @@ -33,7 +33,7 @@ if (($xml = simplexml_load_file($file))) { } } else { $base = basename($file); - if ($base{0} !== ".") { + if ($base[0] !== ".") { array_push($dirs, $file); } } diff --git a/scripts/ci b/scripts/ci new file mode 160000 index 0000000..547c8e8 --- /dev/null +++ b/scripts/ci @@ -0,0 +1 @@ +Subproject commit 547c8e89e38d6e899914c05ddf6598669bd16532 diff --git a/scripts/curlver.dist b/scripts/curlver.dist new file mode 100644 index 0000000..416cb07 --- /dev/null +++ b/scripts/curlver.dist @@ -0,0 +1,17 @@ +# current is 8.1.1 ATM +# 7.21.5-7.29.0 fail to configure on gh actions + +alpine: 8.1.1 7.78.0 +centos: 7.61.1 # 7.29.0 +debian: 7.88.1 7.74.0 +fedora: 7.87.0 7.85.0 +other: 7.49.1 7.31.0 +ubuntu: 7.81.0 7.74.0 + +# always test against a few recent +latest: master 8.1.1 8.0.1 7.88.1 7.81.0 +# and a couple ancient +oldest: 7.18.2 7.19.7 7.20.1 + +# 7.64.1 fails client tests because of superfluous infof() calls +# 7.64.0 fails client cookie test because of curl/curl#3613 diff --git a/scripts/gen_curlinfo.php b/scripts/gen_curlinfo.php index 9fae4cb..ab4391d 100755 --- a/scripts/gen_curlinfo.php +++ b/scripts/gen_curlinfo.php @@ -31,14 +31,20 @@ function file_re($file, $pattern, $all = true) { $ifdefs = array( 'PRIMARY_IP' => 'PHP_HTTP_CURL_VERSION(7,19,0)', 'APPCONNECT_TIME' => 'PHP_HTTP_CURL_VERSION(7,19,0)', - 'CONDITION_UNMET' => 'PHP_HTTP_CURL_VERSION(7,19,4)', - '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)', + 'CONDITION_UNMET' => 'PHP_HTTP_CURL_VERSION(7,19,4)', + '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)', '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)', + 'RETRY_AFTER' => 'PHP_HTTP_CURL_VERSION(7,66,0)', + 'EFFECTIVE_METHOD' => 'PHP_HTTP_CURL_VERSION(7,72,0)', + 'PROXY_ERROR' => 'PHP_HTTP_CURL_VERSION(7,73,0)', + 'REFERER' => 'PHP_HTTP_CURL_VERSION(7,76,0)', + 'CAINFO' => 'PHP_HTTP_CURL_VERSION(7,84,0)', + 'CAPATH' => 'PHP_HTTP_CURL_VERSION(7,84,0)', ); $exclude = array( 'ACTIVESOCKET', @@ -79,6 +85,12 @@ $templates = array( zend_hash_str_update(info, "%s", lenof("%2$s"), &tmp); } ', +'OFF_T' => +' if (CURLE_OK == curl_easy_getinfo(ch, %s, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "%s", lenof("%2$s"), &tmp); + } +', 'SLIST' => ' if (CURLE_OK == curl_easy_getinfo(ch, %s, &s)) { array_init(&tmp); @@ -93,8 +105,8 @@ $templates = array( ', ); -$infos = file_re('curl.h', '/^\s*(CURLINFO_(\w+))\s*=\s*CURLINFO_(STRING|LONG|DOUBLE|SLIST)\s*\+\s*\d+\s*,?\s*$/m'); - +$infos = file_re('curl.h', '/\s*(CURLINFO_(\w+))\s*(?:CURL_DEPRECATED\(\d+\.\d+\.\d+,\s*"[\w _-]+"\))?\s*=\s*CURLINFO_(STRING|LONG|DOUBLE|SLIST|OFF_T)\s*\+\s*\d+\s*,?\s*/m'); +var_dump($infos); ob_start(); foreach ($infos as $info) { list(, $full, $short, $type) = $info; diff --git a/scripts/gen_github_workflow_ci.php b/scripts/gen_github_workflow_ci.php new file mode 100755 index 0000000..41ce95f --- /dev/null +++ b/scripts/gen_github_workflow_ci.php @@ -0,0 +1,109 @@ +#!/usr/bin/env php + + +name: ci +on: + workflow_dispatch: + push: + pull_request: + +jobs: +github([ +"next" => [ + "PHP" => ["master"], + "enable_debug" => "yes", + "enable_zts" => "yes", + "enable_iconv" => "yes", + "TEST_PHP_ARGS" => "-d error_reporting=24575" // ignore E_DEPRECATED +], +"old" => [ + "PHP" => ["8.1", "8.0"], + "enable_debug" => "yes", + "enable_zts" => "yes", + "enable_iconv" => "yes", +], +"cur-none" => [ +// 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", + "with_http_libbrotli_dir" => "no", +], +"cur-dbg-zts" => [ +// everything enabled for current, switching debug/zts + "PHP" => $cur, + "enable_debug", + "enable_zts", + "enable_iconv" => "yes", +], +"cur-cov" => [ +// once everything enabled for current, with coverage + "CFLAGS" => "-O0 -g --coverage", + "CXXFLAGS" => "-O0 -g --coverage", + "PHP" => $cur, + "enable_iconv" => "yes", + [ + // mutually exclusive + "with_http_libicu_dir", + "with_http_libidn_dir", + "with_http_libidn2_dir", + ], +]]); +foreach ($job as $id => $env) { + printf(" %s:\n", $id); + printf(" name: \"%s (%s)\"\n", $id, $env["PHP"]); + if ($env["PHP"] == "master") { + printf(" continue-on-error: true\n"); + } + printf(" env:\n"); + foreach ($env as $key => $val) { + printf(" %s: \"%s\"\n", $key, $val); + } +?> + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Info + run: | + locale -a && locale + - name: Install + run: | + sudo apt-get install -y \ + php-cli \ + php-pear \ + libcurl4-openssl-dev \ + libidn-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Prepare + run: | + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + make -f scripts/ci/Makefile test + + - name: Coverage + if: success() + run: | + cd src/.libs + bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy + + + + +name: curl-matrix +on: + workflow_dispatch: + push: + +jobs: + 1) { + $curlver = array_map(fn($v) => strtr($v, ".", "_"), array_unique(array_slice($argv, 1))); +} else { + $curlver = array_unique( + iterator_to_array( + (function() { + $split = function($sep, $subject, $def = [""]) { + return array_filter(array_map("trim", explode($sep, $subject))) + $def; + }; + foreach (file(__DIR__."/curlver.dist") as $line) { + $rec = $split(":", $split("#", $line)[0]); + if (!empty($rec[1])) foreach ($split(" ", $rec[1], []) as $dist_ver) { + yield strtr($dist_ver, ".", "_"); + } + } + })() + ) + ); +} + +rsort($curlver, SORT_NATURAL); + +$gen = include __DIR__ . "/ci/gen-matrix.php"; +$job = $gen->github([ +"curl" => [ + "PHP" => "8.2", + "CURL" => $curlver, + "enable_debug" => "yes", + "enable_iconv" => "yes", + "with_http_libcurl_dir" => "/opt", +]]); +foreach ($job as $id => $env) { + printf(" curl-%s:\n", $env["CURL"]); + printf(" name: curl-%s\n", $env["CURL"]); + printf(" continue-on-error: true\n"); + printf(" env:\n"); + foreach ($env as $key => $val) { + printf(" %s: \"%s\"\n", $key, $val); + } +?> + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + path: http + - uses: actions/checkout@v2 + with: + repository: curl/curl + path: curl + + ref: curl- # + + - name: Install + run: | + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy main' | sudo tee -a /etc/apt/sources.list && \ + echo 'deb-src http://azure.archive.ubuntu.com/ubuntu jammy-updates main' | sudo tee -a /etc/apt/sources.list && \ + sudo apt-get update -y && \ + sudo apt-get build-dep -y libcurl4-openssl-dev && \ + sudo apt-get install -y \ + php-cli \ + php-pear \ + libidn11-dev \ + libidn2-0-dev \ + libicu-dev \ + libevent-dev \ + libbrotli-dev \ + re2c + - name: Curl + run: | + sudo chmod +x /usr/share/libtool/build-aux/ltmain.sh + sudo ln -s /usr/share/libtool/build-aux/ltmain.sh /usr/bin/libtool + cd curl + ./buildconf + ./configure --prefix=/opt --disable-dependency-tracking --with-ssl --with-openssl --without-libssh2 --disable-ldap + make -j2 + make install + - name: Prepare + run: | + cd http + make -f scripts/ci/Makefile php || make -f scripts/ci/Makefile clean php + make -f scripts/ci/Makefile pecl PECL=m6w6/ext-raphf.git:raphf:master + - name: Build + run: | + cd http + make -f scripts/ci/Makefile ext PECL=http + - name: Test + run: | + cd http + make -f scripts/ci/Makefile test + + ["7.0", "7.1", "7.2", "7.3", "master"], - "enable_debug" => "yes", - "enable_maintainer_zts" => "yes", - "enable_json" => "yes", - "enable_hash" => "yes", - "enable_iconv" => "yes", -], [ -// 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", - "with_http_libbrotli_dir" => "no", -], [ -// everything enabled for current, switching debug/zts - "PHP" => $cur, - "PECLs" => "event", // for tests/client029.phpt - "enable_sockets" => "yes", // needed by pecl/event - "enable_debug", - "enable_maintainer_zts", - "enable_json" => "yes", - "enable_hash" => "yes", - "enable_iconv" => "yes", -], [ -// once everything enabled for current, with coverage - "CFLAGS" => "'-O0 -g --coverage'", - "CXXFLAGS" => "'-O0 -g --coverage'", - "PHP" => $cur, - "PECLs" => "event", // for tests/client029.phpt - "enable_sockets" => "yes", // needed by pecl/event - "enable_json" => "yes", - "enable_hash" => "yes", - "enable_iconv" => "yes", - [ - "with_http_libicu_dir", - "with_http_libidn_dir", - "with_http_libidn2_dir", - ], -]); -foreach ($env as $grp) { - foreach ($grp as $e) { - printf(" - %s\n", $e); - } -} -?> - -matrix: - fast_finish: true - allow_failures: - - -install: - - | - 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 - - | - if test -n "$PECLs"; then \ - IFS=$','; \ - for pecl in $PECLs; do \ - make -f travis/pecl/Makefile pecl PECL=$pecl; \ - done; \ - unset IFS; \ - fi - -script: - - make -f travis/pecl/Makefile ext PECL=http - - make -f travis/pecl/Makefile test - -after_script: - - make -f travis/pecl/Makefile cppcheck -after_failure: - - test -e tests/helper/server.log && cat tests/helper/server.log -after_success: - - test -n "$CFLAGS" && cd src/.libs && bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy - -notifications: - webhooks: - urls: - - https://webhooks.gitter.im/e/28d35158ac7e385bd14d - on_success: change - on_failure: always - on_start: never diff --git a/src/php_http.c b/src/php_http.c index 498a224..8cf8126 100644 --- a/src/php_http.c +++ b/src/php_http.c @@ -58,7 +58,6 @@ PHP_MINFO_FUNCTION(http); static zend_module_dep http_module_deps[] = { ZEND_MOD_REQUIRED("raphf") - ZEND_MOD_REQUIRED("propro") ZEND_MOD_REQUIRED("spl") #if PHP_HTTP_HAVE_HASH ZEND_MOD_REQUIRED("hash") diff --git a/src/php_http_api.h b/src/php_http_api.h index bca57f1..a4058af 100644 --- a/src/php_http_api.h +++ b/src/php_http_api.h @@ -32,7 +32,6 @@ #include "SAPI.h" #include "ext/raphf/php_raphf_api.h" -#include "ext/propro/php_propro_api.h" #include "ext/standard/php_string.h" #include "ext/spl/spl_iterators.h" #include "ext/date/php_date.h" diff --git a/src/php_http_client.c b/src/php_http_client.c index 9551dd0..dcdfffa 100644 --- a/src/php_http_client.c +++ b/src/php_http_client.c @@ -74,7 +74,7 @@ void php_http_client_options_set_subr(zval *instance, char *key, size_t len, zva zval old_opts_tmp, *old_opts, new_opts, *entry = NULL; array_init(&new_opts); - old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); + old_opts = zend_read_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL(new_opts)); @@ -97,7 +97,7 @@ void php_http_client_options_set_subr(zval *instance, char *key, size_t len, zva } } - zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); + zend_update_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); } } @@ -112,7 +112,7 @@ void php_http_client_options_set(zval *instance, zval *opts) array_init(&new_opts); if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) { - zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); + zend_update_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); } else { zval old_opts_tmp, *old_opts, add_opts, *opt; @@ -125,9 +125,9 @@ void php_http_client_options_set(zval *instance, zval *opts) if (Z_TYPE_P(opt) == IS_ARRAY && (zend_string_equals_literal(key.key, "ssl") || zend_string_equals_literal(key.key, "cookies"))) { php_http_client_options_set_subr(instance, key.key->val, key.key->len, opt, 0); } else if (is_client && (zend_string_equals_literal(key.key, "recordHistory") || zend_string_equals_literal(key.key, "responseMessageClass"))) { - zend_update_property(this_ce, instance, key.key->val, key.key->len, opt); + zend_update_property(this_ce, Z_OBJ_P(instance), key.key->val, key.key->len, opt); } else if (Z_TYPE_P(opt) == IS_NULL) { - old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); + old_opts = zend_read_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { zend_symtable_del(Z_ARRVAL_P(old_opts), key.key); } @@ -139,12 +139,12 @@ void php_http_client_options_set(zval *instance, zval *opts) } ZEND_HASH_FOREACH_END(); - old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); + old_opts = zend_read_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL(new_opts)); } array_join(Z_ARRVAL(add_opts), Z_ARRVAL(new_opts), 0, 0); - zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); + zend_update_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); zval_ptr_dtor(&add_opts); } @@ -153,7 +153,7 @@ void php_http_client_options_set(zval *instance, zval *opts) void php_http_client_options_get_subr(zval *instance, char *key, size_t len, zval *return_value) { zend_class_entry *this_ce = Z_OBJCE_P(instance); - zval *options, opts_tmp, *opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &opts_tmp); + zval *options, opts_tmp, *opts = zend_read_property(this_ce, Z_OBJ_P(instance), ZEND_STRL("options"), 0, &opts_tmp); if ((Z_TYPE_P(opts) == IS_ARRAY) && (options = zend_symtable_str_find(Z_ARRVAL_P(opts), key, len))) { RETVAL_ZVAL(options, 1, 0); @@ -254,6 +254,20 @@ ZEND_RESULT_CODE php_http_client_dequeue(php_http_client_t *h, php_http_message_ return FAILURE; } +ZEND_RESULT_CODE php_http_client_requeue(php_http_client_t *h, php_http_message_t *request) +{ + if (h->ops->dequeue) { + php_http_client_enqueue_t *enqueue = php_http_client_enqueued(h, request, NULL); + + if (!enqueue) { + php_error_docref(NULL, E_WARNING, "Failed to requeue request; request not in queue"); + return FAILURE; + } + return h->ops->requeue(h, enqueue); + } + return FAILURE; +} + php_http_client_enqueue_t *php_http_client_enqueued(php_http_client_t *h, void *compare_arg, php_http_client_enqueue_cmp_func_t compare_func) { zend_llist_element *el = NULL; @@ -367,11 +381,11 @@ zend_object *php_http_client_object_new(zend_class_entry *ce) return &php_http_client_object_new_ex(ce, NULL)->zo; } -static HashTable *php_http_client_object_get_gc(zval *object, zval **table, int *n) +static HashTable *php_http_client_object_get_gc(zend_object *object, zval **table, int *n) { - php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, object); + php_http_client_object_t *obj = PHP_HTTP_OBJ(object, NULL); zend_llist_element *el = NULL; - HashTable *props = Z_OBJPROP_P(object); + HashTable *props = object->handlers->get_properties(object); uint32_t count = zend_hash_num_elements(props) + zend_llist_count(&obj->client->responses) + zend_llist_count(&obj->client->requests) + 2; zval *val; @@ -417,7 +431,7 @@ static HashTable *php_http_client_object_get_gc(zval *object, zval **table, int static void handle_history(zval *zclient, php_http_message_t *request, php_http_message_t *response) { - zval new_hist, old_hist_tmp, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0, &old_hist_tmp); + zval new_hist, old_hist_tmp, *old_hist = zend_read_property(php_http_client_class_entry, Z_OBJ_P(zclient), ZEND_STRL("history"), 0, &old_hist_tmp); php_http_message_t *req_copy = php_http_message_copy(request, NULL); php_http_message_t *res_copy = php_http_message_copy(response, NULL); php_http_message_t *zipped = php_http_message_zip(res_copy, req_copy); @@ -429,7 +443,7 @@ static void handle_history(zval *zclient, php_http_message_t *request, php_http_ php_http_message_object_prepend(&new_hist, old_hist, 1); } - zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), &new_hist); + zend_update_property(php_http_client_class_entry, Z_OBJ_P(zclient), ZEND_STRL("history"), &new_hist); zval_ptr_dtor(&new_hist); } @@ -450,7 +464,7 @@ static ZEND_RESULT_CODE handle_response(void *arg, php_http_client_t *client, ph /* ensure the message is of type response (could be uninitialized in case of early error, like DNS) */ php_http_message_set_type(msg, PHP_HTTP_RESPONSE); - if (zend_is_true(zend_read_property(php_http_client_class_entry, &zclient, ZEND_STRL("recordHistory"), 0, &rec_hist_tmp))) { + if (zend_is_true(zend_read_property(php_http_client_class_entry, Z_OBJ(zclient), ZEND_STRL("recordHistory"), 0, &rec_hist_tmp))) { handle_history(&zclient, e->request, *response); } @@ -467,7 +481,7 @@ static ZEND_RESULT_CODE handle_response(void *arg, php_http_client_t *client, ph object_init(&info); info_ht = HASH_OF(&info); php_http_client_getopt(client, PHP_HTTP_CLIENT_OPT_TRANSFER_INFO, e->request, &info_ht); - zend_update_property(php_http_get_client_response_class_entry(), &zresponse, ZEND_STRL("transferInfo"), &info); + zend_update_property(php_http_get_client_response_class_entry(), Z_OBJ(zresponse), ZEND_STRL("transferInfo"), &info); zval_ptr_dtor(&info); zend_llist_add_element(&client->responses, &msg_obj); @@ -548,12 +562,11 @@ static void handle_debug(void *arg, php_http_client_t *client, php_http_client_e ZVAL_STRINGL(&zdata, data, size); zend_replace_error_handling(EH_NORMAL, NULL, &zeh); - if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci, 4, &zclient, &zreq, &ztype, &zdata)) { - ++client->callback.depth; - zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); - --client->callback.depth; - zend_fcall_info_args_clear(&client_obj->debug.fci, 0); - } + zend_fcall_info_argn(&client_obj->debug.fci, 4, &zclient, &zreq, &ztype, &zdata); + ++client->callback.depth; + zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); + --client->callback.depth; + zend_fcall_info_args_clear(&client_obj->debug.fci, 0); zend_restore_error_handling(&zeh); zval_ptr_dtor(&zclient); @@ -593,7 +606,7 @@ static PHP_METHOD(HttpClient, __construct) } object_init_ex(&os, spl_ce_SplObjectStorage); - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), &os); + zend_update_property(php_http_client_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("observers"), &os); zval_ptr_dtor(&os); if (persistent_handle_name) { @@ -633,25 +646,28 @@ static PHP_METHOD(HttpClient, reset) RETVAL_ZVAL(getThis(), 1, 0); } -static HashTable *combined_options(zval *client, zval *request) +static HashTable *combined_options(HashTable *options, zval *client, zval *request) { - HashTable *options; unsigned num_options = 0; - zval z_roptions, z_options_tmp, *z_coptions = zend_read_property(php_http_client_class_entry, client, ZEND_STRL("options"), 0, &z_options_tmp); + zval z_roptions, z_options_tmp, *z_coptions = zend_read_property(php_http_client_class_entry, Z_OBJ_P(client), ZEND_STRL("options"), 0, &z_options_tmp); if (Z_TYPE_P(z_coptions) == IS_ARRAY) { num_options = zend_hash_num_elements(Z_ARRVAL_P(z_coptions)); } ZVAL_UNDEF(&z_roptions); - zend_call_method_with_0_params(request, NULL, NULL, "getOptions", &z_roptions); + zend_call_method_with_0_params(Z_OBJ_P(request), NULL, NULL, "getOptions", &z_roptions); if (Z_TYPE(z_roptions) == IS_ARRAY) { unsigned num = zend_hash_num_elements(Z_ARRVAL(z_roptions)); if (num > num_options) { num_options = num; } } - ALLOC_HASHTABLE(options); - ZEND_INIT_SYMTABLE_EX(options, num_options, 0); + if (options) { + zend_hash_clean(options); + } else { + ALLOC_HASHTABLE(options); + ZEND_INIT_SYMTABLE_EX(options, num_options, 0); + } if (Z_TYPE_P(z_coptions) == IS_ARRAY) { array_copy(Z_ARRVAL_P(z_coptions), options); } @@ -714,7 +730,7 @@ static PHP_METHOD(HttpClient, enqueue) Z_ADDREF_P(request); q.request = msg_obj->message; - q.options = combined_options(getThis(), request); + q.options = combined_options(NULL, getThis(), request); q.dtor = msg_queue_dtor; q.opaque = msg_obj; q.closure.fci = fci; @@ -770,19 +786,35 @@ static PHP_METHOD(HttpClient, requeue) 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, *e; 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); obj = PHP_HTTP_OBJ(NULL, getThis()); msg_obj = PHP_HTTP_OBJ(NULL, request); - if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { - php_http_expect(SUCCESS == php_http_client_dequeue(obj->client, msg_obj->message), runtime, return); + if ((e = php_http_client_enqueued(obj->client, msg_obj->message, NULL))) { + combined_options(e->options, getThis(), request); + php_http_expect(SUCCESS == php_http_client_requeue(obj->client, msg_obj->message), runtime, return); + if (fci.size) { + if (e->closure.fci.size) { + zval_ptr_dtor(&e->closure.fci.function_name); + if (e->closure.fci.object) { + zend_object_release(e->closure.fci.object); + } + } + Z_TRY_ADDREF(fci.function_name); + if (fci.object) { + GC_ADDREF(fci.object); + } + e->closure.fci = fci; + e->closure.fcc = fcc; + } + RETURN_ZVAL(getThis(), 1, 0); } q.request = msg_obj->message; - q.options = combined_options(getThis(), request); + q.options = combined_options(NULL, getThis(), request); q.dtor = msg_queue_dtor; q.opaque = msg_obj; q.closure.fci = fci; @@ -805,7 +837,7 @@ static PHP_METHOD(HttpClient, requeue) RETVAL_ZVAL(getThis(), 1, 0); } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_count, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpClient_count, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, count) { @@ -868,7 +900,7 @@ static PHP_METHOD(HttpClient, getHistory) php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - zhistory = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("history"), 0, &zhistory_tmp); + zhistory = zend_read_property(php_http_client_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("history"), 0, &zhistory_tmp); RETVAL_ZVAL(zhistory, 1, 0); } @@ -985,7 +1017,11 @@ static int notify(zend_object_iterator *iter, void *puser) return ZEND_HASH_APPLY_STOP; } +#if PHP_VERSION_ID >= 80100 +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpClient_notify, 0, 0, IS_VOID, 0) +#else ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_notify, 0, 0, 0) +#endif ZEND_ARG_OBJ_INFO(0, request, http\\Client\\Request, 1) ZEND_ARG_INFO(0, progress) ZEND_END_ARG_INFO(); @@ -998,7 +1034,7 @@ static PHP_METHOD(HttpClient, notify) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|O!o!", &request, php_http_get_client_request_class_entry(), &zprogress), invalid_arg, return); client_obj = PHP_HTTP_OBJ(NULL, getThis()); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); + observers = zend_read_property(php_http_client_class_entry, &client_obj->zo, ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted"); @@ -1029,11 +1065,16 @@ static PHP_METHOD(HttpClient, notify) zval_ptr_dtor(zprogress); } } - +#if PHP_VERSION_ID < 80100 RETVAL_ZVAL(getThis(), 1, 0); +#endif } +#if PHP_VERSION_ID >= 80100 +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpClient_attach, 0, 1, IS_VOID, 0) +#else ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_attach, 0, 0, 1) +#endif ZEND_ARG_OBJ_INFO(0, observer, SplObserver, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, attach) @@ -1044,7 +1085,7 @@ static PHP_METHOD(HttpClient, attach) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &observer, spl_ce_SplObserver), invalid_arg, return); client_obj = PHP_HTTP_OBJ(NULL, getThis()); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); + observers = zend_read_property(php_http_client_class_entry, &client_obj->zo, ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted"); @@ -1056,13 +1097,18 @@ static PHP_METHOD(HttpClient, attach) } ZVAL_UNDEF(&retval); - zend_call_method_with_1_params(observers, NULL, NULL, "attach", &retval, observer); + zend_call_method_with_1_params(Z_OBJ_P(observers), NULL, NULL, "attach", &retval, observer); zval_ptr_dtor(&retval); - +#if PHP_VERSION_ID < 80100 RETVAL_ZVAL(getThis(), 1, 0); +#endif } +#if PHP_VERSION_ID >= 80100 +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpClient_detach, 0, 1, IS_VOID, 0) +#else ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_detach, 0, 0, 1) +#endif ZEND_ARG_OBJ_INFO(0, observer, SplObserver, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, detach) @@ -1071,7 +1117,7 @@ static PHP_METHOD(HttpClient, detach) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &observer, spl_ce_SplObserver), invalid_arg, return); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); + observers = zend_read_property(php_http_client_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted"); @@ -1079,10 +1125,11 @@ static PHP_METHOD(HttpClient, detach) } ZVAL_UNDEF(&retval); - zend_call_method_with_1_params(observers, NULL, NULL, "detach", &retval, observer); + zend_call_method_with_1_params(Z_OBJ_P(observers), NULL, NULL, "detach", &retval, observer); zval_ptr_dtor(&retval); - +#if PHP_VERSION_ID < 80100 RETVAL_ZVAL(getThis(), 1, 0); +#endif } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getObservers, 0, 0, 0) @@ -1093,7 +1140,7 @@ static PHP_METHOD(HttpClient, getObservers) php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); + observers = zend_read_property(php_http_client_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted"); @@ -1169,7 +1216,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getOptions) { if (SUCCESS == zend_parse_parameters_none()) { - zval options_tmp, *options = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0, &options_tmp); + zval options_tmp, *options = zend_read_property(php_http_client_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("options"), 0, &options_tmp); RETVAL_ZVAL(options, 1, 0); } } @@ -1358,7 +1405,7 @@ PHP_MINIT_FUNCTION(http_client) INIT_NS_CLASS_ENTRY(ce, "http", "Client", php_http_client_methods); php_http_client_class_entry = zend_register_internal_class_ex(&ce, NULL); php_http_client_class_entry->create_object = php_http_client_object_new; - zend_class_implements(php_http_client_class_entry, 2, spl_ce_SplSubject, spl_ce_Countable); + zend_class_implements(php_http_client_class_entry, 2, spl_ce_SplSubject, zend_ce_countable); memcpy(&php_http_client_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_http_client_object_handlers.offset = XtOffsetOf(php_http_client_object_t, zo); php_http_client_object_handlers.free_obj = php_http_client_object_free; diff --git a/src/php_http_client.h b/src/php_http_client.h index fd77204..da53b4d 100644 --- a/src/php_http_client.h +++ b/src/php_http_client.h @@ -47,6 +47,7 @@ typedef int (*php_http_client_once_func_t)(struct php_http_client *p); typedef ZEND_RESULT_CODE (*php_http_client_wait_func_t)(struct php_http_client *p, struct timeval *custom_timeout); typedef ZEND_RESULT_CODE (*php_http_client_enqueue_func_t)(struct php_http_client *p, php_http_client_enqueue_t *enqueue); typedef ZEND_RESULT_CODE (*php_http_client_dequeue_func_t)(struct php_http_client *p, php_http_client_enqueue_t *enqueue); +typedef ZEND_RESULT_CODE (*php_http_client_requeue_func_t)(struct php_http_client *p, php_http_client_enqueue_t *enqueue); typedef ZEND_RESULT_CODE (*php_http_client_setopt_func_t)(struct php_http_client *p, php_http_client_setopt_opt_t opt, void *arg); typedef ZEND_RESULT_CODE (*php_http_client_getopt_func_t)(struct php_http_client *h, php_http_client_getopt_opt_t opt, void *arg, void **res); @@ -61,6 +62,7 @@ typedef struct php_http_client_ops { php_http_client_once_func_t once; php_http_client_enqueue_func_t enqueue; php_http_client_dequeue_func_t dequeue; + php_http_client_requeue_func_t requeue; php_http_client_setopt_func_t setopt; php_http_client_getopt_func_t getopt; } php_http_client_ops_t; diff --git a/src/php_http_client_curl.c b/src/php_http_client_curl.c index 94cdf47..4decc7a 100644 --- a/src/php_http_client_curl.c +++ b/src/php_http_client_curl.c @@ -17,6 +17,8 @@ #if PHP_HTTP_HAVE_LIBCURL +#define DEBUG_COOKIES 0 + #if PHP_HTTP_HAVE_LIBCURL_OPENSSL # include #endif @@ -311,14 +313,14 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data, return 0; } -static int php_http_curle_header_callback(char *data, size_t n, size_t l, void *arg) +static size_t php_http_curle_header_callback(char *data, size_t n, size_t l, void *arg) { php_http_client_curl_handler_t *h = arg; return php_http_buffer_append(&h->response.headers, data, n * l); } -static int php_http_curle_body_callback(char *data, size_t n, size_t l, void *arg) +static size_t php_http_curle_body_callback(char *data, size_t n, size_t l, void *arg) { php_http_client_curl_handler_t *h = arg; @@ -330,8 +332,11 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) char *c = NULL; long l = 0; double d = 0; + curl_off_t o = 0; struct curl_slist *s = NULL, *p = NULL; - zval tmp = {{0}}; + zval tmp; + + ZVAL_NULL(&tmp); /* BEGIN::CURLINFO */ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_EFFECTIVE_URL, &c)) { @@ -362,18 +367,34 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "size_upload", lenof("size_upload"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SIZE_UPLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "size_upload_t", lenof("size_upload_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SIZE_DOWNLOAD, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "size_download", lenof("size_download"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SIZE_DOWNLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "size_download_t", lenof("size_download_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_DOWNLOAD, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "speed_download", lenof("speed_download"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_DOWNLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "speed_download_t", lenof("speed_download_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_UPLOAD, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "speed_upload", lenof("speed_upload"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_UPLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "speed_upload_t", lenof("speed_upload_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_HEADER_SIZE, &l)) { ZVAL_LONG(&tmp, l); zend_hash_str_update(info, "header_size", lenof("header_size"), &tmp); @@ -390,14 +411,26 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) ZVAL_LONG(&tmp, l); zend_hash_str_update(info, "filetime", lenof("filetime"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_FILETIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "filetime_t", lenof("filetime_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "content_length_download", lenof("content_length_download"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "content_length_download_t", lenof("content_length_download_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_UPLOAD, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "content_length_upload", lenof("content_length_upload"), &tmp); } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "content_length_upload_t", lenof("content_length_upload_t"), &tmp); + } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_STARTTRANSFER_TIME, &d)) { ZVAL_DOUBLE(&tmp, d); zend_hash_str_update(info, "starttransfer_time", lenof("starttransfer_time"), &tmp); @@ -508,6 +541,70 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) zend_hash_str_update(info, "scheme", lenof("scheme"), &tmp); } #endif + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TOTAL_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "total_time_t", lenof("total_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_NAMELOOKUP_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "namelookup_time_t", lenof("namelookup_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONNECT_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "connect_time_t", lenof("connect_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PRETRANSFER_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "pretransfer_time_t", lenof("pretransfer_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_STARTTRANSFER_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "starttransfer_time_t", lenof("starttransfer_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REDIRECT_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "redirect_time_t", lenof("redirect_time_t"), &tmp); + } + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_APPCONNECT_TIME_T, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "appconnect_time_t", lenof("appconnect_time_t"), &tmp); + } +#if PHP_HTTP_CURL_VERSION(7,66,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_RETRY_AFTER, &o)) { + ZVAL_LONG(&tmp, o); + zend_hash_str_update(info, "retry_after", lenof("retry_after"), &tmp); + } +#endif +#if PHP_HTTP_CURL_VERSION(7,72,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_EFFECTIVE_METHOD, &c)) { + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "effective_method", lenof("effective_method"), &tmp); + } +#endif +#if PHP_HTTP_CURL_VERSION(7,73,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROXY_ERROR, &l)) { + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "proxy_error", lenof("proxy_error"), &tmp); + } +#endif +#if PHP_HTTP_CURL_VERSION(7,76,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REFERER, &c)) { + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "referer", lenof("referer"), &tmp); + } +#endif +#if PHP_HTTP_CURL_VERSION(7,84,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CAINFO, &c)) { + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "cainfo", lenof("cainfo"), &tmp); + } +#endif +#if PHP_HTTP_CURL_VERSION(7,84,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CAPATH, &c)) { + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "capath", lenof("capath"), &tmp); + } +#endif /* END::CURLINFO */ @@ -607,8 +704,9 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) #if (PHP_HTTP_CURL_VERSION(7,19,1) && PHP_HTTP_HAVE_LIBCURL_OPENSSL) || \ (PHP_HTTP_CURL_VERSION(7,34,0) && PHP_HTTP_HAVE_LIBCURL_NSS) || \ + (PHP_HTTP_CURL_VERSION(7,39,0) && PHP_HTTP_HAVE_LIBCURL_GSKIT) || \ (PHP_HTTP_CURL_VERSION(7,42,0) && PHP_HTTP_HAVE_LIBCURL_GNUTLS) || \ - (PHP_HTTP_CURL_VERSION(7,39,0) && PHP_HTTP_HAVE_LIBCURL_GSKIT) + (PHP_HTTP_CURL_VERSION(7,79,0) && PHP_HTTP_HAVE_LIBCURL_SECURETRANSPORT) { int i; zval ci_array, subarray; @@ -791,13 +889,14 @@ static php_http_options_t php_http_curle_options, php_http_curlm_options; #define PHP_HTTP_CURLE_OPTION_CHECK_STRLEN 0x0001 #define PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR 0x0002 #define PHP_HTTP_CURLE_OPTION_TRANSFORM_MS 0x0004 +#define PHP_HTTP_CURLE_OPTION_IGNORE_RC 0x0008 static ZEND_RESULT_CODE php_http_curle_option_set_ssl_verifyhost(php_http_option_t *opt, zval *val, void *userdata) { php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, Z_TYPE_P(val) == IS_TRUE ? 2 : 0)) { + if (CURLE_OK != curl_easy_setopt(ch, opt->option, Z_TYPE_P(val) == IS_TRUE ? 2 : 0)) { return FAILURE; } return SUCCESS; @@ -812,6 +911,9 @@ static ZEND_RESULT_CODE php_http_curle_option_set_cookiesession(php_http_option_ return FAILURE; } if (Z_TYPE_P(val) == IS_TRUE) { +#if DEBUG_COOKIES + fprintf(stderr, "CURLOPT_COOKIELIST: SESS\n"); +#endif if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIELIST, "SESS")) { return FAILURE; } @@ -834,9 +936,19 @@ static ZEND_RESULT_CODE php_http_curle_option_set_cookiestore(php_http_option_t } else { storage->cookiestore = NULL; } - if ( CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEFILE, storage->cookiestore) - || CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEJAR, storage->cookiestore) - ) { + +#if DEBUG_COOKIES + fprintf(stderr, "CURLOPT_COOKIEFILE: %s\n", storage->cookiestore); +#endif + // does NOT enable ch->data.cookies until transfer; adds to ch->stsate.cookielist + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEFILE, storage->cookiestore ? storage->cookiestore : "")) { + return FAILURE; + } +#if DEBUG_COOKIES + fprintf(stderr, "CURLOPT_COOKIEJAR: %s\n", storage->cookiestore); +#endif + // enables ch->data.cookies + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIEJAR, storage->cookiestore)) { return FAILURE; } @@ -928,6 +1040,21 @@ static ZEND_RESULT_CODE php_http_curle_option_set_lastmodified(php_http_option_t return SUCCESS; } +#if PHP_HTTP_CURL_VERSION(7,64,1) +static ZEND_RESULT_CODE php_http_curle_option_set_altsvc_ctrl(php_http_option_t *opt, zval *val, void *userdata) +{ + php_http_client_curl_handler_t *curl = userdata; + CURL *ch = curl->handle; + + if (Z_LVAL_P(val)) { + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_ALTSVC_CTRL, Z_LVAL_P(val))) { + return FAILURE; + } + } + return SUCCESS; +} +#endif + static ZEND_RESULT_CODE php_http_curle_option_set_compress(php_http_option_t *opt, zval *val, void *userdata) { php_http_client_curl_handler_t *curl = userdata; @@ -1150,8 +1277,10 @@ static ZEND_RESULT_CODE php_http_curle_option_set_ssl_tlsauthtype(php_http_optio if (val && Z_LVAL_P(val)) { switch (Z_LVAL_P(val)) { + case CURL_TLSAUTH_NONE: + break; case CURL_TLSAUTH_SRP: - if (CURLE_OK == curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_SRP)) { + if (CURLE_OK == curl_easy_setopt(ch, opt->option, "SRP")) { return SUCCESS; } /* no break */ @@ -1159,7 +1288,7 @@ static ZEND_RESULT_CODE php_http_curle_option_set_ssl_tlsauthtype(php_http_optio return FAILURE; } } - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_DEF)) { + if (CURLE_OK != curl_easy_setopt(ch, opt->option, "NONE")) { return FAILURE; } return SUCCESS; @@ -1189,6 +1318,9 @@ static void php_http_curle_options_init(php_http_options_t *registry) #if PHP_HTTP_CURL_VERSION(7,19,4) php_http_option_register(registry, ZEND_STRL("noproxy"), CURLOPT_NOPROXY, IS_STRING); #endif +#if PHP_HTTP_CURL_VERSION(7,55,0) + php_http_option_register(registry, ZEND_STRL("socks5_auth"), CURLOPT_SOCKS5_AUTH, IS_LONG); +#endif #if PHP_HTTP_CURL_VERSION(7,37,0) if ((opt = php_http_option_register(registry, ZEND_STRL("proxyheader"), CURLOPT_PROXYHEADER, IS_ARRAY))) { @@ -1202,13 +1334,22 @@ static void php_http_curle_options_init(php_http_options_t *registry) opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } #endif +#if PHP_HTTP_CURL_VERSION(7,60,0) + php_http_option_register(registry, ZEND_STRL("haproxy_protocol"), CURLOPT_HAPROXYPROTOCOL, _IS_BOOL); +#endif + /* unix sockets */ #if PHP_HTTP_CURL_VERSION(7,40,0) if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_UNIX_SOCKETS)) { if ((opt = php_http_option_register(registry, ZEND_STRL("unix_socket_path"), CURLOPT_UNIX_SOCKET_PATH, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } +#if PHP_HTTP_CURL_VERSION(7,53,0) + if ((opt = php_http_option_register(registry, ZEND_STRL("abstract_unix_socket"), CURLOPT_ABSTRACT_UNIX_SOCKET, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } +#endif } #endif @@ -1240,6 +1381,13 @@ static void php_http_curle_options_init(php_http_options_t *registry) } # endif #endif +#if PHP_HTTP_CURL_VERSION(7,60,0) + php_http_option_register(registry, ZEND_STRL("dns_shuffle_addresses"), CURLOPT_DNS_SHUFFLE_ADDRESSES, _IS_BOOL); +#endif +#if PHP_HTTP_CURL_VERSION(7,62,0) + php_http_option_register(registry, ZEND_STRL("doh_url"), CURLOPT_DOH_URL, IS_STRING); +#endif + /* limits */ php_http_option_register(registry, ZEND_STRL("low_speed_limit"), CURLOPT_LOW_SPEED_LIMIT, IS_LONG); @@ -1258,6 +1406,11 @@ static void php_http_curle_options_init(php_http_options_t *registry) */ php_http_option_register(registry, ZEND_STRL("fresh_connect"), CURLOPT_FRESH_CONNECT, _IS_BOOL); php_http_option_register(registry, ZEND_STRL("forbid_reuse"), CURLOPT_FORBID_REUSE, _IS_BOOL); +#if PHP_HTTP_CURL_VERSION(7,65,0) + if ((opt = php_http_option_register(registry, ZEND_STRL("maxage_conn"), CURLOPT_MAXAGE_CONN, IS_LONG))) { + ZVAL_LONG(&opt->defval, 118); + } +#endif /* outgoing interface */ php_http_option_register(registry, ZEND_STRL("interface"), CURLOPT_INTERFACE, IS_STRING); @@ -1286,6 +1439,14 @@ static void php_http_curle_options_init(php_http_options_t *registry) opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } #endif +#if PHP_HTTP_CURL_VERSION(7,61,0) + if ((opt = php_http_option_register(registry, ZEND_STRL("xoauth2_bearer"), CURLOPT_XOAUTH2_BEARER, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } +#endif +#if PHP_HTTP_CURL_VERSION(7,75,0) + php_http_option_register(registry, ZEND_STRL("aws_sigv4"), CURLOPT_AWS_SIGV4, IS_STRING); +#endif /* redirects */ if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) { @@ -1371,6 +1532,9 @@ static void php_http_curle_options_init(php_http_options_t *registry) /* http protocol version */ php_http_option_register(registry, ZEND_STRL("protocol"), CURLOPT_HTTP_VERSION, IS_LONG); +#if PHP_HTTP_CURL_VERSION(7,64,0) + php_http_option_register(registry, ZEND_STRL("http09_allowed"), CURLOPT_HTTP09_ALLOWED, _IS_BOOL); +#endif /* timeouts */ if ((opt = php_http_option_register(registry, ZEND_STRL("timeout"), CURLOPT_TIMEOUT_MS, IS_DOUBLE))) { @@ -1397,119 +1561,251 @@ static void php_http_curle_options_init(php_http_options_t *registry) if ((opt = php_http_option_register(registry, ZEND_STRL("tcp_keepintvl"), CURLOPT_TCP_KEEPINTVL, IS_LONG))) { Z_LVAL(opt->defval) = 60; } +#endif +#if PHP_HTTP_CURL_VERSION(7,49,0) +# if defined(linux) || defined(__APPLE__) + /* CURLOPT_TCP_FASTOPEN is not supported (yet) on Windows */ + php_http_option_register(registry, ZEND_STRL("tcp_fastopen"), CURLOPT_TCP_FASTOPEN, _IS_BOOL); +# endif #endif /* ssl */ if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_SSL)) { - if ((opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) { - registry = &opt->suboptions; + php_http_option_t *ssl_opt, *proxy_opt; - if ((opt = php_http_option_register(registry, ZEND_STRL("cert"), CURLOPT_SSLCERT, IS_STRING))) { + if ((ssl_opt = php_http_option_register(registry, ZEND_STRL("ssl"), 0, IS_ARRAY))) { + php_http_options_t *ssl_registry = &ssl_opt->suboptions; + + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("cert"), CURLOPT_SSLCERT, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } - if ((opt = php_http_option_register(registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; ZVAL_PSTRING(&opt->defval, "PEM"); } - if ((opt = php_http_option_register(registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } - if ((opt = php_http_option_register(registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; ZVAL_PSTRING(&opt->defval, "PEM"); } - if ((opt = php_http_option_register(registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } - php_http_option_register(registry, ZEND_STRL("engine"), CURLOPT_SSLENGINE, IS_STRING); - php_http_option_register(registry, ZEND_STRL("version"), CURLOPT_SSLVERSION, IS_LONG); - if ((opt = php_http_option_register(registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, _IS_BOOL))) { + php_http_option_register(ssl_registry, ZEND_STRL("engine"), CURLOPT_SSLENGINE, IS_STRING); + php_http_option_register(ssl_registry, ZEND_STRL("version"), CURLOPT_SSLVERSION, IS_LONG); + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } - if ((opt = php_http_option_register(registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, _IS_BOOL))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); opt->setter = php_http_curle_option_set_ssl_verifyhost; } #if PHP_HTTP_CURL_VERSION(7,41,0) && (PHP_HTTP_HAVE_LIBCURL_OPENSSL || PHP_HTTP_HAVE_LIBCURL_NSS || PHP_HTTP_HAVE_LIBCURL_GNUTLS) - php_http_option_register(registry, ZEND_STRL("verifystatus"), CURLOPT_SSL_VERIFYSTATUS, _IS_BOOL); + php_http_option_register(ssl_registry, ZEND_STRL("verifystatus"), CURLOPT_SSL_VERIFYSTATUS, _IS_BOOL); #endif - php_http_option_register(registry, ZEND_STRL("cipher_list"), CURLOPT_SSL_CIPHER_LIST, IS_STRING); + php_http_option_register(ssl_registry, ZEND_STRL("cipher_list"), CURLOPT_SSL_CIPHER_LIST, IS_STRING); #if PHP_HTTP_HAVE_LIBCURL_CAINFO - if ((opt = php_http_option_register(registry, ZEND_STRL("cainfo"), CURLOPT_CAINFO, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("cainfo"), CURLOPT_CAINFO, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; -#ifdef PHP_HTTP_CAINFO - ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAINFO); -#endif +# ifdef PHP_HTTP_CAINFO + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAINFO); +# endif } #endif #if PHP_HTTP_HAVE_LIBCURL_CAPATH - if ((opt = php_http_option_register(registry, ZEND_STRL("capath"), CURLOPT_CAPATH, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("capath"), CURLOPT_CAPATH, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; -#ifdef PHP_HTTP_CAPATH - ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH); -#endif +# ifdef PHP_HTTP_CAPATH + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH); +# endif } #endif - if ((opt = php_http_option_register(registry, ZEND_STRL("random_file"), CURLOPT_RANDOM_FILE, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("random_file"), CURLOPT_RANDOM_FILE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } - if ((opt = php_http_option_register(registry, ZEND_STRL("egdsocket"), CURLOPT_EGDSOCKET, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("egdsocket"), CURLOPT_EGDSOCKET, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } #if PHP_HTTP_CURL_VERSION(7,19,0) - if ((opt = php_http_option_register(registry, ZEND_STRL("issuercert"), CURLOPT_ISSUERCERT, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("issuercert"), CURLOPT_ISSUERCERT, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } # if PHP_HTTP_HAVE_LIBCURL_OPENSSL - if ((opt = php_http_option_register(registry, ZEND_STRL("crlfile"), CURLOPT_CRLFILE, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("crlfile"), CURLOPT_CRLFILE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } # endif #endif #if (PHP_HTTP_CURL_VERSION(7,19,1) && PHP_HTTP_HAVE_LIBCURL_OPENSSL) || (PHP_HTTP_CURL_VERSION(7,34,0) && PHP_HTTP_HAVE_LIBCURL_NSS) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_LIBCURL_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_LIBCURL_GSKIT)) - if ((opt = php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) { ZVAL_FALSE(&opt->defval); } #endif #if PHP_HTTP_CURL_VERSION(7,36,0) - if ((opt = php_http_option_register(registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } - if ((opt = php_http_option_register(registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } #endif #if PHP_HTTP_CURL_VERSION(7,39,0) /* FIXME: see http://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html#AVAILABILITY */ - if ((opt = php_http_option_register(registry, ZEND_STRL("pinned_publickey"), CURLOPT_PINNEDPUBLICKEY, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("pinned_publickey"), CURLOPT_PINNEDPUBLICKEY, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; } #endif #if PHP_HTTP_CURL_VERSION(7,21,4) && PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE - if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthtype"), CURLOPT_TLSAUTH_TYPE, IS_LONG))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthtype"), CURLOPT_TLSAUTH_TYPE, IS_LONG))) { opt->setter = php_http_curle_option_set_ssl_tlsauthtype; } - if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthuser"), CURLOPT_TLSAUTH_USERNAME, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthuser"), CURLOPT_TLSAUTH_USERNAME, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } - if ((opt = php_http_option_register(registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) { + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tlsauthpass"), CURLOPT_TLSAUTH_PASSWORD, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } #endif #if PHP_HTTP_CURL_VERSION(7,42,0) && (PHP_HTTP_HAVE_LIBCURL_NSS || PHP_HTTP_HAVE_LIBCURL_SECURETRANSPORT) - php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL); + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_IGNORE_RC; + } #endif +#if PHP_HTTP_CURL_VERSION(7,61,0) && PHP_HTTP_HAVE_LIBCURL_TLS13_CIPHERS + if ((opt = php_http_option_register(ssl_registry, ZEND_STRL("tls13_ciphers"), CURLOPT_TLS13_CIPHERS, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } +#endif + } + +#if PHP_HTTP_CURL_VERSION(7,52,0) + /* proxy_ssl */ + if ((proxy_opt = php_http_option_register(registry, ZEND_STRL("proxy_ssl"), 0, IS_ARRAY))) { + php_http_options_t *proxy_registry = &proxy_opt->suboptions; + + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("cert"), CURLOPT_PROXY_SSLCERT, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("certtype"), CURLOPT_PROXY_SSLCERTTYPE, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + ZVAL_PSTRING(&opt->defval, "PEM"); + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("key"), CURLOPT_PROXY_SSLKEY, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("keytype"), CURLOPT_PROXY_SSLKEYTYPE, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + ZVAL_PSTRING(&opt->defval, "PEM"); + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("keypasswd"), CURLOPT_PROXY_KEYPASSWD, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } + php_http_option_register(proxy_registry, ZEND_STRL("version"), CURLOPT_PROXY_SSLVERSION, IS_LONG); + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("verifypeer"), CURLOPT_PROXY_SSL_VERIFYPEER, _IS_BOOL))) { + ZVAL_BOOL(&opt->defval, 1); + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("verifyhost"), CURLOPT_PROXY_SSL_VERIFYHOST, _IS_BOOL))) { + ZVAL_BOOL(&opt->defval, 1); + opt->setter = php_http_curle_option_set_ssl_verifyhost; + } + php_http_option_register(proxy_registry, ZEND_STRL("cipher_list"), CURLOPT_PROXY_SSL_CIPHER_LIST, IS_STRING); +# if PHP_HTTP_CURL_VERSION(7,71,0) + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("issuercert"), CURLOPT_PROXY_ISSUERCERT, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } +# endif +# if PHP_HTTP_HAVE_LIBCURL_OPENSSL + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("crlfile"), CURLOPT_PROXY_CRLFILE, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } +# endif +# if PHP_HTTP_HAVE_LIBCURL_CAINFO + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("cainfo"), CURLOPT_PROXY_CAINFO, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; +# ifdef PHP_HTTP_CAINFO + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAINFO); +# endif + } +# endif +# if PHP_HTTP_HAVE_LIBCURL_CAPATH + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("capath"), CURLOPT_PROXY_CAPATH, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; +# ifdef PHP_HTTP_CAPATH + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CAPATH); +# endif + } +# endif + +# if PHP_HTTP_HAVE_LIBCURL_TLSAUTH_TYPE + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthtype"), CURLOPT_PROXY_TLSAUTH_TYPE, IS_LONG))) { + opt->setter = php_http_curle_option_set_ssl_tlsauthtype; + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthuser"), CURLOPT_PROXY_TLSAUTH_USERNAME, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tlsauthpass"), CURLOPT_PROXY_TLSAUTH_PASSWORD, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } +# endif +# if PHP_HTTP_CURL_VERSION(7,59,0) + /* FIXME: see http://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html#AVAILABILITY */ + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("pinned_publickey"), CURLOPT_PROXY_PINNEDPUBLICKEY, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } +# endif +# if PHP_HTTP_CURL_VERSION(7,61,0) && PHP_HTTP_HAVE_LIBCURL_TLS13_CIPHERS + if ((opt = php_http_option_register(proxy_registry, ZEND_STRL("tls13_ciphers"), CURLOPT_PROXY_TLS13_CIPHERS, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; + } +# endif } +#endif + } + +#if PHP_HTTP_CURL_VERSION(7,64,1) +# if !PHP_HTTP_HAVE_LIBCURL_ALT_SVC + if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_ALTSVC)) { +# endif + if ((opt = php_http_option_register(registry, ZEND_STRL("altsvc_ctrl"), CURLOPT_ALTSVC_CTRL, IS_LONG))) { + opt->setter = php_http_curle_option_set_altsvc_ctrl; + } + if ((opt = php_http_option_register(registry, ZEND_STRL("altsvc"), CURLOPT_ALTSVC, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } +# if !PHP_HTTP_HAVE_LIBCURL_ALT_SVC + } +# endif +#endif +#if PHP_HTTP_CURL_VERSION(7,74,0) +# if !PHP_HTTP_HAVE_LIBCURL_HSTS + if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_HSTS)) { +# endif + php_http_option_register(registry, ZEND_STRL("hsts_ctrl"), CURLOPT_HSTS_CTRL, IS_LONG); + if ((opt = php_http_option_register(registry, ZEND_STRL("hsts"), CURLOPT_HSTS, IS_STRING))) { + opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; + } +# if !PHP_HTTP_HAVE_LIBCURL_HSTS } +# endif +#endif } static zval *php_http_curle_get_option(php_http_option_t *opt, HashTable *options, void *userdata) @@ -1607,12 +1903,16 @@ static ZEND_RESULT_CODE php_http_curle_set_option(php_http_option_t *opt, zval * break; } if (rv != SUCCESS) { - php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc)); + if (opt->flags & PHP_HTTP_CURLE_OPTION_IGNORE_RC) { + rv = SUCCESS; + } else { + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc)); + } } return rv; } -#if PHP_HTTP_CURL_VERSION(7,30,0) +#if PHP_HTTP_CURL_VERSION(7,30,0) && !PHP_HTTP_CURL_VERSION(7,62,0) static ZEND_RESULT_CODE php_http_curlm_option_set_pipelining_bl(php_http_option_t *opt, zval *value, void *userdata) { php_http_client_t *client = userdata; @@ -1714,7 +2014,7 @@ static ZEND_RESULT_CODE php_http_curlm_option_set_share_cookies(php_http_option_ return SUCCESS; } -#if PHP_HTTP_CURL_VERSION(7,23,0) +#if PHP_HTTP_HAVE_LIBCURL_SHARE_SSL static ZEND_RESULT_CODE php_http_curlm_option_set_share_ssl(php_http_option_t *opt, zval *value, void *userdata) { php_http_client_t *client = userdata; @@ -1747,38 +2047,38 @@ static void php_http_curlm_options_init(php_http_options_t *registry) /* set max number of connections to a single host */ #if PHP_HTTP_CURL_VERSION(7,30,0) php_http_option_register(registry, ZEND_STRL("max_host_connections"), CURLMOPT_MAX_HOST_CONNECTIONS, IS_LONG); -#endif - /* maximum number of requests in a pipeline */ -#if PHP_HTTP_CURL_VERSION(7,30,0) - if ((opt = php_http_option_register(registry, ZEND_STRL("max_pipeline_length"), CURLMOPT_MAX_PIPELINE_LENGTH, IS_LONG))) { - ZVAL_LONG(&opt->defval, 5); - } #endif /* max simultaneously open connections */ #if PHP_HTTP_CURL_VERSION(7,30,0) php_http_option_register(registry, ZEND_STRL("max_total_connections"), CURLMOPT_MAX_TOTAL_CONNECTIONS, IS_LONG); #endif +#if PHP_HTTP_CURL_VERSION(7,67,0) + if ((opt = php_http_option_register(registry, ZEND_STRL("max_concurrent_streams"), CURLMOPT_MAX_CONCURRENT_STREAMS, IS_LONG))) { + ZVAL_LONG(&opt->defval, 100); + } +#endif + +#if !PHP_HTTP_CURL_VERSION(7,62,0) /* enable/disable HTTP pipelining */ php_http_option_register(registry, ZEND_STRL("pipelining"), CURLMOPT_PIPELINING, _IS_BOOL); +# if PHP_HTTP_CURL_VERSION(7,30,0) + /* maximum number of requests in a pipeline */ + if ((opt = php_http_option_register(registry, ZEND_STRL("max_pipeline_length"), CURLMOPT_MAX_PIPELINE_LENGTH, IS_LONG))) { + ZVAL_LONG(&opt->defval, 5); + } /* chunk length threshold for pipelining */ -#if PHP_HTTP_CURL_VERSION(7,30,0) php_http_option_register(registry, ZEND_STRL("chunk_length_penalty_size"), CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, IS_LONG); -#endif /* size threshold for pipelining penalty */ -#if PHP_HTTP_CURL_VERSION(7,30,0) php_http_option_register(registry, ZEND_STRL("content_length_penalty_size"), CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, IS_LONG); -#endif /* pipelining server blacklist */ -#if PHP_HTTP_CURL_VERSION(7,30,0) if ((opt = php_http_option_register(registry, ZEND_STRL("pipelining_server_bl"), CURLMOPT_PIPELINING_SERVER_BL, IS_ARRAY))) { opt->setter = php_http_curlm_option_set_pipelining_bl; } -#endif /* pipelining host blacklist */ -#if PHP_HTTP_CURL_VERSION(7,30,0) if ((opt = php_http_option_register(registry, ZEND_STRL("pipelining_site_bl"), CURLMOPT_PIPELINING_SITE_BL, IS_ARRAY))) { opt->setter = php_http_curlm_option_set_pipelining_bl; } +# endif #endif /* events */ if ((opt = php_http_option_register(registry, ZEND_STRL("use_eventloop"), 0, 0))) { @@ -1789,7 +2089,7 @@ static void php_http_curlm_options_init(php_http_options_t *registry) opt->setter = php_http_curlm_option_set_share_cookies; ZVAL_TRUE(&opt->defval); } -#if PHP_HTTP_CURL_VERSION(7,23,0) +#if PHP_HTTP_HAVE_LIBCURL_SHARE_SSL if ((opt = php_http_option_register(registry, ZEND_STRL("share_ssl"), 0, _IS_BOOL))) { opt->setter = php_http_curlm_option_set_share_ssl; ZVAL_TRUE(&opt->defval); @@ -1847,9 +2147,10 @@ static ZEND_RESULT_CODE php_http_curlm_set_option(php_http_option_t *opt, zval * /* client ops */ -static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_handler_t *curl) +static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_handler_t *handler) { - CURL *ch = curl->handle; + php_http_client_curl_t *curl = handler->client->ctx; + CURL *ch = handler->handle; php_http_curle_storage_t *st; if ((st = php_http_curle_get_storage(ch))) { @@ -1878,27 +2179,61 @@ static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_ #endif #if PHP_HTTP_CURL_VERSION(7,21,3) - if (curl->options.resolve) { - curl_slist_free_all(curl->options.resolve); - curl->options.resolve = NULL; + if (handler->options.resolve) { + curl_slist_free_all(handler->options.resolve); + handler->options.resolve = NULL; } #endif - curl->options.retry.count = 0; - curl->options.retry.delay = 0; - curl->options.redirects = 0; - curl->options.encode_cookies = 1; + handler->options.retry.count = 0; + handler->options.retry.delay = 0; + handler->options.redirects = 0; + handler->options.encode_cookies = 1; - if (curl->options.headers) { - curl_slist_free_all(curl->options.headers); - curl->options.headers = NULL; + if (handler->options.headers) { + curl_slist_free_all(handler->options.headers); + handler->options.headers = NULL; } - if (curl->options.proxyheaders) { - curl_slist_free_all(curl->options.proxyheaders); - curl->options.proxyheaders = NULL; + if (handler->options.proxyheaders) { + curl_slist_free_all(handler->options.proxyheaders); + handler->options.proxyheaders = NULL; } - php_http_buffer_reset(&curl->options.cookies); - php_http_buffer_reset(&curl->options.ranges); + php_http_buffer_reset(&handler->options.cookies); + php_http_buffer_reset(&handler->options.ranges); + + if (php_http_message_body_size(handler->response.body)) { + php_http_message_body_free(&handler->response.body); + handler->response.body = php_http_message_body_init(NULL, NULL); + } + php_http_buffer_reset(&handler->response.headers); + +#if ZTS + curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L); +#endif + curl_easy_setopt(ch, CURLOPT_HEADER, 0L); + curl_easy_setopt(ch, CURLOPT_FILETIME, 1L); + curl_easy_setopt(ch, CURLOPT_AUTOREFERER, 1L); + curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, php_http_curle_header_callback); + curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, php_http_curle_body_callback); + curl_easy_setopt(ch, CURLOPT_DEBUGFUNCTION, php_http_curle_raw_callback); + curl_easy_setopt(ch, CURLOPT_READFUNCTION, php_http_curle_read_callback); + curl_easy_setopt(ch, CURLOPT_SEEKFUNCTION, php_http_curle_seek_callback); +#if PHP_HTTP_CURL_VERSION(7,32,0) + curl_easy_setopt(ch, CURLOPT_XFERINFOFUNCTION, php_http_curle_xferinfo_callback); + curl_easy_setopt(ch, CURLOPT_XFERINFODATA, handler); +#else + curl_easy_setopt(ch, CURLOPT_PROGRESSFUNCTION, php_http_curle_progress_callback); + curl_easy_setopt(ch, CURLOPT_PROGRESSDATA, handler); +#endif + curl_easy_setopt(ch, CURLOPT_DEBUGDATA, handler); + curl_easy_setopt(ch, CURLOPT_WRITEDATA, handler); + curl_easy_setopt(ch, CURLOPT_HEADERDATA, handler); +#if DEBUG_COOKIES + fprintf(stderr, "CURLOPT_SHARE: %p\n", curl->handle->share); +#endif + curl_easy_setopt(ch, CURLOPT_SHARE, curl->handle->share); return SUCCESS; } @@ -1906,7 +2241,6 @@ static ZEND_RESULT_CODE php_http_client_curl_handler_reset(php_http_client_curl_ static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_http_client_t *h, php_resource_factory_t *rf) { void *handle; - php_http_client_curl_t *curl = h->ctx; php_http_client_curl_handler_t *handler; if (!(handle = php_resource_factory_handle_ctor(rf, NULL))) { @@ -1924,31 +2258,6 @@ static php_http_client_curl_handler_t *php_http_client_curl_handler_init(php_htt php_http_buffer_init(&handler->options.ranges); zend_hash_init(&handler->options.cache, 0, NULL, ZVAL_PTR_DTOR, 0); -#if ZTS - curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L); -#endif - curl_easy_setopt(handle, CURLOPT_HEADER, 0L); - curl_easy_setopt(handle, CURLOPT_FILETIME, 1L); - curl_easy_setopt(handle, CURLOPT_AUTOREFERER, 1L); - curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, php_http_curle_header_callback); - curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, php_http_curle_body_callback); - curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, php_http_curle_raw_callback); - curl_easy_setopt(handle, CURLOPT_READFUNCTION, php_http_curle_read_callback); - curl_easy_setopt(handle, CURLOPT_SEEKFUNCTION, php_http_curle_seek_callback); -#if PHP_HTTP_CURL_VERSION(7,32,0) - curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, php_http_curle_xferinfo_callback); - curl_easy_setopt(handle, CURLOPT_XFERINFODATA, handler); -#else - curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, php_http_curle_progress_callback); - curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, handler); -#endif - curl_easy_setopt(handle, CURLOPT_DEBUGDATA, handler); - curl_easy_setopt(handle, CURLOPT_WRITEDATA, handler); - curl_easy_setopt(handle, CURLOPT_HEADERDATA, handler); - curl_easy_setopt(handle, CURLOPT_SHARE, curl->handle->share); - php_http_client_curl_handler_reset(handler); return handler; @@ -1974,7 +2283,9 @@ static ZEND_RESULT_CODE php_http_client_curl_handler_prepare(php_http_client_cur curl_easy_setopt(curl->handle, CURLOPT_URL, storage->url); /* apply options */ - php_http_options_apply(&php_http_curle_options, enqueue->options, curl); + if (SUCCESS != php_http_options_apply(&php_http_curle_options, enqueue->options, curl)) { + return FAILURE; + } /* request headers */ php_http_message_update_headers(msg); @@ -2072,10 +2383,19 @@ static void php_http_client_curl_handler_clear(php_http_client_curl_handler_t *h #endif curl_easy_setopt(handler->handle, CURLOPT_VERBOSE, 0L); curl_easy_setopt(handler->handle, CURLOPT_DEBUGFUNCTION, NULL); + /* see gh issue #84 */ +#if DEBUG_COOKIES + fprintf(stderr, "CURLOPT_COOKIELIST: FLUSH\n"); + fprintf(stderr, "CURLOPT_SHARE: (null)\n"); +#endif curl_easy_setopt(handler->handle, CURLOPT_COOKIELIST, "FLUSH"); curl_easy_setopt(handler->handle, CURLOPT_SHARE, NULL); - /* see gh issue #84 */ - curl_easy_setopt(handler->handle, CURLOPT_COOKIEJAR, NULL); +#if PHP_HTTP_CURL_VERSION(7,63,0) && !PHP_HTTP_CURL_VERSION(7,65,0) + { + php_http_curle_storage_t *st = php_http_curle_get_storage(handler->handle); + curl_easy_setopt(handler->handle, CURLOPT_COOKIEJAR, st ? st->cookiestore : NULL); + } +#endif } static void php_http_client_curl_handler_dtor(php_http_client_curl_handler_t *handler) @@ -2155,6 +2475,17 @@ static void queue_dtor(php_http_client_enqueue_t *e) php_http_client_curl_handler_dtor(handler); } +static void retire_ch(php_persistent_handle_factory_t *f, void **handle) +{ + CURL *ch = *handle; + /* erase all cookies */ + if (ch) { + curl_easy_reset(ch); + curl_easy_setopt(ch, CURLOPT_COOKIELIST, "ALL"); + curl_easy_setopt(ch, CURLOPT_COOKIEFILE, NULL); + } +} + static php_resource_factory_t *create_rf(php_http_client_t *h, php_http_client_enqueue_t *enqueue) { php_persistent_handle_factory_t *pf = NULL; @@ -2185,7 +2516,7 @@ static php_resource_factory_t *create_rf(php_http_client_t *h, php_http_client_e id_len = spprintf(&id_str, 0, "%.*s:%s:%d", (int) phf->ident->len, phf->ident->val, STR_PTR(url->host), port); id = php_http_cs2zs(id_str, id_len); - pf = php_persistent_handle_concede(NULL, PHP_HTTP_G->client.curl.driver.request_name, id, NULL, NULL); + pf = php_persistent_handle_concede(NULL, PHP_HTTP_G->client.curl.driver.request_name, id, NULL, retire_ch); zend_string_release(id); } @@ -2243,6 +2574,43 @@ static ZEND_RESULT_CODE php_http_client_curl_enqueue(php_http_client_t *h, php_h return SUCCESS; } +static ZEND_RESULT_CODE php_http_client_curl_requeue(php_http_client_t *h, php_http_client_enqueue_t *enqueue) +{ + CURLMcode rs; + php_http_client_curl_t *curl = h->ctx; + php_http_client_curl_handler_t *handler = enqueue->opaque; + php_http_client_progress_state_t *progress; + + if (SUCCESS != php_http_client_curl_handler_reset(handler)) { + return FAILURE; + } + + if (SUCCESS != php_http_client_curl_handler_prepare(handler, enqueue)) { + return FAILURE; + } + + if (CURLM_OK != (rs = curl_multi_remove_handle(curl->handle->multi, handler->handle))) { + php_error_docref(NULL, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs)); + return FAILURE; + } + + if (CURLM_OK != (rs = curl_multi_add_handle(curl->handle->multi, handler->handle))) { + zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue); + php_error_docref(NULL, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs)); + return FAILURE; + } + + ++curl->unfinished; + + if (h->callback.progress.func && SUCCESS == php_http_client_getopt(h, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, enqueue->request, &progress)) { + progress->info = "start"; + h->callback.progress.func(h->callback.progress.arg, h, &handler->queue, progress); + progress->started = 1; + } + + return SUCCESS; +} + static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_http_client_enqueue_t *enqueue) { CURLMcode rs; @@ -2359,17 +2727,19 @@ static ZEND_RESULT_CODE php_http_client_curl_setopt(php_http_client_t *h, php_ht { php_http_client_curl_t *curl = h->ctx; + (void) curl; + switch (opt) { case PHP_HTTP_CLIENT_OPT_CONFIGURATION: return php_http_options_apply(&php_http_curlm_options, (HashTable *) arg, h); break; - +#if !PHP_HTTP_CURL_VERSION(7,62,0) case PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING: if (CURLM_OK != curl_multi_setopt(curl->handle->multi, CURLMOPT_PIPELINING, (long) *((zend_bool *) arg))) { return FAILURE; } break; - +#endif case PHP_HTTP_CLIENT_OPT_USE_EVENTS: #if PHP_HTTP_HAVE_LIBEVENT return php_http_curlm_use_eventloop(h, (*(zend_bool *) arg) @@ -2463,6 +2833,7 @@ static php_http_client_ops_t php_http_client_curl_ops = { php_http_client_curl_once, php_http_client_curl_enqueue, php_http_client_curl_dequeue, + php_http_client_curl_requeue, php_http_client_curl_setopt, php_http_client_curl_getopt }; @@ -2472,13 +2843,13 @@ php_http_client_ops_t *php_http_client_curl_get_ops(void) return &php_http_client_curl_ops; } -#define REGISTER_NS_STRING_OR_NULL_CONSTANT(ns, name, str, flags) \ - do { \ - if ((str) != NULL) { \ - REGISTER_NS_STRING_CONSTANT(ns, name, str, flags); \ - } else { \ - REGISTER_NS_NULL_CONSTANT(ns, name, flags); \ - } \ +#define REGISTER_NS_STRING_OR_NULL_CONSTANT(ns, name, str, flags) \ + do { \ + if ((str) != NULL) { \ + REGISTER_NS_STRING_CONSTANT(ns, name, str, flags); \ + } else { \ + REGISTER_NS_NULL_CONSTANT(ns, name, flags); \ + } \ } while (0) PHP_MINIT_FUNCTION(http_client_curl) @@ -2516,6 +2887,13 @@ PHP_MINIT_FUNCTION(http_client_curl) } if ((info = curl_version_info(CURLVERSION_NOW))) { + char tmp_ver[0x20], *tmp_ptr, *tmp_end; +#define tmp_ver_init() do {\ + tmp_ver[0] = 0; \ + tmp_ptr = &tmp_ver[0]; \ + tmp_end = &tmp_ver[sizeof(tmp_ver) - 1]; \ +} while (0) + /* * Feature constants */ @@ -2523,9 +2901,6 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "IPV6", CURL_VERSION_IPV6, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS4", CURL_VERSION_KERBEROS4, CONST_CS|CONST_PERSISTENT); -#if PHP_HTTP_CURL_VERSION(7,40,0) - REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS5", CURL_VERSION_KERBEROS5, CONST_CS|CONST_PERSISTENT); -#endif REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "SSL", CURL_VERSION_SSL, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "LIBZ", CURL_VERSION_LIBZ, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "NTLM", CURL_VERSION_NTLM, CONST_CS|CONST_PERSISTENT); @@ -2535,9 +2910,6 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "LARGEFILE", CURL_VERSION_LARGEFILE, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "IDN", CURL_VERSION_IDN, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "SSPI", CURL_VERSION_SSPI, CONST_CS|CONST_PERSISTENT); -#if PHP_HTTP_CURL_VERSION(7,38,0) - REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "GSSAPI", CURL_VERSION_GSSAPI, CONST_CS|CONST_PERSISTENT); -#endif #if PHP_HTTP_CURL_VERSION(7,21,4) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "TLSAUTH_SRP", CURL_VERSION_TLSAUTH_SRP, CONST_CS|CONST_PERSISTENT); #endif @@ -2547,28 +2919,75 @@ PHP_MINIT_FUNCTION(http_client_curl) #if PHP_HTTP_CURL_VERSION(7,33,0) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTP2", CURL_VERSION_HTTP2, CONST_CS|CONST_PERSISTENT); #endif +#if PHP_HTTP_CURL_VERSION(7,38,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "GSSAPI", CURL_VERSION_GSSAPI, CONST_CS|CONST_PERSISTENT); +#endif #if PHP_HTTP_CURL_VERSION(7,40,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "KERBEROS5", CURL_VERSION_KERBEROS5, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "UNIX_SOCKETS", CURL_VERSION_UNIX_SOCKETS, CONST_CS|CONST_PERSISTENT); #endif #if PHP_HTTP_CURL_VERSION(7,47,0) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "PSL", CURL_VERSION_PSL, CONST_CS|CONST_PERSISTENT); #endif +#if PHP_HTTP_CURL_VERSION(7,52,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTPS_PROXY", CURL_VERSION_HTTPS_PROXY, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,56,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "MULTI_SSL", CURL_VERSION_MULTI_SSL, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,57,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "BROTLI", CURL_VERSION_BROTLI, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,64,1) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "ALTSVC", CURL_VERSION_ALTSVC, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,66,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HTTP3", CURL_VERSION_HTTP3, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,72,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "ZSTD", CURL_VERSION_ZSTD, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "UNICODE", CURL_VERSION_UNICODE, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,74,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl\\Features", "HSTS", CURL_VERSION_HSTS, CONST_CS|CONST_PERSISTENT); +#endif + /* * Version constants */ REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl", "VERSIONS", curl_version(), CONST_CS|CONST_PERSISTENT); -#if CURLVERSION_NOW >= 0 - REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "CURL", (char *) info->version, CONST_CS|CONST_PERSISTENT); - REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "SSL", (char *) info->ssl_version, CONST_CS|CONST_PERSISTENT); - REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "LIBZ", (char *) info->libz_version, CONST_CS|CONST_PERSISTENT); -# if CURLVERSION_NOW >= 1 - REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ARES", (char *) info->ares, CONST_CS|CONST_PERSISTENT); -# if CURLVERSION_NOW >= 2 - REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "IDN", (char *) info->libidn, CONST_CS|CONST_PERSISTENT); -# endif -# endif + REGISTER_NS_STRING_CONSTANT("http\\Client\\Curl\\Versions", "CURL", info->version, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "SSL", info->ssl_version, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "LIBZ", info->libz_version, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ARES", info->ares, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "IDN", info->libidn, CONST_CS|CONST_PERSISTENT); + tmp_ver_init(); + if (info->iconv_ver_num) { + tmp_ptr = zend_print_ulong_to_buf(tmp_end, info->iconv_ver_num & 0xf); + tmp_end = tmp_ptr - 1; + tmp_ptr = zend_print_ulong_to_buf(tmp_end, info->iconv_ver_num >> 8); + *tmp_end = '.'; + } + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ICONV", *tmp_ptr ? tmp_ptr : NULL, CONST_CS|CONST_PERSISTENT); +#if PHP_HTTP_CURL_VERSION(7,57,0) + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "BROTLI", info->brotli_version, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,66,0) + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "NGHTTP2", info->nghttp2_version, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "QUIC", info->quic_version, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,70,0) + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "CAINFO", info->cainfo, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "CAPATH", info->capath, CONST_CS|CONST_PERSISTENT); #endif +#if PHP_HTTP_CURL_VERSION(7,72,0) + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "ZSTD", info->zstd_version, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,75,0) + REGISTER_NS_STRING_OR_NULL_CONSTANT("http\\Client\\Curl\\Versions", "HYPER", info->hyper_version, CONST_CS|CONST_PERSISTENT); +#endif + } /* @@ -2581,6 +3000,12 @@ PHP_MINIT_FUNCTION(http_client_curl) #endif #if PHP_HTTP_CURL_VERSION(7,47,0) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_2TLS", CURL_HTTP_VERSION_2TLS, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,49,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_2_PRIOR_KNOWLEDGE", CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,66,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_3", CURL_HTTP_VERSION_3, CONST_CS|CONST_PERSISTENT); #endif REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HTTP_VERSION_ANY", CURL_HTTP_VERSION_NONE, CONST_CS|CONST_PERSISTENT); @@ -2592,6 +3017,9 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_TLSv1_0", CURL_SSLVERSION_TLSv1_0, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_TLSv1_1", CURL_SSLVERSION_TLSv1_1, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_TLSv1_2", CURL_SSLVERSION_TLSv1_2, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,52,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_TLSv1_3", CURL_SSLVERSION_TLSv1_3, CONST_CS|CONST_PERSISTENT); #endif REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_SSLv2", CURL_SSLVERSION_SSLv2, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_SSLv3", CURL_SSLVERSION_SSLv3, CONST_CS|CONST_PERSISTENT); @@ -2600,6 +3028,14 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "TLSAUTH_SRP", CURL_TLSAUTH_SRP, CONST_CS|CONST_PERSISTENT); #endif +#if PHP_HTTP_CURL_VERSION(7,54,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_MAX_DEFAULT", CURL_SSLVERSION_MAX_DEFAULT, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_MAX_TLSv1_0", CURL_SSLVERSION_MAX_TLSv1_0, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_MAX_TLSv1_1", CURL_SSLVERSION_MAX_TLSv1_1, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_MAX_TLSv1_2", CURL_SSLVERSION_MAX_TLSv1_2, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "SSL_VERSION_MAX_TLSv1_3", CURL_SSLVERSION_MAX_TLSv1_3, CONST_CS|CONST_PERSISTENT); +#endif + /* * DNS IPvX resolving */ @@ -2610,6 +3046,7 @@ PHP_MINIT_FUNCTION(http_client_curl) /* * Auth Constants */ + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_NONE", CURLAUTH_NONE, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_BASIC", CURLAUTH_BASIC, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_DIGEST", CURLAUTH_DIGEST, CONST_CS|CONST_PERSISTENT); #if PHP_HTTP_CURL_VERSION(7,19,3) @@ -2619,6 +3056,12 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_GSSNEG", CURLAUTH_GSSNEGOTIATE, CONST_CS|CONST_PERSISTENT); #if PHP_HTTP_CURL_VERSION(7,38,0) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_SPNEGO", CURLAUTH_NEGOTIATE, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,61,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_BEARER", CURLAUTH_BEARER, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,75,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AWS_SIGV4", CURLAUTH_AWS_SIGV4, CONST_CS|CONST_PERSISTENT); #endif REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "AUTH_ANY", CURLAUTH_ANY, CONST_CS|CONST_PERSISTENT); @@ -2626,8 +3069,8 @@ PHP_MINIT_FUNCTION(http_client_curl) * Proxy Type Constants */ REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS4", CURLPROXY_SOCKS4, CONST_CS|CONST_PERSISTENT); - REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS4A", CURLPROXY_SOCKS5, CONST_CS|CONST_PERSISTENT); - REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS5_HOSTNAME", CURLPROXY_SOCKS5, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS4A", CURLPROXY_SOCKS4A, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS5_HOSTNAME", CURLPROXY_SOCKS5_HOSTNAME, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_SOCKS5", CURLPROXY_SOCKS5, CONST_CS|CONST_PERSISTENT); REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "PROXY_HTTP", CURLPROXY_HTTP, CONST_CS|CONST_PERSISTENT); #if PHP_HTTP_CURL_VERSION(7,19,4) @@ -2646,6 +3089,16 @@ PHP_MINIT_FUNCTION(http_client_curl) REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "POSTREDIR_ALL", CURL_REDIR_POST_ALL, CONST_CS|CONST_PERSISTENT); #endif +#if PHP_HTTP_CURL_VERSION(7,64,1) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_READONLYFILE", CURLALTSVC_READONLYFILE, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H1", CURLALTSVC_H1, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H2", CURLALTSVC_H2, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "ALTSVC_H3", CURLALTSVC_H3, CONST_CS|CONST_PERSISTENT); +#endif +#if PHP_HTTP_CURL_VERSION(7,74,0) + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HSTS_ENABLE", CURLHSTS_ENABLE, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("http\\Client\\Curl", "HSTS_READONLYFILE", CURLHSTS_READONLYFILE, CONST_CS|CONST_PERSISTENT); +#endif return SUCCESS; } diff --git a/src/php_http_client_curl_event.c b/src/php_http_client_curl_event.c index b8db1b2..2e663ed 100644 --- a/src/php_http_client_curl_event.c +++ b/src/php_http_client_curl_event.c @@ -97,8 +97,6 @@ static void php_http_client_curl_event_timer(CURLM *multi, long timeout_ms, void } break; case 0: - php_http_client_curl_event_handler(context, CURL_SOCKET_TIMEOUT, 0); - break; default: if (!event_initialized(context->timeout)) { event_assign(context->timeout, context->evbase, CURL_SOCKET_TIMEOUT, 0, php_http_client_curl_event_timeout_callback, context); diff --git a/src/php_http_client_curl_user.c b/src/php_http_client_curl_user.c index 1f69a51..2e646f6 100644 --- a/src/php_http_client_curl_user.c +++ b/src/php_http_client_curl_user.c @@ -22,6 +22,11 @@ typedef struct php_http_client_curl_user_ev { php_http_client_curl_user_context_t *context; } php_http_client_curl_user_ev_t; +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_user_handler, 0, 1, IS_LONG, 1) + ZEND_ARG_OBJ_INFO(0, client, "http\\Client", 0) + ZEND_ARG_TYPE_INFO(0, stream, IS_RESOURCE, 1) + ZEND_ARG_TYPE_INFO(0, action, IS_LONG, 1) +ZEND_END_ARG_INFO(); static ZEND_NAMED_FUNCTION(php_http_client_curl_user_handler) { zval *zstream = NULL, *zclient = NULL; @@ -57,9 +62,7 @@ static void php_http_client_curl_user_timer(CURLM *multi, long timeout_ms, void fprintf(stderr, "\ntimer <- timeout_ms: %ld\n", timeout_ms); #endif - if (timeout_ms <= 0) { - php_http_client_curl_loop(context->client, CURL_SOCKET_TIMEOUT, 0); - } else { + if (timeout_ms >= 0) { zval args[1], *ztimeout = &args[0]; ZVAL_LONG(ztimeout, timeout_ms); @@ -188,6 +191,10 @@ static void *php_http_client_curl_user_init(php_http_client_t *client, void *use ctx->closure.common.type = ZEND_INTERNAL_FUNCTION; ctx->closure.common.function_name = zend_string_init(ZEND_STRL("php_http_client_curl_user_handler"), 0); ctx->closure.internal_function.handler = php_http_client_curl_user_handler; + ctx->closure.internal_function.arg_info = (zend_internal_arg_info *) &ai_user_handler[1]; + ctx->closure.internal_function.num_args = 3; + ctx->closure.internal_function.required_num_args = 1; + zend_create_closure(zclosure, &ctx->closure, NULL, NULL, NULL); diff --git a/src/php_http_client_request.c b/src/php_http_client_request.c index 9055f49..52e9c70 100644 --- a/src/php_http_client_request.c +++ b/src/php_http_client_request.c @@ -230,7 +230,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClientRequest, getOptions) { if (SUCCESS == zend_parse_parameters_none()) { - zval tmp, *zoptions = zend_read_property(php_http_client_request_class_entry, getThis(), ZEND_STRL("options"), 0, &tmp); + zval tmp, *zoptions = zend_read_property(php_http_client_request_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("options"), 0, &tmp); RETURN_ZVAL(zoptions, 1, 0); } } diff --git a/src/php_http_client_response.c b/src/php_http_client_response.c index 34748aa..722b4e0 100644 --- a/src/php_http_client_response.c +++ b/src/php_http_client_response.c @@ -101,7 +101,7 @@ static PHP_METHOD(HttpClientResponse, getTransferInfo) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &info_name, &info_len), invalid_arg, return); - info = zend_read_property(php_http_client_response_class_entry, getThis(), ZEND_STRL("transferInfo"), 0, &info_tmp); + info = zend_read_property(php_http_client_response_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("transferInfo"), 0, &info_tmp); /* request completed? */ if (Z_TYPE_P(info) != IS_OBJECT) { @@ -110,7 +110,7 @@ static PHP_METHOD(HttpClientResponse, getTransferInfo) } if (info_len && info_name) { - info = zend_read_property(NULL, info, php_http_pretty_key(info_name, info_len, 0, 0), info_len, 0, &info_name_tmp); + info = zend_read_property(NULL, Z_OBJ_P(info), php_http_pretty_key(info_name, info_len, 0, 0), info_len, 0, &info_name_tmp); if (!info) { php_http_throw(unexpected_val, "Could not find transfer info with name '%s'", info_name); diff --git a/src/php_http_cookie.c b/src/php_http_cookie.c index 1186ca0..dd4c6c6 100644 --- a/src/php_http_cookie.c +++ b/src/php_http_cookie.c @@ -17,16 +17,16 @@ php_http_cookie_list_t *php_http_cookie_list_init(php_http_cookie_list_t *list) if (!list) { list = emalloc(sizeof(*list)); } - + zend_hash_init(&list->cookies, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&list->extras, 0, NULL, ZVAL_PTR_DTOR, 0); - + list->path = NULL; list->domain = NULL; list->expires = -1; list->max_age = -1; list->flags = 0; - + return list; } @@ -51,7 +51,7 @@ void php_http_cookie_list_dtor(php_http_cookie_list_t *list) if (list) { zend_hash_destroy(&list->cookies); zend_hash_destroy(&list->extras); - + PTR_SET(list->path, NULL); PTR_SET(list->domain, NULL); } @@ -206,15 +206,15 @@ void php_http_cookie_list_to_struct(php_http_cookie_list_t *list, zval *strct) { zval cookies, extras, tmp; HashTable *ht = HASH_OF(strct); - + array_init_size(&cookies, zend_hash_num_elements(&list->cookies)); array_copy(&list->cookies, Z_ARRVAL(cookies)); zend_symtable_str_update(ht, ZEND_STRL("cookies"), &cookies); - + array_init_size(&extras, zend_hash_num_elements(&list->extras)); array_copy(&list->extras, Z_ARRVAL(extras)); zend_symtable_str_update(ht, ZEND_STRL("extras"), &extras); - + ZVAL_LONG(&tmp, list->flags); zend_symtable_str_update(ht, ZEND_STRL("flags"), &tmp); ZVAL_LONG(&tmp, list->expires); @@ -286,22 +286,22 @@ php_http_cookie_list_t *php_http_cookie_list_from_struct(php_http_cookie_list_t list->domain = estrndup(str->val, str->len); zend_string_release(str); } - + return list; } static inline void append_encoded(php_http_buffer_t *buf, const char *key, size_t key_len, const char *val, size_t val_len) { zend_string *enc_str[2]; - + enc_str[0] = php_raw_url_encode(key, key_len); enc_str[1] = php_raw_url_encode(val, val_len); - + php_http_buffer_append(buf, enc_str[0]->val, enc_str[0]->len); php_http_buffer_appends(buf, "="); php_http_buffer_append(buf, enc_str[1]->val, enc_str[1]->len); php_http_buffer_appends(buf, "; "); - + zend_string_release(enc_str[0]); zend_string_release(enc_str[1]); } @@ -311,7 +311,7 @@ void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, si php_http_buffer_t buf; zend_hash_key key; zval *val; - + php_http_buffer_init(&buf); ZEND_HASH_FOREACH_KEY_VAL(&list->cookies, key.h, key.key, val) @@ -325,7 +325,7 @@ void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, si zend_string_release(str); } ZEND_HASH_FOREACH_END(); - + if (list->domain && *list->domain) { php_http_buffer_appendf(&buf, "domain=%s; ", list->domain); } @@ -340,7 +340,7 @@ void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, si if (list->max_age >= 0) { php_http_buffer_appendf(&buf, "max-age=%ld; ", list->max_age); } - + ZEND_HASH_FOREACH_KEY_VAL(&list->extras, key.h, key.key, val) { zend_string *str = zval_get_string(val); @@ -352,14 +352,14 @@ void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, si zend_string_release(str); } ZEND_HASH_FOREACH_END(); - + if (list->flags & PHP_HTTP_COOKIE_SECURE) { php_http_buffer_appends(&buf, "secure; "); } if (list->flags & PHP_HTTP_COOKIE_HTTPONLY) { php_http_buffer_appends(&buf, "httpOnly; "); } - + php_http_buffer_fix(&buf); *str = buf.data; *len = buf.used; @@ -406,9 +406,9 @@ php_http_cookie_object_t *php_http_cookie_object_new_ex(zend_class_entry *ce, ph } \ } while(0) -zend_object *php_http_cookie_object_clone(zval *obj) +zend_object *php_http_cookie_object_clone(zend_object *obj) { - php_http_cookie_object_t *new_obj, *old_obj = PHP_HTTP_OBJ(NULL, obj); + php_http_cookie_object_t *new_obj, *old_obj = PHP_HTTP_OBJ(obj, NULL); PHP_HTTP_COOKIE_OBJECT_INIT(old_obj); @@ -943,7 +943,7 @@ static PHP_METHOD(HttpCookie, setFlags) } ZEND_BEGIN_ARG_INFO_EX(ai_HttpCookie_toString, 0, 0, 0) -ZEND_END_ARG_INFO();; +ZEND_END_ARG_INFO(); static PHP_METHOD(HttpCookie, toString) { php_http_cookie_object_t *obj; @@ -981,6 +981,9 @@ static PHP_METHOD(HttpCookie, toArray) php_http_cookie_list_to_struct(obj->list, return_value); } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpCookie___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_cookie_methods[] = { PHP_ME(HttpCookie, __construct, ai_HttpCookie___construct, ZEND_ACC_PUBLIC) PHP_ME(HttpCookie, getCookies, ai_HttpCookie_getCookies, ZEND_ACC_PUBLIC) @@ -1010,7 +1013,7 @@ static zend_function_entry php_http_cookie_methods[] = { PHP_ME(HttpCookie, toArray, ai_HttpCookie_toArray, ZEND_ACC_PUBLIC) PHP_ME(HttpCookie, toString, ai_HttpCookie_toString, ZEND_ACC_PUBLIC) - ZEND_MALIAS(HttpCookie, __toString, toString, ai_HttpCookie_toString, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpCookie, __toString, toString, ai_HttpCookie___toString, ZEND_ACC_PUBLIC) EMPTY_FUNCTION_ENTRY }; diff --git a/src/php_http_cookie.h b/src/php_http_cookie.h index e7b924e..3186d6f 100644 --- a/src/php_http_cookie.h +++ b/src/php_http_cookie.h @@ -62,7 +62,7 @@ typedef struct php_http_cookie_object { zend_object *php_http_cookie_object_new(zend_class_entry *ce); php_http_cookie_object_t *php_http_cookie_object_new_ex(zend_class_entry *ce, php_http_cookie_list_t *list); -zend_object *php_http_cookie_object_clone(zval *this_ptr); +zend_object *php_http_cookie_object_clone(zend_object *this_ptr); void php_http_cookie_object_free(zend_object *object); PHP_MINIT_FUNCTION(http_cookie); diff --git a/src/php_http_encoding.c b/src/php_http_encoding.c index 3e57e29..2e3007b 100644 --- a/src/php_http_encoding.c +++ b/src/php_http_encoding.c @@ -477,9 +477,9 @@ php_http_encoding_stream_object_t *php_http_encoding_stream_object_new_ex(zend_c return o; } -zend_object *php_http_encoding_stream_object_clone(zval *object) +zend_object *php_http_encoding_stream_object_clone(zend_object *object) { - php_http_encoding_stream_object_t *new_obj, *old_obj = PHP_HTTP_OBJ(NULL, object); + php_http_encoding_stream_object_t *new_obj, *old_obj = PHP_HTTP_OBJ(object, NULL); php_http_encoding_stream_t *cpy = php_http_encoding_stream_copy(old_obj->stream, NULL); if (!cpy) { diff --git a/src/php_http_encoding.h b/src/php_http_encoding.h index 3b59829..842bff7 100644 --- a/src/php_http_encoding.h +++ b/src/php_http_encoding.h @@ -76,7 +76,7 @@ PHP_HTTP_API zend_class_entry *php_http_get_encoding_stream_class_entry(void); zend_object *php_http_encoding_stream_object_new(zend_class_entry *ce); php_http_encoding_stream_object_t *php_http_encoding_stream_object_new_ex(zend_class_entry *ce, php_http_encoding_stream_t *s); -zend_object *php_http_encoding_stream_object_clone(zval *object); +zend_object *php_http_encoding_stream_object_clone(zend_object *object); void php_http_encoding_stream_object_free(zend_object *object); #endif diff --git a/src/php_http_env.c b/src/php_http_env.c index 4afcd31..9c88822 100644 --- a/src/php_http_env.c +++ b/src/php_http_env.c @@ -15,6 +15,12 @@ PHP_RSHUTDOWN_FUNCTION(http_env) +{ + php_http_env_reset(); + return SUCCESS; +} + +void php_http_env_reset() { if (PHP_HTTP_G->env.request.headers) { zend_hash_destroy(PHP_HTTP_G->env.request.headers); @@ -24,13 +30,10 @@ PHP_RSHUTDOWN_FUNCTION(http_env) if (PHP_HTTP_G->env.request.body) { php_http_message_body_free(&PHP_HTTP_G->env.request.body); } - if (PHP_HTTP_G->env.server_var) { zval_ptr_dtor(PHP_HTTP_G->env.server_var); PHP_HTTP_G->env.server_var = NULL; } - - return SUCCESS; } void php_http_env_get_request_headers(HashTable *headers) @@ -414,10 +417,12 @@ ZEND_RESULT_CODE php_http_env_set_response_status_line(long code, php_http_versi { sapi_header_line h = {NULL, 0, 0}; ZEND_RESULT_CODE ret; + char *line; - h.line_len = spprintf(&h.line, 0, "HTTP/%u.%u %ld %s", v->major, v->minor, code, php_http_env_get_response_status_for_code(code)); + h.line_len = spprintf(&line, 0, "HTTP/%u.%u %ld %s", v->major, v->minor, code, php_http_env_get_response_status_for_code(code)); + h.line = line; ret = sapi_header_op(SAPI_HEADER_REPLACE, (void *) &h); - efree(h.line); + efree(line); return ret; } @@ -429,10 +434,9 @@ ZEND_RESULT_CODE php_http_env_set_response_protocol_version(php_http_version_t * ZEND_RESULT_CODE php_http_env_set_response_header(long http_code, const char *header_str, size_t header_len, zend_bool replace) { - sapi_header_line h = {estrndup(header_str, header_len), header_len, http_code}; + sapi_header_line h = {header_str, header_len, http_code}; ZEND_RESULT_CODE ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, (void *) &h); - efree(h.line); return ret; } @@ -440,14 +444,16 @@ ZEND_RESULT_CODE php_http_env_set_response_header_va(long http_code, zend_bool r { ZEND_RESULT_CODE ret = FAILURE; sapi_header_line h = {NULL, 0, http_code}; + char *line; - h.line_len = vspprintf(&h.line, 0, fmt, argv); + h.line_len = vspprintf(&line, 0, fmt, argv); + h.line = line; if (h.line) { if (h.line_len) { ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, (void *) &h); } - efree(h.line); + efree(line); } return ret; } @@ -496,17 +502,19 @@ ZEND_RESULT_CODE php_http_env_set_response_header_value(long http_code, const ch } else { sapi_header_line h; ZEND_RESULT_CODE ret; + char *line; if (name_len > INT_MAX) { return FAILURE; } h.response_code = http_code; - h.line_len = spprintf(&h.line, 0, "%s: %s", name_str, data->val); + h.line_len = spprintf(&line, 0, "%s: %s", name_str, data->val); + h.line = line; ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, (void *) &h); zend_string_release(data); - PTR_FREE(h.line); + PTR_FREE(line); return ret; } @@ -774,6 +782,15 @@ static PHP_METHOD(HttpEnv, negotiate) } } +ZEND_BEGIN_ARG_INFO(ai_HttpEnv_reset, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(HttpEnv, reset) +{ + zend_parse_parameters_none(); + php_http_env_reset(); +} + + static zend_function_entry php_http_env_methods[] = { PHP_ME(HttpEnv, getRequestHeader, ai_HttpEnv_getRequestHeader, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(HttpEnv, getRequestBody, ai_HttpEnv_getRequestBody, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) @@ -792,6 +809,8 @@ static zend_function_entry php_http_env_methods[] = { PHP_ME(HttpEnv, negotiateCharset, ai_HttpEnv_negotiateCharset, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(HttpEnv, negotiate, ai_HttpEnv_negotiate, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(HttpEnv, reset, ai_HttpEnv_reset, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + EMPTY_FUNCTION_ENTRY }; diff --git a/src/php_http_env.h b/src/php_http_env.h index 8292744..d71ec47 100644 --- a/src/php_http_env.h +++ b/src/php_http_env.h @@ -75,6 +75,7 @@ static inline zend_bool php_http_env_got_server_var(const char *v) return NULL != php_http_env_get_server_var(v, strlen(v), 1); } +PHP_HTTP_API void php_http_env_reset(); PHP_HTTP_API zend_class_entry *php_http_env_get_class_entry(void); PHP_MINIT_FUNCTION(http_env); diff --git a/src/php_http_env_request.c b/src/php_http_env_request.c index 7c6eea8..0ed0eb8 100644 --- a/src/php_http_env_request.c +++ b/src/php_http_env_request.c @@ -140,26 +140,26 @@ static PHP_METHOD(HttpEnvRequest, __construct) zsg = php_http_env_get_superglobal(ZEND_STRL("_GET")); object_init_ex(&zqs, php_http_querystring_get_class_entry()); php_http_expect(SUCCESS == php_http_querystring_ctor(&zqs, zsg), unexpected_val, return); - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("query"), &zqs); + zend_update_property(php_http_env_request_class_entry, &obj->zo, ZEND_STRL("query"), &zqs); zval_ptr_dtor(&zqs); zsg = php_http_env_get_superglobal(ZEND_STRL("_POST")); object_init_ex(&zqs, php_http_querystring_get_class_entry()); php_http_expect(SUCCESS == php_http_querystring_ctor(&zqs, zsg), unexpected_val, return); - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("form"), &zqs); + zend_update_property(php_http_env_request_class_entry, &obj->zo, ZEND_STRL("form"), &zqs); zval_ptr_dtor(&zqs); zsg = php_http_env_get_superglobal(ZEND_STRL("_COOKIE")); object_init_ex(&zqs, php_http_querystring_get_class_entry()); php_http_expect(SUCCESS == php_http_querystring_ctor(&zqs, zsg), unexpected_val, return); - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("cookie"), &zqs); + zend_update_property(php_http_env_request_class_entry, &obj->zo, ZEND_STRL("cookie"), &zqs); zval_ptr_dtor(&zqs); array_init(&zqs); if ((zsg = php_http_env_get_superglobal(ZEND_STRL("_FILES")))) { zend_hash_apply_with_arguments(Z_ARRVAL_P(zsg), grab_files, 1, &zqs); } - zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("files"), &zqs); + zend_update_property(php_http_env_request_class_entry, &obj->zo, ZEND_STRL("files"), &zqs); zval_ptr_dtor(&zqs); } @@ -169,7 +169,7 @@ static PHP_METHOD(HttpEnvRequest, __construct) zend_fcall_info_cache fcc; \ zval rv, mn, *args = ecalloc(sizeof(zval), ZEND_NUM_ARGS()); \ zval *this_ptr = getThis(); \ - zval qs_tmp, *qs = zend_read_property(Z_OBJCE_P(this_ptr), this_ptr, ZEND_STRL(prop), 0, &qs_tmp); \ + zval qs_tmp, *qs = zend_read_property(Z_OBJCE_P(this_ptr), Z_OBJ_P(this_ptr), ZEND_STRL(prop), 0, &qs_tmp); \ \ ZVAL_NULL(&rv); \ array_init(&mn); \ @@ -197,7 +197,7 @@ static PHP_METHOD(HttpEnvRequest, getForm) if (ZEND_NUM_ARGS()) { call_querystring_get("form"); } else { - zval zform_tmp, *zform = zend_read_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("form"), 0, &zform_tmp); + zval zform_tmp, *zform = zend_read_property(php_http_env_request_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("form"), 0, &zform_tmp); RETURN_ZVAL(zform, 1, 0); } } @@ -213,7 +213,7 @@ static PHP_METHOD(HttpEnvRequest, getQuery) if (ZEND_NUM_ARGS()) { call_querystring_get("query"); } else { - zval zquery_tmp, *zquery = zend_read_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("query"), 0, &zquery_tmp); + zval zquery_tmp, *zquery = zend_read_property(php_http_env_request_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("query"), 0, &zquery_tmp); RETURN_ZVAL(zquery, 1, 0); } } @@ -229,7 +229,7 @@ static PHP_METHOD(HttpEnvRequest, getCookie) if (ZEND_NUM_ARGS()) { call_querystring_get("cookie"); } else { - zval zcookie_tmp, *zcookie = zend_read_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("cookie"), 0, &zcookie_tmp); + zval zcookie_tmp, *zcookie = zend_read_property(php_http_env_request_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("cookie"), 0, &zcookie_tmp); RETURN_ZVAL(zcookie, 1, 0); } } @@ -239,7 +239,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpEnvRequest, getFiles) { if (SUCCESS == zend_parse_parameters_none()) { - zval zfiles_tmp, *zfiles = zend_read_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("files"), 0, &zfiles_tmp); + zval zfiles_tmp, *zfiles = zend_read_property(php_http_env_request_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("files"), 0, &zfiles_tmp); RETURN_ZVAL(zfiles, 1, 0); } } diff --git a/src/php_http_env_response.c b/src/php_http_env_response.c index f5d2da9..3dba5b9 100644 --- a/src/php_http_env_response.c +++ b/src/php_http_env_response.c @@ -18,21 +18,21 @@ static void set_option(zval *options, const char *name_str, size_t name_len, int 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); + zend_update_property_double(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len, *(double *)value_ptr); break; case IS_LONG: - zend_update_property_long(Z_OBJCE_P(options), options, name_str, name_len, *(zend_long *)value_ptr); + zend_update_property_long(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len, *(zend_long *)value_ptr); break; case IS_STRING: - zend_update_property_stringl(Z_OBJCE_P(options), options, name_str, name_len, value_ptr, value_len); + zend_update_property_stringl(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len, value_ptr, value_len); break; case IS_ARRAY: case IS_OBJECT: - zend_update_property(Z_OBJCE_P(options), options, name_str, name_len, value_ptr); + zend_update_property(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len, value_ptr); break; } } else { - zend_update_property_null(Z_OBJCE_P(options), options, name_str, name_len); + zend_update_property_null(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len); } } else { convert_to_array(options); @@ -65,7 +65,7 @@ static zval *get_option(zval *options, const char *name_str, size_t name_len, zv zval *val = NULL; if (EXPECTED(Z_TYPE_P(options) == IS_OBJECT)) { - val = zend_read_property(Z_OBJCE_P(options), options, name_str, name_len, 0, tmp); + val = zend_read_property(Z_OBJCE_P(options), Z_OBJ_P(options), name_str, name_len, 0, tmp); } else if (EXPECTED(Z_TYPE_P(options) == IS_ARRAY)) { val = zend_symtable_str_find(Z_ARRVAL_P(options), name_str, name_len); } else { @@ -363,12 +363,12 @@ static ZEND_RESULT_CODE php_http_env_response_send_head(php_http_env_response_t php_http_version_t v; zend_string *zs = zval_get_string(zoption); - zval_ptr_dtor(zoption); if (EXPECTED(zs->len && php_http_version_parse(&v, zs->val))) { ret = r->ops->set_protocol_version(r, &v); php_http_version_dtor(&v); } zend_string_release(zs); + zval_ptr_dtor(zoption); } if (ret != SUCCESS) { @@ -1205,7 +1205,7 @@ static PHP_METHOD(HttpEnvResponse, setContentDisposition) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "a", &zdisposition), invalid_arg, return); - zend_update_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("contentDisposition"), zdisposition); + zend_update_property(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), ZEND_STRL("contentDisposition"), zdisposition); RETVAL_ZVAL(getThis(), 1, 0); } diff --git a/src/php_http_etag.c b/src/php_http_etag.c index 048af87..7e309f2 100644 --- a/src/php_http_etag.c +++ b/src/php_http_etag.c @@ -12,41 +12,32 @@ #include "php_http_api.h" -#if PHP_HTTP_HAVE_HASH -# include "ext/hash/php_hash.h" -#endif - +#include "ext/hash/php_hash.h" #include "ext/standard/crc32.h" #include "ext/standard/sha1.h" #include "ext/standard/md5.h" +#if PHP_VERSION_ID >= 80100 +# define HASH_INIT_ARGS ,NULL +#else +# define HASH_INIT_ARGS +#endif + php_http_etag_t *php_http_etag_init(const char *mode) { - void *ctx; php_http_etag_t *e; + zend_string *mode_str = zend_string_init(mode, strlen(mode), 0); + const php_hash_ops *eho = php_hash_fetch_ops(mode_str); - if (mode && (!strcasecmp(mode, "crc32b"))) { - ctx = emalloc(sizeof(uint32_t)); - *((uint32_t *) ctx) = ~0; - } else if (mode && !strcasecmp(mode, "sha1")) { - PHP_SHA1Init(ctx = emalloc(sizeof(PHP_SHA1_CTX))); - } else if (mode && !strcasecmp(mode, "md5")) { - PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX))); - } else { -#if PHP_HTTP_HAVE_HASH - const php_hash_ops *eho = NULL; - - if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) { - ctx = emalloc(eho->context_size); - eho->hash_init(ctx); - } else -#endif + if (!eho) { + zend_string_release(mode_str); return NULL; } + zend_string_release(mode_str); - e = emalloc(sizeof(*e)); - e->ctx = ctx; - e->mode = estrdup(mode); + e = emalloc(sizeof(*e) + eho->context_size - 1); + e->ops = eho; + eho->hash_init(e->ctx HASH_INIT_ARGS); return e; } @@ -54,32 +45,10 @@ php_http_etag_t *php_http_etag_init(const char *mode) char *php_http_etag_finish(php_http_etag_t *e) { unsigned char digest[128] = {0}; - char *etag = NULL; - - if (!strcasecmp(e->mode, "crc32b")) { - uint32_t e_ctx; - memcpy(&e_ctx, e->ctx, 4); - e_ctx = ntohl(~e_ctx); - etag = php_http_etag_digest((unsigned char *) &e_ctx, 4); - } else if ((!strcasecmp(e->mode, "sha1"))) { - PHP_SHA1Final(digest, e->ctx); - etag = php_http_etag_digest(digest, 20); - } else if ((!strcasecmp(e->mode, "md5"))) { - PHP_MD5Final(digest, e->ctx); - etag = php_http_etag_digest(digest, 16); - } else { -#if PHP_HTTP_HAVE_HASH - const php_hash_ops *eho = NULL; + char *etag; - if ((eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) { - eho->hash_final(digest, e->ctx); - etag = php_http_etag_digest(digest, eho->digest_size); - } -#endif - } - - efree(e->ctx); - efree(e->mode); + e->ops->hash_final(digest, e->ctx); + etag = php_http_etag_digest(digest, e->ops->digest_size); efree(e); return etag; @@ -87,25 +56,7 @@ char *php_http_etag_finish(php_http_etag_t *e) size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len) { - if (!strcasecmp(e->mode, "crc32b")) { - uint32_t i, c = *((uint32_t *) e->ctx); - for (i = 0; i < data_len; ++i) { - CRC32(c, data_ptr[i]); - } - *((uint32_t *) e->ctx) = c; - } else if ((!strcasecmp(e->mode, "sha1"))) { - PHP_SHA1Update(e->ctx, (const unsigned char *) data_ptr, data_len); - } else if ((!strcasecmp(e->mode, "md5"))) { - PHP_MD5Update(e->ctx, (const unsigned char *) data_ptr, data_len); - } else { -#if PHP_HTTP_HAVE_HASH - const php_hash_ops *eho = NULL; - - if ((eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) { - eho->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len); - } -#endif - } + e->ops->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len); return data_len; } @@ -119,4 +70,3 @@ size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t dat * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/src/php_http_etag.h b/src/php_http_etag.h index f208db7..338506c 100644 --- a/src/php_http_etag.h +++ b/src/php_http_etag.h @@ -13,9 +13,11 @@ #ifndef PHP_HTTP_ETAG_H #define PHP_HTTP_ETAG_H +#include "ext/hash/php_hash.h" + typedef struct php_http_etag { - void *ctx; - char *mode; + const php_hash_ops *ops; + char ctx[1]; } php_http_etag_t; PHP_HTTP_API php_http_etag_t *php_http_etag_init(const char *mode); diff --git a/src/php_http_header.c b/src/php_http_header.c index 4c9a702..c475a81 100644 --- a/src/php_http_header.c +++ b/src/php_http_header.c @@ -17,18 +17,18 @@ ZEND_RESULT_CODE php_http_header_parse(const char *header, size_t length, HashTa php_http_header_parser_t ctx; php_http_buffer_t buf; php_http_header_parser_state_t rs; - + if (!php_http_buffer_from_string_ex(&buf, header, length)) { php_error_docref(NULL, E_WARNING, "Could not allocate buffer"); return FAILURE; } - + if (!php_http_header_parser_init(&ctx)) { php_http_buffer_dtor(&buf); php_error_docref(NULL, E_WARNING, "Could not initialize header parser"); return FAILURE; } - + rs = php_http_header_parser_parse(&ctx, &buf, PHP_HTTP_HEADER_PARSER_CLEANUP, headers, callback_func, callback_data); php_http_header_parser_dtor(&ctx); php_http_buffer_dtor(&buf); @@ -183,11 +183,46 @@ PHP_METHOD(HttpHeader, __construct) if (name_str && name_len) { char *pretty_str = estrndup(name_str, name_len); - zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("name"), php_http_pretty_key(pretty_str, name_len, 1, 1), name_len); + zend_update_property_stringl(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), php_http_pretty_key(pretty_str, name_len, 1, 1), name_len); efree(pretty_str); } if (value_str && value_len) { - zend_update_property_stringl(php_http_header_class_entry, getThis(), ZEND_STRL("value"), value_str, value_len); + zend_update_property_stringl(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), value_str, value_len); + } +} + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpHeader___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, __serialize) +{ + zval name, value, *ptr; + + zend_parse_parameters_none(); + + array_init(return_value); + ptr = zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), 0, &name); + Z_TRY_ADDREF_P(ptr); + add_next_index_zval(return_value, ptr); + ptr = zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), 0, &value); + Z_TRY_ADDREF_P(ptr); + add_next_index_zval(return_value, ptr); +} + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpHeader___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpHeader, __unserialize) +{ + HashTable *ha; + zval *name, *value; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "h", &ha), invalid_arg, return); + name = zend_hash_index_find(ha, 0); + value = zend_hash_index_find(ha, 1); + + if (name && value) { + zend_update_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), name); + zend_update_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), value); } } @@ -201,11 +236,11 @@ PHP_METHOD(HttpHeader, serialize) zval name_tmp, value_tmp; php_http_buffer_init(&buf); - zs = zval_get_string(zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0, &name_tmp)); + zs = zval_get_string(zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), 0, &name_tmp)); php_http_buffer_appendz(&buf, zs); zend_string_release(zs); - zs = zval_get_string(zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0, &value_tmp)); + zs = zval_get_string(zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), 0, &value_tmp)); if (zs->len) { php_http_buffer_appends(&buf, ": "); php_http_buffer_appendz(&buf, zs); @@ -239,16 +274,16 @@ PHP_METHOD(HttpHeader, unserialize) zend_hash_internal_pointer_reset(&ht); switch (zend_hash_get_current_key(&ht, &key, &idx)) { case HASH_KEY_IS_STRING: - zend_update_property_str(php_http_header_class_entry, getThis(), ZEND_STRL("name"), key); + zend_update_property_str(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), key); break; case HASH_KEY_IS_LONG: - zend_update_property_long(php_http_header_class_entry, getThis(), ZEND_STRL("name"), idx); + zend_update_property_long(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), idx); break; default: break; } zs = zval_get_string(zend_hash_get_current_data(&ht)); - zend_update_property_str(php_http_header_class_entry, getThis(), ZEND_STRL("value"), zs); + zend_update_property_str(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), zs); zend_string_release(zs); } } @@ -273,7 +308,7 @@ PHP_METHOD(HttpHeader, match) return; } - zs = zval_get_string(zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0, &value_tmp)); + zs = zval_get_string(zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), 0, &value_tmp)); RETVAL_BOOL(php_http_match(zs->val, val_str, flags)); zend_string_release(zs); } @@ -299,7 +334,7 @@ PHP_METHOD(HttpHeader, negotiate) array_init(rs_array); } - zs = zval_get_string(zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("name"), 0, &name_tmp)); + zs = zval_get_string(zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("name"), 0, &name_tmp)); if (zend_string_equals_literal(zs, "Accept")) { sep_str = "/"; sep_len = 1; @@ -309,7 +344,7 @@ PHP_METHOD(HttpHeader, negotiate) } zend_string_release(zs); - zs = zval_get_string(zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0, &value_tmp)); + zs = zval_get_string(zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), 0, &value_tmp)); if ((rs = php_http_negotiate(zs->val, zs->len, supported, sep_str, sep_len))) { PHP_HTTP_DO_NEGOTIATE_HANDLE_RESULT(rs, supported, rs_array); } else { @@ -327,21 +362,21 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpHeader, getParams) { zval value_tmp, zctor, zparams_obj, *zargs = NULL; - + ZVAL_STRINGL(&zctor, "__construct", lenof("__construct")); - + object_init_ex(&zparams_obj, php_http_params_get_class_entry()); - + zargs = (zval *) ecalloc(ZEND_NUM_ARGS()+1, sizeof(zval)); - ZVAL_COPY_VALUE(&zargs[0], zend_read_property(php_http_header_class_entry, getThis(), ZEND_STRL("value"), 0, &value_tmp)); + ZVAL_COPY_VALUE(&zargs[0], zend_read_property(php_http_header_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), 0, &value_tmp)); if (ZEND_NUM_ARGS()) { zend_get_parameters_array(ZEND_NUM_ARGS(), ZEND_NUM_ARGS(), &zargs[1]); } - + if (SUCCESS == call_user_function(NULL, &zparams_obj, &zctor, return_value, ZEND_NUM_ARGS()+1, zargs)) { RETVAL_ZVAL(&zparams_obj, 0, 1); } - + zval_ptr_dtor(&zctor); if (zargs) { efree(zargs); @@ -381,7 +416,7 @@ PHP_METHOD(HttpHeader, parse) object_init_ex(&zho, ce); Z_TRY_ADDREF_P(val); - zend_call_method_with_2_params(&zho, ce, NULL, "__construct", NULL, &zkey, val); + zend_call_method_with_2_params(Z_OBJ(zho), ce, NULL, "__construct", NULL, &zkey, val); zval_ptr_dtor(val); zval_ptr_dtor(&zkey); @@ -397,12 +432,17 @@ PHP_METHOD(HttpHeader, parse) } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpHeader___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_header_methods[] = { PHP_ME(HttpHeader, __construct, ai_HttpHeader___construct, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, __unserialize, ai_HttpHeader___unserialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, __serialize, ai_HttpHeader___serialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpHeader, unserialize, ai_HttpHeader_unserialize, 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) - PHP_ME(HttpHeader, unserialize, ai_HttpHeader_unserialize, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpHeader, __toString, serialize, ai_HttpHeader___toString, ZEND_ACC_PUBLIC) PHP_ME(HttpHeader, match, ai_HttpHeader_match, ZEND_ACC_PUBLIC) PHP_ME(HttpHeader, negotiate, ai_HttpHeader_negotiate, ZEND_ACC_PUBLIC) PHP_ME(HttpHeader, getParams, ai_HttpHeader_getParams, ZEND_ACC_PUBLIC) @@ -436,4 +476,3 @@ PHP_MINIT_FUNCTION(http_header) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/src/php_http_header_parser.c b/src/php_http_header_parser.c index cd76b76..6700c49 100644 --- a/src/php_http_header_parser.c +++ b/src/php_http_header_parser.c @@ -40,7 +40,13 @@ php_http_header_parser_t *php_http_header_parser_init(php_http_header_parser_t * return parser; } -#define php_http_header_parser_state_push(parser, state) zend_ptr_stack_push(&(parser)->stack, (void *) (state)), (state) +static inline php_http_header_parser_state_t +php_http_header_parser_state_push(php_http_header_parser_t *parser, php_http_header_parser_state_t state) +{ + zend_ptr_stack_push(&(parser)->stack, (void *) (state)); + return 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) @@ -428,7 +434,7 @@ static zend_function_entry php_http_header_parser_methods[] = { PHP_ME(HttpHeaderParser, getState, ai_HttpHeaderParser_getState, ZEND_ACC_PUBLIC) PHP_ME(HttpHeaderParser, parse, ai_HttpHeaderParser_parse, ZEND_ACC_PUBLIC) PHP_ME(HttpHeaderParser, stream, ai_HttpHeaderParser_stream, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} + {0} }; PHP_MINIT_FUNCTION(http_header_parser) diff --git a/src/php_http_message.c b/src/php_http_message.c index 371ecb7..cd01757 100644 --- a/src/php_http_message.c +++ b/src/php_http_message.c @@ -332,7 +332,7 @@ static void message_headers(php_http_message_t *msg, php_http_buffer_t *str) char *tmp = NULL; size_t len = 0; - php_http_info_to_string((php_http_info_t *) msg, &tmp, &len, PHP_HTTP_CRLF TSRMLS_CC); + php_http_info_to_string((php_http_info_t *) msg, &tmp, &len, PHP_HTTP_CRLF); php_http_message_update_headers(msg); php_http_buffer_append(str, tmp, len); @@ -509,9 +509,8 @@ zend_class_entry *php_http_message_get_class_entry(void) return php_http_message_class_entry; } -static zval *php_http_message_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *rv); - -static PHP_WRITE_PROP_HANDLER_TYPE php_http_message_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot); +static zval *php_http_message_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv); +static zval *php_http_message_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot); static zend_object_handlers php_http_message_object_handlers; static HashTable php_http_message_object_prophandlers; @@ -648,15 +647,15 @@ static void php_http_message_object_prophandler_set_headers(php_http_message_obj } } static void php_http_message_object_prophandler_get_body(php_http_message_object_t *obj, zval *return_value) { - if (obj->body) { - zval tmp; + zval tmp; - ZVAL_COPY_VALUE(&tmp, return_value); - RETVAL_OBJECT(&obj->body->zo, 1); - zval_ptr_dtor(&tmp); - } else { - RETVAL_NULL(); + if (!obj->body) { + RETURN_NULL(); } + + ZVAL_COPY_VALUE(&tmp, return_value); + RETVAL_OBJECT(&obj->body->zo, 1); + zval_ptr_dtor(&tmp); } static void php_http_message_object_prophandler_set_body(php_http_message_object_t *obj, zval *value) { php_http_message_object_set_body(obj, value); @@ -689,6 +688,8 @@ static void php_http_message_object_prophandler_set_parent_message(php_http_mess do { \ if (!obj->message) { \ obj->message = php_http_message_init(NULL, 0, NULL); \ + } else if (!obj->body && php_http_message_body_size(obj->message->body)) { \ + php_http_message_object_init_body_object(obj); \ } \ } while(0) @@ -857,10 +858,10 @@ php_http_message_object_t *php_http_message_object_new_ex(zend_class_entry *ce, return o; } -zend_object *php_http_message_object_clone(zval *this_ptr) +zend_object *php_http_message_object_clone(zend_object *this_ptr) { php_http_message_object_t *new_obj; - php_http_message_object_t *old_obj = PHP_HTTP_OBJ(NULL, this_ptr); + php_http_message_object_t *old_obj = PHP_HTTP_OBJ(this_ptr, NULL); new_obj = php_http_message_object_new_ex(old_obj->zo.ce, php_http_message_copy(old_obj->message, NULL)); zend_objects_clone_members(&new_obj->zo, &old_obj->zo); @@ -895,70 +896,53 @@ void php_http_message_object_free(zend_object *object) zend_object_std_dtor(object); } -#if PHP_VERSION_ID >= 70400 -static zval *php_http_message_object_get_prop_ptr(zval *object, zval *member, int type, void **cache_slot) +static zval *php_http_message_object_get_prop_ptr(zend_object *object, zend_string *member, int type, void **cache_slot) { return NULL; } -#endif -static zval *php_http_message_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp) +static zval *php_http_message_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *tmp) { zval *return_value; - zend_string *member_name = zval_get_string(member); - php_http_message_object_prophandler_t *handler = php_http_message_object_get_prophandler(member_name); + php_http_message_object_prophandler_t *handler = php_http_message_object_get_prophandler(member); return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); 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_t *obj = PHP_HTTP_OBJ(object, NULL); - 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); - - ZVAL_OBJ(tmp, &proxy_obj->zo); - return_value = tmp; - } + handler->read(obj, return_value); } - - zend_string_release(member_name); return return_value; } -static PHP_WRITE_PROP_HANDLER_TYPE php_http_message_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot) +static zval *php_http_message_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot) { - php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object); + php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL); php_http_message_object_prophandler_t *handler; - zend_string *member_name = zval_get_string(member); PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - if ((handler = php_http_message_object_get_prophandler(member_name))) { + if ((handler = php_http_message_object_get_prophandler(member))) { handler->write(obj, value); } else { zend_get_std_object_handlers()->write_property(object, member, value, cache_slot); } - - zend_string_release(member_name); - PHP_WRITE_PROP_HANDLER_RETURN(value); + return value; } -static HashTable *php_http_message_object_get_debug_info(zval *object, int *is_temp) +static HashTable *php_http_message_object_get_debug_info(zend_object *object, int *is_temp) { - zval tmp; - php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object); + php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL); HashTable *props = zend_get_std_object_handlers()->get_properties(object); char *ver_str, *url_str = NULL; size_t ver_len, url_len = 0; + zval tmp; PHP_HTTP_MESSAGE_OBJECT_INIT(obj); - *is_temp = 0; + if (is_temp) { + *is_temp = 0; + } #define UPDATE_PROP(name_str, action_with_tmp) \ do { \ @@ -1028,10 +1012,10 @@ static HashTable *php_http_message_object_get_debug_info(zval *object, int *is_t return props; } -static HashTable *php_http_message_object_get_gc(zval *object, zval **table, int *n) +static HashTable *php_http_message_object_get_gc(zend_object *object, zval **table, int *n) { - php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object); - HashTable *props = Z_OBJPROP_P(object); + php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL); + HashTable *props = object->handlers->get_properties(object); uint32_t count = 2 + zend_hash_num_elements(props); zval *val; @@ -1054,6 +1038,30 @@ static HashTable *php_http_message_object_get_gc(zval *object, zval **table, int return NULL; } +static int php_http_message_object_cast(zend_object *object, zval *return_value, int type) +{ + php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL); + char *string; + size_t length; + + switch (type) { + case IS_STRING: + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + php_http_message_to_string(obj->message, &string, &length); + if (string) { + RETVAL_STR(php_http_cs2zs(string, length)); + } else { + RETVAL_EMPTY_STRING(); + } + return SUCCESS; + case _IS_BOOL: + RETVAL_TRUE; + return SUCCESS; + default: + return FAILURE; + } +} + ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___construct, 0, 0, 0) ZEND_ARG_INFO(0, message) ZEND_ARG_INFO(0, greedy) @@ -1691,8 +1699,6 @@ static PHP_METHOD(HttpMessage, getParentMessage) RETVAL_OBJECT(&obj->parent->zo, 1); } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___toString, 0, 0, 0) -ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_toString, 0, 0, 0) ZEND_ARG_INFO(0, include_parent) ZEND_END_ARG_INFO(); @@ -1758,6 +1764,58 @@ static PHP_METHOD(HttpMessage, toCallback) } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(HttpMessage, __serialize) +{ + zend_ulong num_index; + zend_string *str_index; + zend_property_info *pi; + php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); + HashTable *props = php_http_message_object_get_debug_info(&obj->zo, NULL); + + zend_parse_parameters_none(); + + array_init(return_value); + + ZEND_HASH_FOREACH_KEY_PTR(&obj->zo.ce->properties_info, num_index, str_index, pi) + { + (void)num_index; + zval *val; + if (str_index && (val = zend_hash_find_ind(props, pi->name))) { + Z_TRY_ADDREF_P(val); + zend_hash_update(Z_ARRVAL_P(return_value), str_index, val); + } + } + ZEND_HASH_FOREACH_END(); +} + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +static PHP_METHOD(HttpMessage, __unserialize) +{ + HashTable *arr; + zend_string *key; + zval *val; + php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "h", &arr), invalid_arg, return); + + PHP_HTTP_MESSAGE_OBJECT_INIT(obj); + + ZEND_HASH_FOREACH_STR_KEY_VAL(arr, key, val) + { + php_http_message_object_prophandler_t *ph = php_http_message_object_get_prophandler(key); + if (ph) { + ph->write(obj, val); + } else { + zend_update_property_ex(php_http_message_class_entry, &obj->zo, key, val); + } + } + ZEND_HASH_FOREACH_END(); +} + ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_serialize, 0, 0, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, serialize) @@ -1912,7 +1970,7 @@ static PHP_METHOD(HttpMessage, splitMultipartBody) RETURN_OBJ(&php_http_message_object_new_ex(obj->zo.ce, msg)->zo); } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_count, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpMessage_count, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, count) { @@ -1927,7 +1985,7 @@ static PHP_METHOD(HttpMessage, count) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_rewind, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpMessage_rewind, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, rewind) { @@ -1942,7 +2000,7 @@ static PHP_METHOD(HttpMessage, rewind) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_valid, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpMessage_valid, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, valid) { @@ -1953,7 +2011,7 @@ static PHP_METHOD(HttpMessage, valid) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_next, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpMessage_next, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, next) { @@ -1977,7 +2035,7 @@ static PHP_METHOD(HttpMessage, next) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_key, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpMessage_key, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, key) { @@ -1988,7 +2046,7 @@ static PHP_METHOD(HttpMessage, key) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_current, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(ai_HttpMessage_current, 0, 0, http\\Message, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(HttpMessage, current) { @@ -2001,6 +2059,9 @@ static PHP_METHOD(HttpMessage, current) } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_message_methods[] = { PHP_ME(HttpMessage, __construct, ai_HttpMessage___construct, ZEND_ACC_PUBLIC) PHP_ME(HttpMessage, getBody, ai_HttpMessage_getBody, ZEND_ACC_PUBLIC) @@ -2037,6 +2098,8 @@ static zend_function_entry php_http_message_methods[] = { /* implements Serializable */ PHP_ME(HttpMessage, serialize, ai_HttpMessage_serialize, ZEND_ACC_PUBLIC) PHP_ME(HttpMessage, unserialize, ai_HttpMessage_unserialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, __serialize, ai_HttpMessage___serialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, __unserialize, ai_HttpMessage___unserialize, ZEND_ACC_PUBLIC) /* implements Iterator */ PHP_ME(HttpMessage, rewind, ai_HttpMessage_rewind, ZEND_ACC_PUBLIC) @@ -2071,14 +2134,11 @@ PHP_MINIT_FUNCTION(http_message) php_http_message_object_handlers.read_property = php_http_message_object_read_prop; php_http_message_object_handlers.write_property = php_http_message_object_write_prop; php_http_message_object_handlers.get_debug_info = php_http_message_object_get_debug_info; -#if PHP_VERSION_ID >= 70400 php_http_message_object_handlers.get_property_ptr_ptr = php_http_message_object_get_prop_ptr; -#else - php_http_message_object_handlers.get_property_ptr_ptr = NULL; -#endif php_http_message_object_handlers.get_gc = php_http_message_object_get_gc; + php_http_message_object_handlers.cast_object = php_http_message_object_cast; - zend_class_implements(php_http_message_class_entry, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator); + zend_class_implements(php_http_message_class_entry, 3, zend_ce_countable, zend_ce_serializable, zend_ce_iterator); zend_hash_init(&php_http_message_object_prophandlers, 9, NULL, php_http_message_object_prophandler_hash_dtor, 1); zend_declare_property_long(php_http_message_class_entry, ZEND_STRL("type"), PHP_HTTP_NONE, ZEND_ACC_PROTECTED); diff --git a/src/php_http_message.h b/src/php_http_message.h index 538cdb1..d0b604f 100644 --- a/src/php_http_message.h +++ b/src/php_http_message.h @@ -104,7 +104,7 @@ ZEND_RESULT_CODE php_http_message_object_init_body_object(php_http_message_objec zend_object *php_http_message_object_new(zend_class_entry *ce); php_http_message_object_t *php_http_message_object_new_ex(zend_class_entry *ce, php_http_message_t *msg); -zend_object *php_http_message_object_clone(zval *object); +zend_object *php_http_message_object_clone(zend_object *object); void php_http_message_object_free(zend_object *object); #endif diff --git a/src/php_http_message_body.c b/src/php_http_message_body.c index 97b1a14..8bde1a7 100644 --- a/src/php_http_message_body.c +++ b/src/php_http_message_body.c @@ -420,7 +420,7 @@ static ZEND_RESULT_CODE add_recursive_files(php_http_message_body_t *body, const } else { zend_string *tmp = zval_get_string(zdata); - stream = php_stream_memory_open(TEMP_STREAM_READONLY, tmp->val, tmp->len); + stream = php_http_mem_stream_open(TEMP_STREAM_READONLY, tmp); zend_string_release(tmp); } } else { @@ -432,7 +432,7 @@ static ZEND_RESULT_CODE add_recursive_files(php_http_message_body_t *body, const return FAILURE; } else { zend_string *znc = zval_get_string(zname), *ztc = zval_get_string(ztype); - php_http_arrkey_t arrkey = {0, znc}; + php_http_arrkey_t arrkey = {0, znc, 0, 0}; char *key = format_key(&arrkey, name); ZEND_RESULT_CODE ret = php_http_message_body_add_form_file(body, key, ztc->val, zfc->val, stream); @@ -590,10 +590,10 @@ php_http_message_body_object_t *php_http_message_body_object_new_ex(zend_class_e return o; } -zend_object *php_http_message_body_object_clone(zval *object) +zend_object *php_http_message_body_object_clone(zend_object *object) { 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_object_t *old_obj = PHP_HTTP_OBJ(object, NULL); php_http_message_body_t *body = php_http_message_body_copy(old_obj->body, NULL); new_obj = php_http_message_body_object_new_ex(old_obj->zo.ce, body); @@ -602,10 +602,10 @@ zend_object *php_http_message_body_object_clone(zval *object) return &new_obj->zo; } -static HashTable *php_http_message_body_object_get_gc(zval *object, zval **table, int *n) +static HashTable *php_http_message_body_object_get_gc(zend_object *object, zval **table, int *n) { - php_http_message_body_object_t *obj = PHP_HTTP_OBJ(NULL, object); - HashTable *props = Z_OBJPROP_P(object); + php_http_message_body_object_t *obj = PHP_HTTP_OBJ(object, NULL); + HashTable *props = object->handlers->get_properties(object); uint32_t count = zend_hash_num_elements(props); obj->gc = erealloc(obj->gc, (1 + count) * sizeof(zval)); @@ -670,9 +670,9 @@ PHP_METHOD(HttpMessageBody, __construct) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody___toString, 0, 0, 0) +ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody_serialize, 0, 0, 0) ZEND_END_ARG_INFO(); -PHP_METHOD(HttpMessageBody, __toString) +PHP_METHOD(HttpMessageBody, serialize) { if (SUCCESS == zend_parse_parameters_none()) { php_http_message_body_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); @@ -693,18 +693,60 @@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody_unserialize, 0, 0, 1) ZEND_END_ARG_INFO(); PHP_METHOD(HttpMessageBody, unserialize) { - char *us_str; - size_t us_len; + zend_string *us_str; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &us_str, &us_len)) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &us_str)) { php_http_message_body_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); - php_stream *s = php_stream_memory_open(0, us_str, us_len); + php_stream *s = php_http_mem_stream_open(0, us_str); obj->body = php_http_message_body_init(NULL, s); php_stream_to_zval(s, obj->gc); } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessageBody___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpMessageBody, __unserialize) +{ + HashTable *arr; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "h", &arr)) { + zval *zv = zend_hash_index_find(arr, 0); + + if (zv) { + zend_string *zs = zval_get_string(zv); + php_stream *s = php_http_mem_stream_open(0, zs); + php_http_message_body_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); + + obj->body = php_http_message_body_init(NULL, s); + php_stream_to_zval(s, obj->gc); + zend_string_release(zs); + } + } +} + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessageBody___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpMessageBody, __serialize) +{ + + php_http_message_body_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); + zend_string *zs; + + zend_parse_parameters_none(); + + PHP_HTTP_MESSAGE_BODY_OBJECT_INIT(obj); + + array_init(return_value); + zs = php_http_message_body_to_string(obj->body, 0, 0); + if (zs) { + add_index_str(return_value, 0, zs); + } +} + + + ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageBody_toStream, 0, 0, 1) ZEND_ARG_INFO(0, stream) ZEND_ARG_INFO(0, offset) @@ -909,12 +951,17 @@ PHP_METHOD(HttpMessageBody, stat) } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessageBody___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_message_body_methods[] = { 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) + PHP_ME(HttpMessageBody, serialize, ai_HttpMessageBody_serialize, ZEND_ACC_PUBLIC) + PHP_MALIAS(HttpMessageBody, toString, serialize, ai_HttpMessageBody_serialize, ZEND_ACC_PUBLIC) + PHP_MALIAS(HttpMessageBody, __toString, serialize, ai_HttpMessageBody___toString, ZEND_ACC_PUBLIC) PHP_ME(HttpMessageBody, unserialize, ai_HttpMessageBody_unserialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessageBody, __serialize, ai_HttpMessageBody___serialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessageBody, __unserialize,ai_HttpMessageBody___unserialize,ZEND_ACC_PUBLIC) PHP_ME(HttpMessageBody, toStream, ai_HttpMessageBody_toStream, ZEND_ACC_PUBLIC) PHP_ME(HttpMessageBody, toCallback, ai_HttpMessageBody_toCallback, ZEND_ACC_PUBLIC) PHP_ME(HttpMessageBody, getResource, ai_HttpMessageBody_getResource, ZEND_ACC_PUBLIC) diff --git a/src/php_http_message_body.h b/src/php_http_message_body.h index d4115f5..81566f2 100644 --- a/src/php_http_message_body.h +++ b/src/php_http_message_body.h @@ -71,7 +71,7 @@ PHP_MINIT_FUNCTION(http_message_body); zend_object *php_http_message_body_object_new(zend_class_entry *ce); php_http_message_body_object_t *php_http_message_body_object_new_ex(zend_class_entry *ce, php_http_message_body_t *body); -zend_object *php_http_message_body_object_clone(zval *object); +zend_object *php_http_message_body_object_clone(zend_object *object); void php_http_message_body_object_free(zend_object *object); #endif diff --git a/src/php_http_message_parser.c b/src/php_http_message_parser.c index 517806d..55087e0 100644 --- a/src/php_http_message_parser.c +++ b/src/php_http_message_parser.c @@ -57,7 +57,13 @@ php_http_message_parser_t *php_http_message_parser_init(php_http_message_parser_ return parser; } -#define php_http_message_parser_state_push(parser, state) zend_ptr_stack_push(&(parser)->stack, (void *) (state)), (state) +static inline php_http_message_parser_state_t +php_http_message_parser_state_push(php_http_message_parser_t *parser, php_http_message_parser_state_t state) +{ + zend_ptr_stack_push(&parser->stack, (void *) state); + return 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) @@ -644,7 +650,7 @@ static zend_function_entry php_http_message_parser_methods[] = { PHP_ME(HttpMessageParser, getState, ai_HttpMessageParser_getState, ZEND_ACC_PUBLIC) PHP_ME(HttpMessageParser, parse, ai_HttpMessageParser_parse, ZEND_ACC_PUBLIC) PHP_ME(HttpMessageParser, stream, ai_HttpMessageParser_stream, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} + {0} }; PHP_MINIT_FUNCTION(http_message_parser) diff --git a/src/php_http_misc.c b/src/php_http_misc.c index f0cc25f..261387f 100644 --- a/src/php_http_misc.c +++ b/src/php_http_misc.c @@ -261,10 +261,9 @@ size_t php_http_pass_fcall_callback(void *cb_arg, const char *str, size_t len) zval zdata; ZVAL_STRINGL(&zdata, str, len); - if (SUCCESS == zend_fcall_info_argn(&fcd->fci, 2, &fcd->fcz, &zdata)) { - zend_fcall_info_call(&fcd->fci, &fcd->fcc, NULL, NULL); - zend_fcall_info_args_clear(&fcd->fci, 0); - } + zend_fcall_info_argn(&fcd->fci, 2, &fcd->fcz, &zdata); + zend_fcall_info_call(&fcd->fci, &fcd->fcc, NULL, NULL); + zend_fcall_info_args_clear(&fcd->fci, 0); zval_ptr_dtor(&zdata); return len; } diff --git a/src/php_http_misc.h b/src/php_http_misc.h index b91638e..c45ab15 100644 --- a/src/php_http_misc.h +++ b/src/php_http_misc.h @@ -99,47 +99,55 @@ static inline const char *php_http_locate_bin_eol(const char *bin, size_t len, i #if PHP_DEBUG # undef HASH_OF -# if PHP_VERSION_ID >= 70500 -# 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(Z_OBJ_P(p)) : NULL)))) -# else -# 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 +# 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(Z_OBJ_P(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) +#if PHP_VERSION_ID >= 80100 +# define php_http_mem_stream_open(type, zstr) php_stream_memory_open((type), (zstr)) #else -# define HT_UNPROTECT_RECURSION(ht) GC_UNPROTECT_RECURSION(ht) +# define php_http_mem_stream_open(type, zstr) php_stream_memory_open((type), (zstr)->val, (zstr)->len) +# define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args) +# define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args) #endif -#if PHP_VERSION_ID >= 70400 -# define PHP_WRITE_PROP_HANDLER_TYPE zval * -# define PHP_WRITE_PROP_HANDLER_RETURN(v) return v -#else -# define PHP_WRITE_PROP_HANDLER_TYPE void -# define PHP_WRITE_PROP_HANDLER_RETURN(v) -#endif +#define HT_IS_RECURSIVE(ht) GC_IS_RECURSIVE(ht) +#define HT_PROTECT_RECURSION(ht) GC_PROTECT_RECURSION(ht) +#define HT_UNPROTECT_RECURSION(ht) GC_UNPROTECT_RECURSION(ht) + +#ifndef convert_to_explicit_type +# define convert_to_explicit_type(pzv, type) \ + do { \ + switch (type) { \ + case IS_NULL: \ + convert_to_null(pzv); \ + break; \ + case IS_LONG: \ + convert_to_long(pzv); \ + break; \ + case IS_DOUBLE: \ + convert_to_double(pzv); \ + break; \ + case _IS_BOOL: \ + convert_to_boolean(pzv); \ + break; \ + case IS_ARRAY: \ + convert_to_array(pzv); \ + break; \ + case IS_OBJECT: \ + convert_to_object(pzv); \ + break; \ + case IS_STRING: \ + convert_to_string(pzv); \ + break; \ + default: \ + assert(0); \ + break; \ + } \ + } while (0); +#endif static inline void *PHP_HTTP_OBJ(zend_object *zo, zval *zv) { if (!zo) { @@ -150,16 +158,8 @@ static inline void *PHP_HTTP_OBJ(zend_object *zo, zval *zv) static inline zend_string *php_http_cs2zs(char *s, size_t l) { - zend_string *str = erealloc(s, sizeof(*str) + l); - - memmove(str->val, str, l); - str->val[l] = 0; - str->len = l; - str->h = 0; - - GC_SET_REFCOUNT(str, 1); - GC_TYPE_INFO(str) = IS_STRING; - + zend_string *str = zend_string_init(s, l, 0); + efree(s); return str; } @@ -180,9 +180,6 @@ static inline ZEND_RESULT_CODE php_http_ini_entry(const char *name_str, size_t n return FAILURE; } -#define Z_ISUSER(zv) (Z_TYPE(zv) <= 10) -#define Z_ISUSER_P(zvp) Z_ISUSER(*(zvp)) - /* return object(values) */ #define ZVAL_OBJECT(z, o, addref) \ ZVAL_OBJ(z, o); \ diff --git a/src/php_http_negotiate.c b/src/php_http_negotiate.c index cd09d37..3a5548e 100644 --- a/src/php_http_negotiate.c +++ b/src/php_http_negotiate.c @@ -16,9 +16,8 @@ # define PHP_HTTP_DEBUG_NEG 0 #endif -static int php_http_negotiate_sort(const void *first, const void *second) +static int php_http_negotiate_sort(Bucket *b1, Bucket *b2) { - Bucket *b1 = (Bucket *) first, *b2 = (Bucket *) second; int result = numeric_compare_function(&b1->val, &b2->val); return (result > 0 ? -1 : (result < 0 ? 1 : 0)); diff --git a/src/php_http_options.c b/src/php_http_options.c index 65a27af..94d703e 100644 --- a/src/php_http_options.c +++ b/src/php_http_options.c @@ -16,7 +16,7 @@ static void php_http_options_hash_dtor(zval *pData) { php_http_option_t *opt = Z_PTR_P(pData); - zval_internal_dtor(&opt->defval); + zval_internal_ptr_dtor(&opt->defval); zend_hash_destroy(&opt->suboptions.options); zend_string_release(opt->name); pefree(opt, opt->persistent); diff --git a/src/php_http_params.c b/src/php_http_params.c index 92c1441..f40b89f 100644 --- a/src/php_http_params.c +++ b/src/php_http_params.c @@ -20,7 +20,7 @@ static php_http_params_opts_t def_opts = { def_param_sep_ptr, def_arg_sep_ptr, def_val_sep_ptr, - {{0}}, + {{0}, {0}, {0}}, PHP_HTTP_PARAMS_DEFAULT }; @@ -677,8 +677,9 @@ static void skip_sep(size_t skip, php_http_params_state_t *state, php_http_param HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t *opts) { - php_http_params_state_t state = {{NULL,0}, {NULL,0}, {NULL,0}, {NULL,0}, {NULL,NULL,NULL}, 0, 0}; + php_http_params_state_t state; + memset(&state, 0, sizeof(state)); state.input.str = opts->input.str; state.input.len = opts->input.len; @@ -1068,16 +1069,16 @@ PHP_METHOD(HttpParams, __construct) { switch (ZEND_NUM_ARGS()) { case 5: - zend_update_property_long(php_http_params_class_entry, getThis(), ZEND_STRL("flags"), flags); + zend_update_property_long(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("flags"), flags); /* no break */ case 4: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("val_sep"), val_sep); /* no break */ case 3: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("arg_sep"), arg_sep); /* no break */ case 2: - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("param_sep"), param_sep); /* no break */ } @@ -1086,7 +1087,7 @@ PHP_METHOD(HttpParams, __construct) case IS_OBJECT: case IS_ARRAY: convert_to_array(zparams); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), zparams); break; default: zs = zval_get_string(zparams); @@ -1095,15 +1096,15 @@ PHP_METHOD(HttpParams, __construct) php_http_params_opts_t opts = { {zs->val, zs->len}, - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0, &tmp)), - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0, &tmp)), - php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0, &tmp)), - {{0}}, flags + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("param_sep"), 0, &tmp)), + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("arg_sep"), 0, &tmp)), + php_http_params_separator_init(zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("val_sep"), 0, &tmp)), + {{0}, {0}, {0}}, flags }; array_init(&tmp); php_http_params_parse(Z_ARRVAL(tmp), &opts); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), &tmp); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), &tmp); zval_ptr_dtor(&tmp); php_http_params_separator_free(opts.param); @@ -1117,7 +1118,7 @@ PHP_METHOD(HttpParams, __construct) zval tmp; array_init(&tmp); - zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), &tmp); + zend_update_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), &tmp); zval_ptr_dtor(&tmp); } } @@ -1133,7 +1134,7 @@ PHP_METHOD(HttpParams, toArray) if (SUCCESS != zend_parse_parameters_none()) { return; } - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); RETURN_ZVAL(zparams, 1, 0); } @@ -1147,23 +1148,23 @@ PHP_METHOD(HttpParams, toString) long flags; php_http_buffer_t buf; - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); convert_to_array_ex(zparams); - flags = zval_get_long(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("flags"), 0, &flags_tmp)); + flags = zval_get_long(zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("flags"), 0, &flags_tmp)); - zpsep = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0, &psep_tmp); + zpsep = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("param_sep"), 0, &psep_tmp); if (Z_TYPE_P(zpsep) == IS_ARRAY && (tmp = zend_hash_get_current_data(Z_ARRVAL_P(zpsep)))) { psep = zval_get_string(tmp); } else { psep = zval_get_string(zpsep); } - zasep = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0, &asep_tmp); + zasep = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("arg_sep"), 0, &asep_tmp); if (Z_TYPE_P(zasep) == IS_ARRAY && (tmp = zend_hash_get_current_data(Z_ARRVAL_P(zasep)))) { asep = zval_get_string(tmp); } else { asep = zval_get_string(zasep); } - zvsep = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0, &vsep_tmp); + zvsep = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("val_sep"), 0, &vsep_tmp); if (Z_TYPE_P(zvsep) == IS_ARRAY && (tmp = zend_hash_get_current_data(Z_ARRVAL_P(zvsep)))) { vsep = zval_get_string(tmp); } else { @@ -1180,7 +1181,7 @@ PHP_METHOD(HttpParams, toString) RETVAL_STR(php_http_cs2zs(buf.data, buf.used)); } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetExists, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpParams_offsetExists, 0, 1, _IS_BOOL, 0) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpParams, offsetExists) @@ -1192,7 +1193,7 @@ PHP_METHOD(HttpParams, offsetExists) return; } - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); if (Z_TYPE_P(zparams) == IS_ARRAY && (zparam = zend_symtable_find(Z_ARRVAL_P(zparams), name))) { RETVAL_BOOL(Z_TYPE_P(zparam) != IS_NULL); @@ -1201,7 +1202,7 @@ PHP_METHOD(HttpParams, offsetExists) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetGet, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpParams_offsetGet, 0, 1, IS_MIXED, 1) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpParams, offsetGet) @@ -1213,14 +1214,14 @@ PHP_METHOD(HttpParams, offsetGet) return; } - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); if (Z_TYPE_P(zparams) == IS_ARRAY && (zparam = zend_symtable_find(Z_ARRVAL_P(zparams), name))) { RETVAL_ZVAL(zparam, 1, 0); } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetUnset, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpParams_offsetUnset, 0, 1, IS_VOID, 0) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpParams, offsetUnset) @@ -1232,14 +1233,14 @@ PHP_METHOD(HttpParams, offsetUnset) return; } - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); if (Z_TYPE_P(zparams) == IS_ARRAY) { zend_symtable_del(Z_ARRVAL_P(zparams), name); } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams_offsetSet, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpParams_offsetSet, 0, 2, IS_VOID, 0) ZEND_ARG_INFO(0, name) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO(); @@ -1248,14 +1249,14 @@ PHP_METHOD(HttpParams, offsetSet) zend_string *name; zval zparams_tmp, *zparam, *zparams, *nvalue; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &nvalue)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S!z", &name, &nvalue)) { return; } - zparams = zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), 0, &zparams_tmp); + zparams = zend_read_property(php_http_params_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("params"), 0, &zparams_tmp); convert_to_array(zparams); - if (name->len) { + if (name && name->len) { if (Z_TYPE_P(nvalue) == IS_ARRAY) { if ((zparam = zend_symtable_find(Z_ARRVAL_P(zparams), name))) { convert_to_array(zparam); @@ -1289,12 +1290,15 @@ PHP_METHOD(HttpParams, offsetSet) } } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpParams___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_params_methods[] = { 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) - ZEND_MALIAS(HttpParams, __toString, toString, ai_HttpParams_toString, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpParams, __toString, toString, ai_HttpParams___toString, ZEND_ACC_PUBLIC) PHP_ME(HttpParams, offsetExists, ai_HttpParams_offsetExists, ZEND_ACC_PUBLIC) PHP_ME(HttpParams, offsetUnset, ai_HttpParams_offsetUnset, ZEND_ACC_PUBLIC) @@ -1344,4 +1348,3 @@ PHP_MINIT_FUNCTION(http_params) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/src/php_http_querystring.c b/src/php_http_querystring.c index 391bccf..06d52c5 100644 --- a/src/php_http_querystring.c +++ b/src/php_http_querystring.c @@ -38,7 +38,7 @@ static inline void php_http_querystring_set(zval *instance, zval *params, int fl array_init(&qa); if (flags & QS_MERGE) { - zval old_tmp, *old = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0, &old_tmp); + zval old_tmp, *old = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(instance), ZEND_STRL("queryArray"), 0, &old_tmp); ZVAL_DEREF(old); if (Z_TYPE_P(old) == IS_ARRAY) { @@ -47,13 +47,13 @@ static inline void php_http_querystring_set(zval *instance, zval *params, int fl } php_http_querystring_update(&qa, params, NULL); - zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), &qa); + zend_update_property(php_http_querystring_class_entry, Z_OBJ_P(instance), ZEND_STRL("queryArray"), &qa); zval_ptr_dtor(&qa); } static inline void php_http_querystring_str(zval *instance, zval *return_value) { - zval qa_tmp, *qa = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0, &qa_tmp); + zval qa_tmp, *qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(instance), ZEND_STRL("queryArray"), 0, &qa_tmp); ZVAL_DEREF(qa); if (Z_TYPE_P(qa) == IS_ARRAY) { @@ -65,7 +65,7 @@ static inline void php_http_querystring_str(zval *instance, zval *return_value) static inline void php_http_querystring_get(zval *instance, int type, char *name, uint32_t name_len, zval *defval, zend_bool del, zval *return_value) { - zval *arrval, qarray_tmp, *qarray = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0, &qarray_tmp); + zval *arrval, qarray_tmp, *qarray = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(instance), ZEND_STRL("queryArray"), 0, &qarray_tmp); ZVAL_DEREF(qarray); if ((Z_TYPE_P(qarray) == IS_ARRAY) && (arrval = zend_symtable_str_find(Z_ARRVAL_P(qarray), name, name_len))) { @@ -98,7 +98,7 @@ ZEND_RESULT_CODE php_http_querystring_xlate(zval *dst, zval *src, const char *ie zval *entry; zend_string *xkey, *xstr; php_http_arrkey_t key; - + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(src), key.h, key.key, entry) { if (key.key) { @@ -107,7 +107,7 @@ ZEND_RESULT_CODE php_http_querystring_xlate(zval *dst, zval *src, const char *ie return FAILURE; } } - + if (Z_TYPE_P(entry) == IS_STRING) { if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_P(entry), Z_STRLEN_P(entry), &xstr, oe, ie)) { if (key.key) { @@ -123,7 +123,7 @@ ZEND_RESULT_CODE php_http_querystring_xlate(zval *dst, zval *src, const char *ie } } else if (Z_TYPE_P(entry) == IS_ARRAY) { zval subarray; - + array_init(&subarray); if (key.key) { add_assoc_zval_ex(dst, xkey->val, xkey->len, &subarray); @@ -137,7 +137,7 @@ ZEND_RESULT_CODE php_http_querystring_xlate(zval *dst, zval *src, const char *ie return FAILURE; } } - + if (key.key) { zend_string_release(xkey); } @@ -254,7 +254,7 @@ ZEND_RESULT_CODE php_http_querystring_update(zval *qarray, zval *params, zval *o /* squeeze the hash out of the zval */ if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_class_entry)) { - zval qa_tmp, *qa = zend_read_property(php_http_querystring_class_entry, params, ZEND_STRL("queryArray"), 0, &qa_tmp); + zval qa_tmp, *qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(params), ZEND_STRL("queryArray"), 0, &qa_tmp); ZVAL_DEREF(qa); convert_to_array(qa); @@ -357,7 +357,7 @@ PHP_METHOD(HttpQueryString, __construct) { zval *params = NULL; zend_error_handling zeh; - + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|z", ¶ms), invalid_arg, return); zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_querystring_class_entry(), &zeh); @@ -378,13 +378,12 @@ PHP_METHOD(HttpQueryString, getGlobalInstance) if (Z_TYPE_P(instance) == IS_OBJECT) { RETVAL_ZVAL(instance, 1, 0); } else if ((_GET = php_http_env_get_superglobal(ZEND_STRL("_GET")))) { - zval tmp, *qa; + zval *qa; + zend_string *qa_str = zend_string_init(ZEND_STRL("queryArray"), 0); ZVAL_OBJ(return_value, php_http_querystring_object_new(php_http_querystring_class_entry)); - - ZVAL_STRING(&tmp, "queryArray"); - qa = Z_OBJ_HT_P(return_value)->get_property_ptr_ptr(return_value, &tmp, BP_VAR_RW, NULL); - zval_ptr_dtor(&tmp); + qa = Z_OBJ_HT_P(return_value)->get_property_ptr_ptr(Z_OBJ_P(return_value), qa_str, BP_VAR_RW, NULL); + zend_string_release(qa_str); ZVAL_NEW_REF(_GET, _GET); ZVAL_COPY(qa, _GET); @@ -396,7 +395,7 @@ PHP_METHOD(HttpQueryString, getGlobalInstance) } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_getIterator, 0, 0, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(ai_HttpQueryString_getIterator, 0, 0, Traversable, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, getIterator) { @@ -404,10 +403,10 @@ PHP_METHOD(HttpQueryString, getIterator) php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0, &qa_tmp); + qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp); object_init_ex(return_value, spl_ce_RecursiveArrayIterator); - zend_call_method_with_1_params(return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", NULL, qa); + zend_call_method_with_1_params(Z_OBJ_P(return_value), spl_ce_RecursiveArrayIterator, NULL, "__construct", NULL, qa); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_toString, 0, 0, 0) @@ -430,7 +429,7 @@ PHP_METHOD(HttpQueryString, toArray) return; } - zqa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0, &zqa_tmp); + zqa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &zqa_tmp); RETURN_ZVAL(zqa, 1, 0); } @@ -447,7 +446,7 @@ PHP_METHOD(HttpQueryString, get) zend_long type = 0; zend_bool del = 0; zval *ztype = NULL, *defval = NULL; - + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|szzb", &name_str, &name_len, &ztype, &defval, &del)) { if (name_str && name_len) { if (ztype) { @@ -455,7 +454,7 @@ PHP_METHOD(HttpQueryString, get) type = Z_LVAL_P(ztype); } else if(Z_TYPE_P(ztype) == IS_STRING) { switch (Z_STRVAL_P(ztype)[0]) { - case 'B': + case 'B': case 'b': type = PHP_HTTP_QUERYSTRING_TYPE_BOOL; break; case 'L': case 'l': @@ -464,7 +463,7 @@ PHP_METHOD(HttpQueryString, get) case 'd': case 'D': case 'F': - case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break; + case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break; case 'S': case 's': type = PHP_HTTP_QUERYSTRING_TYPE_STRING; break; case 'A': @@ -487,11 +486,11 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, set) { zval *params; - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "z", ¶ms)) { return; } - + php_http_querystring_set(getThis(), params, QS_MERGE); RETVAL_ZVAL(getThis(), 1, 0); } @@ -505,11 +504,11 @@ PHP_METHOD(HttpQueryString, mod) zend_error_handling zeh; php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "z", ¶ms), invalid_arg, return); - + zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_querystring_class_entry(), &zeh); - ZVAL_OBJ(return_value, Z_OBJ_HT_P(instance)->clone_obj(instance)); + ZVAL_OBJ(return_value, Z_OBJ_HT_P(instance)->clone_obj(Z_OBJ_P(instance))); /* make sure we do not inherit the reference to _GET */ - SEPARATE_ZVAL(zend_read_property(Z_OBJCE_P(return_value), return_value, ZEND_STRL("queryArray"), 0, &qa_tmp)); + SEPARATE_ZVAL(zend_read_property(Z_OBJCE_P(return_value), Z_OBJ_P(return_value), ZEND_STRL("queryArray"), 0, &qa_tmp)); php_http_querystring_set(return_value, params, QS_MERGE); zend_restore_error_handling(&zeh); } @@ -551,7 +550,7 @@ PHP_METHOD(HttpQueryString, xlate) php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &ie, &ie_len, &oe, &oe_len), invalid_arg, return); array_init(&na); - qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0, &qa_tmp); + qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp); ZVAL_DEREF(qa); convert_to_array(qa); @@ -562,11 +561,34 @@ PHP_METHOD(HttpQueryString, xlate) php_http_querystring_set(getThis(), &na, 0); RETVAL_ZVAL(getThis(), 1, 0); - + zval_ptr_dtor(&na); } #endif /* HAVE_ICONV */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpQueryString___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpQueryString, __serialize) +{ + zval *zqa, zqa_tmp; + + zend_parse_parameters_none(); + + zqa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &zqa_tmp); + RETURN_ZVAL(zqa, 1, 0); +} + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpQueryString___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO(); +PHP_METHOD(HttpQueryString, __unserialize) +{ + zval *qa; + + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "a", &qa), invalid_arg, return); + php_http_querystring_set(getThis(), qa, 0); +} + ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_serialize, 0, 0, 0) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, serialize) @@ -583,7 +605,7 @@ ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, unserialize) { zval *serialized; - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "z", &serialized)) { return; } @@ -595,8 +617,8 @@ PHP_METHOD(HttpQueryString, unserialize) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetGet, 0, 0, 1) - ZEND_ARG_INFO(0, offset) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpQueryString_offsetGet, 0, 1, IS_MIXED, 1) + ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, offsetGet) { @@ -606,8 +628,8 @@ PHP_METHOD(HttpQueryString, offsetGet) if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S", &offset)) { return; } - - qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0, &qa_tmp); + + qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp); ZVAL_DEREF(qa); if (Z_TYPE_P(qa) == IS_ARRAY) { @@ -617,15 +639,15 @@ PHP_METHOD(HttpQueryString, offsetGet) } } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetSet, 0, 0, 2) - ZEND_ARG_INFO(0, offset) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpQueryString_offsetSet, 0, 2, IS_VOID, 0) + ZEND_ARG_INFO(0, name) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, offsetSet) { zend_string *offset; zval *value, param, znull; - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &offset, &value)) { return; } @@ -642,8 +664,8 @@ PHP_METHOD(HttpQueryString, offsetSet) zval_ptr_dtor(¶m); } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetExists, 0, 0, 1) - ZEND_ARG_INFO(0, offset) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpQueryString_offsetExists, 0, 1, _IS_BOOL, 0) + ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, offsetExists) { @@ -653,8 +675,8 @@ PHP_METHOD(HttpQueryString, offsetExists) if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S", &offset)) { return; } - - qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0, &qa_tmp); + + qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp); ZVAL_DEREF(qa); if (Z_TYPE_P(qa) == IS_ARRAY) { @@ -665,14 +687,14 @@ PHP_METHOD(HttpQueryString, offsetExists) RETURN_FALSE; } -ZEND_BEGIN_ARG_INFO_EX(ai_HttpQueryString_offsetUnset, 0, 0, 1) - ZEND_ARG_INFO(0, offset) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_HttpQueryString_offsetUnset, 0, 1, IS_VOID, 0) + ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO(); PHP_METHOD(HttpQueryString, offsetUnset) { zend_string *offset; zval param, znull; - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S", &offset)) { return; } @@ -684,12 +706,15 @@ PHP_METHOD(HttpQueryString, offsetUnset) zval_ptr_dtor(¶m); } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpQueryString___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_querystring_methods[] = { 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) - ZEND_MALIAS(HttpQueryString, __toString, toString, ai_HttpQueryString_toString, ZEND_ACC_PUBLIC) + ZEND_MALIAS(HttpQueryString, __toString, toString, ai_HttpQueryString___toString, ZEND_ACC_PUBLIC) PHP_ME(HttpQueryString, get, ai_HttpQueryString_get, ZEND_ACC_PUBLIC) PHP_ME(HttpQueryString, set, ai_HttpQueryString_set, ZEND_ACC_PUBLIC) @@ -712,6 +737,8 @@ static zend_function_entry php_http_querystring_methods[] = { /* Implements Serializable */ PHP_ME(HttpQueryString, serialize, ai_HttpQueryString_serialize, ZEND_ACC_PUBLIC) PHP_ME(HttpQueryString, unserialize, ai_HttpQueryString_unserialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpQueryString, __serialize, ai_HttpQueryString___serialize, ZEND_ACC_PUBLIC) + PHP_ME(HttpQueryString, __unserialize, ai_HttpQueryString___unserialize, ZEND_ACC_PUBLIC) /* Implements ArrayAccess */ PHP_ME(HttpQueryString, offsetGet, ai_HttpQueryString_offsetGet, ZEND_ACC_PUBLIC) diff --git a/src/php_http_url.c b/src/php_http_url.c index 24a13ff..459396f 100644 --- a/src/php_http_url.c +++ b/src/php_http_url.c @@ -73,7 +73,7 @@ static inline char *localhostname(void) static php_http_url_t *php_http_url_from_env(void) { zval *https, *zhost, *zport; - long port; + zend_long port; php_http_buffer_t buf; php_http_buffer_init_ex(&buf, MAX(PHP_HTTP_BUFFER_DEFAULT_SIZE, sizeof(php_http_url_t)<<2), PHP_HTTP_BUFFER_INIT_PREALLOC); @@ -535,7 +535,7 @@ HashTable *php_http_url_to_struct(const php_http_url_t *url, zval *strct) if (!strct || Z_TYPE_P(strct) == IS_ARRAY) { \ zend_hash_str_update(ht, part, lenof(part), &tmp); \ } else { \ - zend_update_property(Z_OBJCE_P(strct), strct, part, lenof(part), &tmp); \ + zend_update_property(Z_OBJCE_P(strct), Z_OBJ_P(strct), part, lenof(part), &tmp); \ zval_ptr_dtor(&tmp); \ } @@ -1021,7 +1021,7 @@ static ZEND_RESULT_CODE parse_uidn_2003(struct parse_state *state, size_t prev_l # endif efree(uhost_str); - if (error > U_ZERO_ERROR) { + if (rc > U_ZERO_ERROR) { goto error; } @@ -1984,7 +1984,7 @@ PHP_METHOD(HttpUrl, mod) if ((old_purl = php_http_url_from_struct(HASH_OF(getThis())))) { php_http_url_t *res_purl; - ZVAL_OBJ(return_value, zend_objects_clone_obj(getThis())); + ZVAL_OBJ(return_value, zend_objects_clone_obj(Z_OBJ_P(getThis()))); res_purl = php_http_url_mod(old_purl, new_purl, flags); php_http_url_to_struct(res_purl, return_value); @@ -2034,11 +2034,14 @@ PHP_METHOD(HttpUrl, toArray) php_http_url_free(&purl); } +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpUrl___toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO(); + static zend_function_entry php_http_url_methods[] = { 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) + ZEND_MALIAS(HttpUrl, __toString, toString, ai_HttpUrl___toString, ZEND_ACC_PUBLIC) PHP_ME(HttpUrl, toArray, ai_HttpUrl_toArray, ZEND_ACC_PUBLIC) EMPTY_FUNCTION_ENTRY }; @@ -2108,4 +2111,3 @@ PHP_MINIT_FUNCTION(http_url) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/tests/client002.phpt b/tests/client002.phpt index 6f01a44..d020f16 100644 --- a/tests/client002.phpt +++ b/tests/client002.phpt @@ -14,10 +14,13 @@ echo "Test\n"; class Observer implements SplObserver { + #[ReturnTypeWillChange] function update(SplSubject $client, http\Client\Request $request = null, StdClass $progress = null) { echo "P"; - if ($progress->info !== "prepare" && $client->getProgressInfo($request) != $progress) { - var_dump($progress); + /* fence against buggy infof() calls in some curl versions */ + $compare = $client->getProgressInfo($request); + if ($progress->info !== "prepare" && $compare && $compare != $progress) { + var_dump($progress, $compare); } } } diff --git a/tests/client009.phpt b/tests/client009.phpt index 6aea225..0eb08f7 100644 --- a/tests/client009.phpt +++ b/tests/client009.phpt @@ -19,24 +19,33 @@ function x($a) { } server("env.inc", function($port) { + $client = new http\Client; + $client->setCookies(array("test" => "bar")); + $client->addCookies(array("foo" => "test")); $request = new http\Client\Request("GET", "http://localhost:$port"); + $client->enqueue($request); + $client->send(); + echo $client->getResponse()->getBody()->toString(); - foreach (http\Client::getAvailableDrivers() as $driver) { - $client = new http\Client($driver); - $client->setCookies(array("test" => "bar")); - $client->addCookies(array("foo" => "test")); - $client->enqueue($request); - $client->send(); - var_dump($client->getResponse()->getBody()->toString()); - $request->setOptions(array("cookies" => x($client->getCookies()))); - $client->requeue($request); - $client->send(); - var_dump($client->getResponse()->getBody()->toString()); - } + $request->setOptions(array("cookies" => x($client->getCookies()))); + $client->requeue($request); + $client->send(); + + echo $client->getResponse()->getBody()->toString(); }); ?> Done ---EXPECTREGEX-- +--EXPECT-- Test -(?:string\(46\) "Array\n\(\n \[test\] \=\> bar\n \[foo\] \=\> test\n\)\n"\nstring\(46\) "Array\n\(\n \[test\] \=\> test\n \[foo\] \=\> bar\n\)\n"\n)+Done +Array +( + [test] => bar + [foo] => test +) +Array +( + [test] => test + [foo] => bar +) +Done diff --git a/tests/client012.phpt b/tests/client012.phpt index bb599db..3b1e1c0 100644 --- a/tests/client012.phpt +++ b/tests/client012.phpt @@ -1,14 +1,19 @@ --TEST-- client ssl --SKIPIF-- - --FILE-- -getSslOptions() ); -$client->attach($observer = new class implements SplObserver { +$client->attach($observer = new class implements SplObserver { public $data = []; + + #[ReturnTypeWillChange] function update(SplSubject $client, $req = null, $progress = null) { $ti = $client->getTransferInfo($req); if (isset($ti->tls_session["internals"])) { @@ -43,7 +50,9 @@ switch ($client->getTransferInfo($req)->tls_session["backend"]) { case "openssl": case "gnutls": if (count($observer->data) < 1) { - die("failed count(ssl.internals) >= 1\n"); + printf("%s: failed count(ssl.internals) >= 1\n", $client->getTransferInfo($req)->tls_session["backend"]); + var_dump($observer); + exit; } break; default: diff --git a/tests/client013.phpt b/tests/client013.phpt index 477edf7..962d448 100644 --- a/tests/client013.phpt +++ b/tests/client013.phpt @@ -16,11 +16,13 @@ class Client extends http\Client { public $pi; } class ProgressObserver1 implements SplObserver { + #[ReturnTypeWillChange] function update(SplSubject $c, $r = null) { if ($c->getProgressInfo($r)) $c->pi .= "-"; } } class ProgressObserver2 implements SplObserver { + #[ReturnTypeWillChange] function update(SplSubject $c, $r = null) { if ($c->getProgressInfo($r)) $c->pi .= "."; } @@ -30,6 +32,7 @@ class CallbackObserver implements SplObserver { function __construct($callback) { $this->callback = $callback; } + #[ReturnTypeWillChange] function update(SplSubject $c, $r = null) { call_user_func($this->callback, $c, $r); } diff --git a/tests/client021.phpt b/tests/client021.phpt index 702685d..f8eeeb5 100644 --- a/tests/client021.phpt +++ b/tests/client021.phpt @@ -4,6 +4,10 @@ client cookies --FILE-- --FILE-- -enablePipelining(false); --EXPECTF-- Test -Deprecated: Function http\Client::enableEvents() is deprecated in %sclient024.php on line %d +Deprecated: Method http\Client::enableEvents() is deprecated in %sclient024.php on line %d -Deprecated: Function http\Client::enablePipelining() is deprecated in %sclient024.php on line %d +Deprecated: Method http\Client::enablePipelining() is deprecated in %sclient024.php on line %d ===DONE=== diff --git a/tests/client025.phpt b/tests/client025.phpt index 4cb63af..21f4c2d 100644 --- a/tests/client025.phpt +++ b/tests/client025.phpt @@ -36,8 +36,8 @@ PUT / HTTP/1.1 Accept: */* Content-Length: %d Content-Range: bytes 1-2/3 -Expect: 100-continue -Host: localhost:%d +%r(Expect: 100-continue +)?%rHost: localhost:%d User-Agent: %s X-Original-Content-Length: %d diff --git a/tests/client027.phpt b/tests/client027.phpt index d33a58d..b87fa65 100644 --- a/tests/client027.phpt +++ b/tests/client027.phpt @@ -15,20 +15,22 @@ echo "Test\n"; server("cookie.inc", function($port) { $client = new http\Client(null, "cookies"); - $client->configure(array("pipelining" => false)); + $client->configure(array("pipelining" => false, "share_cookies" => false)); + $request = new http\Client\Request("GET", "http://localhost:$port?r1"); $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => 1]); + $client->requeue($request); + $client->send(); + dump_responses($client, ["counter" => 2]); + $client->dequeue($request); + $request = new http\Client\Request("GET", "http://localhost:$port?r2"); $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => 1]); }); ?> @@ -44,7 +46,7 @@ Set-Cookie: counter=2; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=2; +Set-Cookie: counter=1; X-Original-Transfer-Encoding: chunked ===DONE=== diff --git a/tests/client030.phpt b/tests/client030.phpt index 8514b4e..5a5155e 100644 --- a/tests/client030.phpt +++ b/tests/client030.phpt @@ -12,6 +12,7 @@ echo "Test\n"; include "helper/server.inc"; class test implements SplObserver { + #[ReturnTypeWillChange] function update(SplSubject $client) { $client->once(); } diff --git a/tests/client031.phpt b/tests/client031.phpt index 3211735..73ce7e4 100644 --- a/tests/client031.phpt +++ b/tests/client031.phpt @@ -16,32 +16,29 @@ echo "Test\n"; server("cookie.inc", function($port) { $client = new http\Client(null, "cookies"); $client->configure(array("share_cookies" => false)); + $request = new http\Client\Request("GET", "http://localhost:$port"); $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => 1]); + /* requeue the previous request */ $client->requeue($request); - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); - $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); + dump_responses($client, ["counter" => 2]); + + for($i = 0; $i < 3; ++$i) { + /* new requests */ + $request = new http\Client\Request("GET", "http://localhost:$port"); + $client->enqueue($request); + $client->send(); + dump_responses($client, ["counter" => 1]); } - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); + + /* requeue the previous request */ + $client->requeue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => 2]); }); ?> @@ -53,11 +50,11 @@ Set-Cookie: counter=1; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=1; +Set-Cookie: counter=2; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=2; +Set-Cookie: counter=1; X-Original-Transfer-Encoding: chunked Etag: "" @@ -68,4 +65,8 @@ Etag: "" Set-Cookie: counter=1; X-Original-Transfer-Encoding: chunked +Etag: "" +Set-Cookie: counter=2; +X-Original-Transfer-Encoding: chunked + ===DONE=== diff --git a/tests/client032.phpt b/tests/client032.phpt index d8dfb2b..954a68e 100644 --- a/tests/client032.phpt +++ b/tests/client032.phpt @@ -16,32 +16,29 @@ echo "Test\n"; server("cookie.inc", function($port) { $client = new http\Client(null, "cookies"); $client->configure(array("share_cookies" => true)); + $request = new http\Client\Request("GET", "http://localhost:$port"); $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => 1]); + /* requeue the previous request */ $client->requeue($request); - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); - $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); + dump_responses($client, ["counter" => 2]); + + for($i = 3; $i < 6; ++$i) { + /* new requests */ + $request = new http\Client\Request("GET", "http://localhost:$port"); + $client->enqueue($request); + $client->send(); + dump_responses($client, ["counter" => $i]); } - $request = new http\Client\Request("GET", "http://localhost:$port"); - $client->enqueue($request); + + /* requeue the previous request */ + $client->requeue($request); $client->send(); - while (($r = $client->getResponse())) { - dump_headers(null, $r->getHeaders()); - } + dump_responses($client, ["counter" => $i]); }); ?> @@ -57,15 +54,19 @@ Set-Cookie: counter=2; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=2; +Set-Cookie: counter=3; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=3; +Set-Cookie: counter=4; X-Original-Transfer-Encoding: chunked Etag: "" -Set-Cookie: counter=4; +Set-Cookie: counter=5; +X-Original-Transfer-Encoding: chunked + +Etag: "" +Set-Cookie: counter=6; X-Original-Transfer-Encoding: chunked ===DONE=== diff --git a/tests/envreset001.phpt b/tests/envreset001.phpt new file mode 100644 index 0000000..547fef0 --- /dev/null +++ b/tests/envreset001.phpt @@ -0,0 +1,65 @@ +--TEST-- +env reset +--SKIPIF-- + +--POST-- +a=b +--ENV-- +HTTP_HOST=foo.bar +HTTP_ACCEPT=*/* +--FILE-- + +==DONE== +--EXPECTF-- +NULL +string(%d) "foo.bar" +string(%d) "application/x-www-form-urlencoded" +array(4) { + ["Accept"]=> + string(3) "*/*" + ["Content-Length"]=> + string(1) "3" + ["Content-Type"]=> + string(33) "application/x-www-form-urlencoded" + ["Host"]=> + string(7) "foo.bar" +} +NULL +string(%d) "foo.bar" +string(%d) "yesyes" +NULL +string(%d) "application/x-www-form-urlencoded" +array(4) { + ["Accept"]=> + string(3) "*/*" + ["Content-Length"]=> + string(1) "3" + ["Content-Type"]=> + string(33) "application/x-www-form-urlencoded" + ["Nono"]=> + string(6) "yesyes" +} +==DONE== diff --git a/tests/envresponse016.phpt b/tests/envresponse016.phpt index 8d48c93..3476216 100644 --- a/tests/envresponse016.phpt +++ b/tests/envresponse016.phpt @@ -10,7 +10,7 @@ include "skipif.inc"; echo "Test\n"; class closer extends php_user_filter { - function filter ($in, $out, &$consumed, $closing) { + function filter ($in, $out, &$consumed, $closing) : int { while ($bucket = stream_bucket_make_writeable($in)) { stream_bucket_append($out, $bucket); } diff --git a/tests/gh-issue11.phpt b/tests/gh-issue11.phpt index aba014a..16948cc 100644 --- a/tests/gh-issue11.phpt +++ b/tests/gh-issue11.phpt @@ -3,7 +3,7 @@ crash when query string has nested array keys --SKIPIF-- --FILE-- --FILE-- - diff --git a/tests/helper/dump.inc b/tests/helper/dump.inc index 452a715..59d258c 100644 --- a/tests/helper/dump.inc +++ b/tests/helper/dump.inc @@ -18,10 +18,25 @@ function dump_message($stream, http\Message $msg, $parent = false) { fprintf($stream, "%s\n", $msg->getInfo()); dump_headers($stream, $msg->getHeaders()); $msg->getBody()->toStream($stream); - + if ($parent && ($msg = $msg->getParentMessage())) { dump_message($stream, $msg, true); } } -?> \ No newline at end of file +function dump_responses($client, array $expect_cookie = []) { + while (($r = $client->getResponse())) { + dump_headers(null, $r->getHeaders()); + if ($expect_cookie) { + $got_cookies = array_merge(...array_map(function($c) { + return $c->getCookies(); + }, $r->getCookies())); + if ($expect_cookie != $got_cookies) { + var_dump($expect_cookie, $got_cookies); + echo $r->toString(true); + } + } + } + +} +?> diff --git a/tests/helper/server.inc b/tests/helper/server.inc index 9ca96cd..b5bc3b7 100644 --- a/tests/helper/server.inc +++ b/tests/helper/server.inc @@ -7,9 +7,9 @@ function logger() { if (!ini_get("date.timezone")) { date_default_timezone_set(@date_default_timezone_get()); } - error_log(sprintf("%s(%s): %s", - basename(getenv("SCRIPT_FILENAME"), ".php"), - basename(current(get_included_files()), ".inc"), + error_log(sprintf("%s(%s): %s", + basename(getenv("SCRIPT_FILENAME"), ".php"), + basename(current(get_included_files()), ".inc"), call_user_func_array("sprintf", func_get_args()) )); } @@ -24,7 +24,7 @@ if ($php) { define("PHP_BIN", PHP_BINDIR.DIRECTORY_SEPARATOR."php"); } -foreach (array("raphf", "propro", "http") as $ext) { +foreach (array("raphf", "http") as $ext) { if (!extension_loaded($ext)) { dl(ext_lib_name($ext)); } @@ -72,11 +72,11 @@ function ext_lib_name($ext) { } function serve($cb) { - /* stream_socket_server() automatically sets SO_REUSEADDR, + /* stream_socket_server() automatically sets SO_REUSEADDR, * which is, well, bad if the tests are run in parallel */ $offset = rand(0,2000); - foreach (range(8000+$offset, 9000+$offset) as $port) { + foreach (range(40000+$offset, 50000+$offset) as $port) { logger("serve: Trying port %d", $port); if (($server = @stream_socket_server("tcp://localhost:$port"))) { fprintf(STDERR, "%s\n", $port); @@ -131,7 +131,7 @@ function server($handler, $cb) { $args[] = $argList[$i]; } } - foreach (['raphf', 'propro', 'http'] as $ext) { + foreach (['raphf', 'http'] as $ext) { if (null !== $arg = get_extension_load_arg(PHP_BIN, $args, $ext)) { $args[] = $arg; } @@ -149,28 +149,28 @@ function nghttpd($cb) { $stdin = $pipes[0]; $stdout = $pipes[1]; $stderr = $pipes[2]; - + sleep(1); $status = proc_get_status($proc); logger("nghttpd: %s", new http\Params($status)); if (!$status["running"]) { continue; } - + try { $cb($port, $stdin, $stdout, $stderr); } catch (Exception $e) { echo $e,"\n"; } - + proc_terminate($proc); - + fpassthru($stderr); fpassthru($stdout); return; } } - + } function proc($bin, $args, $cb) { @@ -186,7 +186,7 @@ function proc($bin, $args, $cb) { $port = trim(fgets($stderr)); $R = array($stderr); $W = array(); $E = array(); } while (is_numeric($port) && stream_select($R, $W, $E, 0, 10000)); - + if (is_numeric($port)) { try { $cb($port, $stdin, $stdout, $stderr); @@ -194,9 +194,9 @@ function proc($bin, $args, $cb) { echo $e,"\n"; } } - + proc_terminate($proc); - + fpassthru($stderr); fpassthru($stdout); } diff --git a/tests/message002.phpt b/tests/message002.phpt index 573fdbd..da0b799 100644 --- a/tests/message002.phpt +++ b/tests/message002.phpt @@ -42,7 +42,8 @@ object(%s)#%d (13) { ["type":protected]=> int(1) ["body":protected]=> - NULL + object(http\Message\Body)#3 (0) { + } ["requestMethod":protected]=> string(4) "POST" ["requestUrl":protected]=> diff --git a/tests/message006.phpt b/tests/message006.phpt deleted file mode 100644 index 4d1a693..0000000 --- a/tests/message006.phpt +++ /dev/null @@ -1,46 +0,0 @@ ---TEST-- -message var_dump with inherited property with increased access level ---SKIPIF-- - ---FILE-- -headers["foo"] = "bar"; -var_dump($m); - -?> -DONE ---EXPECTF-- -Test -object(c)#%d (9) { - ["headers"]=> - array(1) { - ["foo"]=> - string(3) "bar" - } - ["type":protected]=> - int(0) - ["body":protected]=> - NULL - ["requestMethod":protected]=> - string(0) "" - ["requestUrl":protected]=> - string(0) "" - ["responseStatus":protected]=> - string(0) "" - ["responseCode":protected]=> - int(0) - ["httpVersion":protected]=> - string(3) "1.1" - ["parentMessage":protected]=> - NULL -} -DONE diff --git a/tests/phpinfo.phpt b/tests/phpinfo.phpt index c1f58d9..0e557a0 100644 --- a/tests/phpinfo.phpt +++ b/tests/phpinfo.phpt @@ -14,6 +14,6 @@ Done Test %a HTTP Support => enabled -Extension Version => 3.%s +Extension Version => 4.%s %a Done diff --git a/tests/propertyproxy001.phpt b/tests/propertyproxy001.phpt deleted file mode 100644 index 88a3543..0000000 --- a/tests/propertyproxy001.phpt +++ /dev/null @@ -1,104 +0,0 @@ ---TEST-- -property proxy ---SKIPIF-- - ---FILE-- -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"]; - $h = 1; - var_dump($this->headers); - - $x = 2; - var_dump($this->headers); - } - function test4() { - $this->headers["bynext"][] = 1; - $this->headers["bynext"][] = 2; - $this->headers["bynext"][] = 3; - var_dump($this->headers); - } -} - -$m=new m; -$m->test1(); -$m->test2(); -$m->test3(); -$m->test4(); -echo $m,"\n"; - -?> -DONE ---EXPECTF-- -array(1) { - ["bykey"]=> - int(1) -} -array(2) { - ["bykey"]=> - int(1) - ["by1ref"]=> - int(2) -} -array(3) { - ["bykey"]=> - int(1) - ["by1ref"]=> - int(2) - ["by2ref"]=> - int(1) -} -array(4) { - ["bykey"]=> - int(1) - ["by1ref"]=> - int(2) - ["by2ref"]=> - int(1) - ["byXref"]=> - int(2) -} -array(5) { - ["bykey"]=> - int(1) - ["by1ref"]=> - int(2) - ["by2ref"]=> - int(1) - ["byXref"]=> - int(2) - ["bynext"]=> - array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - int(3) - } -} -bykey: 1 -by1ref: 2 -by2ref: 1 -byXref: 2 -bynext: 1 -bynext: 2 -bynext: 3 - -DONE - diff --git a/tests/querystring001.phpt b/tests/querystring001.phpt deleted file mode 100644 index e2e563d..0000000 --- a/tests/querystring001.phpt +++ /dev/null @@ -1,180 +0,0 @@ ---TEST-- -query string ---SKIPIF-- - ---GET-- -str=abc&num=-123&dec=123.123&bool=1&arr[]=1&arr[]=2&ma[l1][l2]=2&ma[l2][l3][l4]=3 ---FILE-- -getString("str")); -var_dump($q->getInt("num")); -var_dump($q->getFloat("dec")); -var_dump($q->getInt("dec")); -var_dump($q->getFloat("dec")); -var_dump($q->getBool("bool")); -var_dump($q->getInt("bool")); -var_dump($q->getBool("num")); -var_dump($q->getInt("num")); -var_dump($q->getArray("arr")); -var_dump($q->getArray("ma")); -var_dump($q->getObject("arr")); -var_dump($q->getObject("ma")); - -$s = $q->toString(); - -printf("\nClone modifications do not alter global instance:\n"); -$q->mod(array("arr" => array(3 => 3))); -printf("%s\n", $q); - -printf("\nClone modifications do not alter standard instance:\n"); -$q2 = new http\QueryString($s); -$q3 = $q2->mod(array("arr" => array(3 => 3))); -printf("%s\n%s\n", $q2, $q3); -#var_dump($q2, $q3); - -printf("\nIterator:\n"); -$it = new RecursiveIteratorIterator($q2, RecursiveIteratorIterator::SELF_FIRST); -foreach ($it as $k => $v) { - $i = $it->getDepth()*8; - @printf("%{$i}s: %s\n", $k, $v); -} - -printf("\nReplace a multi dimensional key:\n"); -printf("%s\n", $q2->mod(array("ma" => null))->set(array("ma" => array("l1" => false)))); - -printf("\nXlate:\n"); -$qu = new http\QueryString("ü=ö"); -printf("utf8: %s\n", $qu); -printf("latin1: %s\n", method_exists($qu, "xlate") ? $qu->xlate("utf-8", "latin1") : "%FC=%F6"); - -printf("\nOffsets:\n"); -var_dump($q2["ma"]); -$q2["ma"] = array("bye"); -var_dump($q2["ma"]); -var_dump(isset($q2["ma"])); -unset($q2["ma"]); -var_dump(isset($q2["ma"])); - -echo "Done\n"; -?> ---EXPECTF-- -Test - -Global instance: -str=abc&num=-123&dec=123.123&bool=1&arr%5B0%5D=1&arr%5B1%5D=2&ma%5Bl1%5D%5Bl2%5D=2&ma%5Bl2%5D%5Bl3%5D%5Bl4%5D=3 - -Standard getters: -string(3) "abc" -int(-123) -float(123.123) -int(123) -float(123.123) -bool(true) -int(1) -bool(true) -int(-123) -array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "2" -} -array(2) { - ["l1"]=> - array(1) { - ["l2"]=> - string(1) "2" - } - ["l2"]=> - array(1) { - ["l3"]=> - array(1) { - ["l4"]=> - string(1) "3" - } - } -} -object(stdClass)#%d (2) { - [0]=> - string(1) "1" - [1]=> - string(1) "2" -} -object(stdClass)#%d (2) { - ["l1"]=> - array(1) { - ["l2"]=> - string(1) "2" - } - ["l2"]=> - array(1) { - ["l3"]=> - array(1) { - ["l4"]=> - string(1) "3" - } - } -} - -Clone modifications do not alter global instance: -str=abc&num=-123&dec=123.123&bool=1&arr%5B0%5D=1&arr%5B1%5D=2&ma%5Bl1%5D%5Bl2%5D=2&ma%5Bl2%5D%5Bl3%5D%5Bl4%5D=3 - -Clone modifications do not alter standard instance: -str=abc&num=-123&dec=123.123&bool=1&arr%5B0%5D=1&arr%5B1%5D=2&ma%5Bl1%5D%5Bl2%5D=2&ma%5Bl2%5D%5Bl3%5D%5Bl4%5D=3 -str=abc&num=-123&dec=123.123&bool=1&arr%5B0%5D=1&arr%5B1%5D=2&arr%5B3%5D=3&ma%5Bl1%5D%5Bl2%5D=2&ma%5Bl2%5D%5Bl3%5D%5Bl4%5D=3 - -Iterator: -str: abc -num: -123 -dec: 123.123 -bool: 1 -arr: Array - 0: 1 - 1: 2 -ma: Array - l1: Array - l2: 2 - l2: Array - l3: Array - l4: 3 - -Replace a multi dimensional key: -str=abc&num=-123&dec=123.123&bool=1&arr%5B0%5D=1&arr%5B1%5D=2&ma%5Bl1%5D= - -Xlate: -utf8: %C3%BC=%C3%B6 -latin1: %FC=%F6 - -Offsets: -array(2) { - ["l1"]=> - array(1) { - ["l2"]=> - string(1) "2" - } - ["l2"]=> - array(1) { - ["l3"]=> - array(1) { - ["l4"]=> - string(1) "3" - } - } -} -array(1) { - [0]=> - string(3) "bye" -} -bool(true) -bool(false) -Done diff --git a/tests/skipif.inc b/tests/skipif.inc index 85dbac2..76c3bd7 100644 --- a/tests/skipif.inc +++ b/tests/skipif.inc @@ -1,13 +1,17 @@ =")) { + die("skip need at least libcurl version $version\n"); } } @@ -49,7 +53,7 @@ function skip_http2_test($message = "skip need http2 support") { if (!(http\Client\Curl\FEATURES & http\Client\Curl\Features\HTTP2)) { die("$message (FEATURES & HTTP2)\n"); } - foreach (explode(":", $_ENV["PATH"]) as $path) { + foreach (explode(":", getenv("PATH")) as $path) { if (is_executable($path . "/nghttpd")) { return; } diff --git a/tests/urlparser004.phpt b/tests/urlparser004.phpt index 36d6983..4eab3b7 100644 --- a/tests/urlparser004.phpt +++ b/tests/urlparser004.phpt @@ -11,7 +11,8 @@ if (!defined("http\\Url::PARSE_MBLOC") or --FILE-- --FILE--