prepare v4.2.5 master
authorMichael Wallner <mike@php.net>
Mon, 5 Feb 2024 19:36:16 +0000 (20:36 +0100)
committerMichael Wallner <mike@php.net>
Mon, 5 Feb 2024 19:36:16 +0000 (20:36 +0100)
* Fix incompatible pointer types (32-bit) (see gh issue #134)
* Fix glitch in CURL_VERSION_TLSAUTH_SRP autoconf probe (see gh issue #133)

49 files changed:
.github/Makefile [new file with mode: 0644]
.github/workflows/ci.yml
.github/workflows/curl-matrix.yml [new file with mode: 0644]
.gitignore
BUGS
CHANGELOG.md
autoconf/pecl/libbrotli.m4
autoconf/pecl/libcurl.m4
autoconf/pecl/pecl.m4
config9.m4
package.xml
php_http.h
scripts/curlver.dist [new file with mode: 0644]
scripts/gen_curlinfo.php
scripts/gen_github_workflow_ci.php
scripts/gen_github_workflow_curl-matrix.php [new file with mode: 0755]
src/php_http_client.c
src/php_http_client.h
src/php_http_client_curl.c
src/php_http_client_curl_event.c
src/php_http_client_curl_user.c
src/php_http_cookie.c
src/php_http_env.c
src/php_http_env.h
src/php_http_header.c
src/php_http_message.c
src/php_http_message_body.c
src/php_http_misc.h
src/php_http_params.c
src/php_http_querystring.c
src/php_http_url.c
tests/client002.phpt
tests/client009.phpt
tests/client012.phpt
tests/client013.phpt
tests/client021.phpt
tests/client024.phpt
tests/client025.phpt
tests/client027.phpt
tests/client030.phpt
tests/client031.phpt
tests/client032.phpt
tests/envreset001.phpt [new file with mode: 0644]
tests/envresponse016.phpt
tests/helper/dump.inc
tests/helper/server.inc
tests/message002.phpt
tests/skipif.inc
tests/urlparser010.phpt

diff --git a/.github/Makefile b/.github/Makefile
new file mode 100644 (file)
index 0000000..29166f3
--- /dev/null
@@ -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
index 5e56d837a713d387c5985cd4e4c7f49989c568b6..e04f594253ff10de7427e41dcb249edf25324ed5 100644 (file)
@@ -7,26 +7,30 @@ on:
   pull_request:
 
 jobs:
-  master-0:
-    name: master-0
+  next-0:
+    name: "next-0 (master)"
     continue-on-error: true
     env:
       PHP: "master"
       enable_debug: "yes"
       enable_zts: "yes"
       enable_iconv: "yes"
-    runs-on: ubuntu-20.04
+      TEST_PHP_ARGS: "-d error_reporting=24575"
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -43,28 +47,107 @@ jobs:
         run: |
           make -f scripts/ci/Makefile test
 
-  cur-none-0:
-    name: cur-none-0
+  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-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -82,24 +165,27 @@ jobs:
           make -f scripts/ci/Makefile test
 
   cur-dbg-zts-0:
-    name: cur-dbg-zts-0
+    name: "cur-dbg-zts-0 (8.2)"
     env:
-      PHP: "8.0"
+      PHP: "8.2"
       enable_debug: "yes"
       enable_zts: "yes"
       enable_iconv: "yes"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -117,24 +203,27 @@ jobs:
           make -f scripts/ci/Makefile test
 
   cur-dbg-zts-1:
-    name: cur-dbg-zts-1
+    name: "cur-dbg-zts-1 (8.2)"
     env:
-      PHP: "8.0"
+      PHP: "8.2"
       enable_debug: "no"
       enable_zts: "yes"
       enable_iconv: "yes"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -152,24 +241,27 @@ jobs:
           make -f scripts/ci/Makefile test
 
   cur-dbg-zts-2:
-    name: cur-dbg-zts-2
+    name: "cur-dbg-zts-2 (8.2)"
     env:
-      PHP: "8.0"
+      PHP: "8.2"
       enable_debug: "yes"
       enable_zts: "no"
       enable_iconv: "yes"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -187,24 +279,27 @@ jobs:
           make -f scripts/ci/Makefile test
 
   cur-dbg-zts-3:
-    name: cur-dbg-zts-3
+    name: "cur-dbg-zts-3 (8.2)"
     env:
-      PHP: "8.0"
+      PHP: "8.2"
       enable_debug: "no"
       enable_zts: "no"
       enable_iconv: "yes"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -222,27 +317,30 @@ jobs:
           make -f scripts/ci/Makefile test
 
   cur-cov-0:
-    name: cur-cov-0
+    name: "cur-cov-0 (8.2)"
     env:
       CFLAGS: "-O0 -g --coverage"
       CXXFLAGS: "-O0 -g --coverage"
-      PHP: "8.0"
+      PHP: "8.2"
       enable_iconv: "yes"
       with_http_libicu_dir: "yes"
       with_http_libidn_dir: "no"
       with_http_libidn2_dir: "no"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -265,27 +363,30 @@ jobs:
           bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy
 
   cur-cov-1:
-    name: cur-cov-1
+    name: "cur-cov-1 (8.2)"
     env:
       CFLAGS: "-O0 -g --coverage"
       CXXFLAGS: "-O0 -g --coverage"
-      PHP: "8.0"
+      PHP: "8.2"
       enable_iconv: "yes"
       with_http_libicu_dir: "no"
       with_http_libidn_dir: "yes"
       with_http_libidn2_dir: "no"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
@@ -308,27 +409,30 @@ jobs:
           bash <(curl -s https://codecov.io/bash) -X xcode -X coveragepy
 
   cur-cov-2:
-    name: cur-cov-2
+    name: "cur-cov-2 (8.2)"
     env:
       CFLAGS: "-O0 -g --coverage"
       CXXFLAGS: "-O0 -g --coverage"
-      PHP: "8.0"
+      PHP: "8.2"
       enable_iconv: "yes"
       with_http_libicu_dir: "no"
       with_http_libidn_dir: "no"
       with_http_libidn2_dir: "yes"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
diff --git a/.github/workflows/curl-matrix.yml b/.github/workflows/curl-matrix.yml
new file mode 100644 (file)
index 0000000..a37e548
--- /dev/null
@@ -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
+
index 95f72a28281acbb05db5529e90af406dc42cd6d3..99028c98e2a0ac08d5554e04a6721c807dc5cb46 100644 (file)
@@ -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/BUGS b/BUGS
index 4c2ad80b6025a49554ce2b2c54e6b02063385c26..0b981790dbeb4ba2cc836b1072de46cf178918ac 100644 (file)
--- 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.
index a028ba4ff978c30aa019cab844b1b00751ad9cce..47ec2a3c70de381fa545763592c1f1e07dc82354 100644 (file)
@@ -1,13 +1,87 @@
 # ChangeLog v4
 
-## 4.0.0beta2, TBR
+## 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 configure on systems which do not provide icu-config
 * Fixed gh-issue #89: Cookie handling cannot be disabled since v3.2.1
 
 ## 4.0.0beta1, 2020-09-23
 
 * PHP 8 compatibility
-       - Drop ext-propro support:  
+       - 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
index f8916e2d79cb99fc0e67accb35f9882e0195141e..aee94836ee99c6228682b8dd5ea7d7da54d42bbf 100644 (file)
@@ -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
        ], [
index fce643748743911517316e35f8d6e790c33864c0..fd0e711ec05b8b920510e068929a893ed7bf8d9b 100644 (file)
@@ -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 <curl/curl.h>
                                        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 <curl/curl.h>
+                                       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 <curl/curl.h>
                                                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
+])
index ffa45ac03fe88cf746f84378199040747f242ce6..cb2bb70e17c110d47d34d9535a8691534534bab9 100644 (file)
@@ -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
index d653a7c72fa9101be03f92cfb6b48bf4147d474f..35f1af159719e3ebb0a00496a783b091528f2fc4 100644 (file)
@@ -25,6 +25,8 @@ 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)
@@ -44,6 +46,8 @@ if test "$PHP_HTTP" != "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
index 66e977f8e6980193d735614063e565583880cca3..5daf7858bfc30b0780ad988f3a0e213b7f57e683 100644 (file)
@@ -31,10 +31,10 @@ https://mdref.m6w6.name/http
   <email>mike@php.net</email>
   <active>yes</active>
  </lead>
- <date>2020-12-01</date>
+ <date>2024-02-05</date>
  <version>
-  <release>4.0.0</release>
-  <api>4.0.0</api>
+  <release>4.2.5</release>
+  <api>4.2.0</api>
  </version>
  <stability>
   <release>stable</release>
@@ -42,15 +42,8 @@ https://mdref.m6w6.name/http
  </stability>
  <license uri="http://copyfree.org/content/standard/licenses/2bsd/license.txt">BSD-2-Clause</license>
  <notes><![CDATA[
-  >*NOTE:*
-  v4.x will be PHP-8 only, v3.x continues PHP-7 support
-
-  * 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.
+* Fix incompatible pointer types (32-bit) (see gh issue #134)
+* Fix glitch in CURL_VERSION_TLSAUTH_SRP autoconf probe (see gh issue #133)
 ]]></notes>
  <contents>
   <dir name="/">
@@ -258,6 +251,7 @@ https://mdref.m6w6.name/http
      <file role="test" name="envrequestform.phpt"/>
      <file role="test" name="envrequestheader001.phpt"/>
      <file role="test" name="envrequestquery.phpt"/>
+     <file role="test" name="envreset001.phpt"/>
      <file role="test" name="envresponse001.phpt"/>
      <file role="test" name="envresponse002.phpt"/>
      <file role="test" name="envresponse003.phpt"/>
@@ -382,9 +376,11 @@ https://mdref.m6w6.name/http
    <dir name="scripts">
     <file role="src" name="bench_select_vs_event.php"/>
     <file role="src" name="check_package-xml.php"/>
+    <file role="src" name="curlver.dist"/>
     <file role="src" name="gen_curlinfo.php"/>
     <file role="src" name="gen_stubs.php"/>
     <file role="src" name="gen_github_workflow_ci.php"/>
+    <file role="src" name="gen_github_workflow_curl-matrix.php"/>
     <file role="src" name="gen_utf8.php"/>
    </dir>
   </dir>
index 608e05873d39029595eeadf2943b864c8f09f3ae..f8cede27e4f5505463045d15a12b9dda7d7aaef2 100644 (file)
 #ifndef PHP_EXT_HTTP_H
 #define PHP_EXT_HTTP_H
 
-#define PHP_PECL_HTTP_VERSION "4.0.0"
+#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/curlver.dist b/scripts/curlver.dist
new file mode 100644 (file)
index 0000000..416cb07
--- /dev/null
@@ -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
index 9fae4cb8d78c6baee7873b89a7a491e1a3c1d22e..ab4391dccef9eb2b09463cbbcf9e35b619551ef8 100755 (executable)
@@ -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;
index 7cbbdfb056640a729137a915bd3d9db77bfc2d53..41ce95fbb68aa144239691f89801cb06fcca82cc 100755 (executable)
@@ -11,15 +11,21 @@ jobs:
 <?php
 
 $gen = include __DIR__ . "/ci/gen-matrix.php";
-$cur = "8.0";
+$cur = "8.2";
 $job = $gen->github([
-"master" => [
-// most useful for all additional versions except current
+"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,
@@ -29,14 +35,14 @@ $job = $gen->github([
     "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",
@@ -52,7 +58,7 @@ $job = $gen->github([
 ]]);
 foreach ($job as $id => $env) {
     printf("  %s:\n", $id);
-    printf("    name: %s\n", $id);
+    printf("    name: \"%s (%s)\"\n", $id, $env["PHP"]);
     if ($env["PHP"] == "master") {
         printf("    continue-on-error: true\n");
     }
@@ -61,18 +67,21 @@ foreach ($job as $id => $env) {
         printf("      %s: \"%s\"\n", $key, $val);
     }
 ?>
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - 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 \
-            libidn11-dev \
+            libidn-dev \
             libidn2-0-dev \
             libicu-dev \
             libevent-dev \
diff --git a/scripts/gen_github_workflow_curl-matrix.php b/scripts/gen_github_workflow_curl-matrix.php
new file mode 100755 (executable)
index 0000000..beaa65d
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/env php
+<?php echo "# generated file; do not edit!\n"; ?>
+
+name: curl-matrix
+on:
+  workflow_dispatch:
+  push:
+
+jobs:
+<?php
+
+if ($argc > 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
+<?php if ($env["CURL"] !== "master") : ?>
+          ref: curl-<?=$env["CURL"]?> #
+<?php endif; ?>
+      - 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
+
+<?php
+}
index 69257f15defed898146941b06432d619ff79b55e..dcdfffab4ffd572fe5213c516423c81faa77e159 100644 (file)
@@ -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;
@@ -632,9 +646,8 @@ 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, Z_OBJ_P(client), ZEND_STRL("options"), 0, &z_options_tmp);
 
@@ -649,8 +662,12 @@ static HashTable *combined_options(zval *client, zval *request)
                        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);
        }
@@ -713,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;
@@ -769,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;
@@ -804,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)
 {
@@ -984,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();
@@ -1028,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)
@@ -1057,11 +1099,16 @@ static PHP_METHOD(HttpClient, attach)
        ZVAL_UNDEF(&retval);
        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)
@@ -1080,8 +1127,9 @@ static PHP_METHOD(HttpClient, detach)
        ZVAL_UNDEF(&retval);
        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)
@@ -1357,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;
index fd77204fc6a53b772931b7ec36931f8486c20835..da53b4d717a744820b4e27129091fe849b100055 100644 (file)
@@ -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;
index 8a28008634adb2352fc090aefe93ef8e434ab02a..4decc7af20c8e7a234ab9492a775fa5f97a6cac1 100644 (file)
@@ -17,6 +17,8 @@
 
 #if PHP_HTTP_HAVE_LIBCURL
 
+#define DEBUG_COOKIES 0
+
 #if PHP_HTTP_HAVE_LIBCURL_OPENSSL
 #      include <openssl/ssl.h>
 #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,6 +332,7 @@ 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;
 
@@ -364,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);
@@ -392,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);
@@ -510,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 */
 
@@ -609,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;
@@ -793,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;
@@ -814,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;
                }
@@ -836,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;
        }
 
@@ -930,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;
@@ -1152,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 */
@@ -1161,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;
@@ -1191,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))) {
@@ -1204,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
 
@@ -1242,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);
@@ -1260,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);
@@ -1288,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))) {
@@ -1373,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))) {
@@ -1399,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 ((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(registry, ZEND_STRL("cert"), CURLOPT_SSLCERT, IS_STRING))) {
+                       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)
@@ -1609,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;
@@ -1716,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;
@@ -1749,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))) {
@@ -1791,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);
@@ -1849,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))) {
@@ -1880,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;
 }
@@ -1908,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))) {
@@ -1926,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;
@@ -1976,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);
@@ -2074,11 +2383,18 @@ 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 */
 #if PHP_HTTP_CURL_VERSION(7,63,0) && !PHP_HTTP_CURL_VERSION(7,65,0)
-       curl_easy_setopt(handler->handle, CURLOPT_COOKIEJAR, NULL);
+       {
+               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
 }
 
@@ -2159,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;
@@ -2189,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);
        }
 
@@ -2247,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;
@@ -2363,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)
@@ -2467,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
 };
@@ -2476,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)
@@ -2520,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
                 */
@@ -2527,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);
@@ -2539,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
@@ -2551,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
+
        }
 
        /*
@@ -2585,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);
 
@@ -2596,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);
@@ -2604,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
        */
@@ -2614,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)
@@ -2623,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);
 
@@ -2630,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)
@@ -2650,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;
 }
 
index b8db1b2d5e15c33429b1c6f6cdc7c06da70ff201..2e663ed74c0bc9348b32e585b77e47670ce9deaa 100644 (file)
@@ -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);
index 1f69a51cb7203e3d4acb05502f512a703a1f1eb6..2e646f60c7f5bc7f3ac845fbbaf0ea9f87bea7ec 100644 (file)
@@ -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);
 
index ecdf94e256e314980339202e3685517c69050f17..dd4c6c6e5bdec7da3534355ae085f640216630c8 100644 (file)
@@ -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;
@@ -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
 };
index 5e14ed21a436cf1dc2c8c1c7435c0d4237ca2bc9..9c88822e3db948ec3331e4d706084f22db7be391 100644 (file)
 
 
 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)
@@ -779,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)
@@ -797,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
 };
 
index 829274470c57d6f72311f811e8bfb4df19b766c6..d71ec474b71974f1d0d073f1211d9f530cc8e92d 100644 (file)
@@ -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);
index 76b2f68a374e197cab53b4a4cb0414bbc39e3d7e..c475a8186a8249714698333df1dd624cacfda29e 100644 (file)
@@ -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);
@@ -191,6 +191,41 @@ PHP_METHOD(HttpHeader, __construct)
        }
 }
 
+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);
+       }
+}
+
 ZEND_BEGIN_ARG_INFO_EX(ai_HttpHeader_serialize, 0, 0, 0)
 ZEND_END_ARG_INFO();
 PHP_METHOD(HttpHeader, serialize)
@@ -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, 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);
@@ -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
  */
-
index 1bbc53cefce10150da3d7d03de434c19bec48895..cd01757b4f83d5261014b10dfa4e7d049231b84b 100644 (file)
@@ -647,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);
@@ -688,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)
 
@@ -931,14 +933,16 @@ static zval *php_http_message_object_write_prop(zend_object *object, zend_string
 
 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(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 { \
@@ -1695,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();
@@ -1762,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)
@@ -1916,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)
 {
@@ -1931,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)
 {
@@ -1946,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)
 {
@@ -1957,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)
 {
@@ -1981,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)
 {
@@ -1992,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)
 {
@@ -2005,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)
@@ -2041,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)
@@ -2075,15 +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);
index 70fd58741667fdd859ffa250d892fb44a91a9dd7..8bde1a770590cf75e1556ada6c50e97fafb6d241 100644 (file)
@@ -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());
@@ -704,6 +704,49 @@ PHP_METHOD(HttpMessageBody, unserialize)
        }
 }
 
+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)
@@ -908,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)
index 481fb8c5b71b88a04c8258ff00750196864a6efa..c45ab1595aeee65c4e0dee3a16a2be9924310d39 100644 (file)
@@ -106,12 +106,48 @@ static inline const char *php_http_locate_bin_eol(const char *bin, size_t len, i
 # define php_http_mem_stream_open(type, zstr) php_stream_memory_open((type), (zstr))
 #else
 # 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
 
 #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) {
index 44f01c32992df9b872f8bddcf28c6a5c846e9d0a..f40b89f9c0fddbdbd06f72a69d54f8fd8aa9249c 100644 (file)
@@ -1181,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)
@@ -1202,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)
@@ -1221,7 +1221,7 @@ PHP_METHOD(HttpParams, offsetGet)
        }
 }
 
-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)
@@ -1240,7 +1240,7 @@ PHP_METHOD(HttpParams, offsetUnset)
        }
 }
 
-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();
@@ -1249,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, 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);
@@ -1290,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)
@@ -1345,4 +1348,3 @@ PHP_MINIT_FUNCTION(http_params)
  * vim600: noet sw=4 ts=4 fdm=marker
  * vim<600: noet sw=4 ts=4
  */
-
index f2d73a4bf2fdb0b12e2bcb232d4d32cc579490af..06d52c5a1c520cdf02c0f0af6e6f826a29f2ad69 100644 (file)
@@ -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);
                }
@@ -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", &params), invalid_arg, return);
 
        zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_querystring_class_entry(), &zeh);
@@ -395,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)
 {
@@ -446,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) {
@@ -454,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':
@@ -463,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':
@@ -486,11 +486,11 @@ ZEND_END_ARG_INFO();
 PHP_METHOD(HttpQueryString, set)
 {
        zval *params;
-       
+
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "z", &params)) {
                return;
        }
-       
+
        php_http_querystring_set(getThis(), params, QS_MERGE);
        RETVAL_ZVAL(getThis(), 1, 0);
 }
@@ -504,7 +504,7 @@ PHP_METHOD(HttpQueryString, mod)
        zend_error_handling zeh;
 
        php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "z", &params), 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(Z_OBJ_P(instance)));
        /* make sure we do not inherit the reference to _GET */
@@ -561,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)
@@ -582,7 +605,7 @@ ZEND_END_ARG_INFO();
 PHP_METHOD(HttpQueryString, unserialize)
 {
        zval *serialized;
-       
+
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "z", &serialized)) {
                return;
        }
@@ -594,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)
 {
@@ -605,7 +628,7 @@ PHP_METHOD(HttpQueryString, offsetGet)
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S", &offset)) {
                return;
        }
-       
+
        qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp);
        ZVAL_DEREF(qa);
 
@@ -616,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;
        }
@@ -641,8 +664,8 @@ PHP_METHOD(HttpQueryString, offsetSet)
        zval_ptr_dtor(&param);
 }
 
-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)
 {
@@ -652,7 +675,7 @@ PHP_METHOD(HttpQueryString, offsetExists)
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S", &offset)) {
                return;
        }
-       
+
        qa = zend_read_property(php_http_querystring_class_entry, Z_OBJ_P(ZEND_THIS), ZEND_STRL("queryArray"), 0, &qa_tmp);
        ZVAL_DEREF(qa);
 
@@ -664,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;
        }
@@ -683,12 +706,15 @@ PHP_METHOD(HttpQueryString, offsetUnset)
        zval_ptr_dtor(&param);
 }
 
+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)
@@ -711,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)
index 21e38e248be4d2355ba5167f5ebc9ee61d1dc712..459396f347d57280858a37c6e55546ff2558d495 100644 (file)
@@ -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);
@@ -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
  */
-
index 6f01a444e97a20d72e95bb6edf1a84c26b659e5d..d020f16e22ff4d5916b2ba4830ae1083c48c321a 100644 (file)
@@ -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);
                }
        }
 }
index 6aea2255cd35b2654550f248f446597ca7a3c87a..0eb08f73a96f0c2e779a677854da3c3788713522 100644 (file)
@@ -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
index bb599db44c2619b1eac6612f84d7b74f098ac5c1..3b1e1c0c2b9773605cb839a44f4aa693350667e3 100644 (file)
@@ -1,14 +1,19 @@
 --TEST--
 client ssl
 --SKIPIF--
-<?php 
+<?php
 include "skipif.inc";
 skip_online_test();
 skip_client_test();
 skip_curl_test("7.34.0");
+if (0 === strpos(http\Client\Curl\Versions\CURL, "7.87.0")) {
+       die("skip SSL bug in libcurl-7.87\n");
+}
+if (strpos(http\Client\Curl\Versions\SSL, "SecureTransport") !== false)
+       die("skip SecureTransport\n");
 ?>
 --FILE--
-<?php 
+<?php
 echo "Test\n";
 
 $client = new http\Client;
@@ -22,8 +27,10 @@ var_dump(
        ) === $client->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:
index 477edf7fa6d18122efbe919c5b8be69b61382ba3..962d448e5dd69a9327c6ab7a7ce7df2ec599d06c 100644 (file)
@@ -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);
        }
index 702685dd125f6efb8c30b976d9f2c9a4d1271195..f8eeeb5911d45caed5e4846eb5df1459bdac62e4 100644 (file)
@@ -4,6 +4,10 @@ client cookies
 <?php
 include "skipif.inc";
 skip_client_test();
+if (0 === strpos(http\Client\Curl\Versions\CURL, "7.64.0") ||
+       0 === strpos(http\Client\Curl\Versions\CURL, "7.88.1")) {
+       die("skip - cookie handling broken or crashes with libcurl v" . http\Client\Curl\Versions\CURL ."\n");
+}
 ?>
 --FILE--
 <?php
index ac29865cca76dca99d4709b398b51a0ac6bde334..4e8fe2f9bf8d695e810ca41fa859c8b321d22b01 100644 (file)
@@ -4,6 +4,8 @@ client deprecated methods
 <?php
 include "skipif.inc";
 skip_client_test();
+if (!(error_reporting() & E_DEPRECATED))
+       die("skip error_reporting() & ~E_DEPRECATED\n");
 ?>
 --FILE--
 <?php
index 4cb63afc915e6ca2f3f4ca32f8baad78cc1ab9f4..21f4c2db12619037f54edfbae5c3a5e22c31f2d4 100644 (file)
@@ -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
 
index d33a58db02c84dbb42b4d39dc6bc77d397957f00..b87fa653dd108aba9f320e10e185950f72cc08e7 100644 (file)
@@ -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===
index 8514b4e9e8b3d3ea3f3cb1f528a6f6758a283c3f..5a5155e1186f0620f5628eca45c7a8edd343822f 100644 (file)
@@ -12,6 +12,7 @@ echo "Test\n";
 include "helper/server.inc";
 
 class test implements SplObserver {
+       #[ReturnTypeWillChange]
        function update(SplSubject $client) {
                $client->once();
        }
index 32117356b62190f080ad817b00cbc613d7bd9309..73ce7e4c6251cb5ae5147d5b422cfeab1c0c7a66 100644 (file)
@@ -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===
index d8dfb2bb3a6dd94d8461d6c4d0a77c1708ccb542..954a68e2609018c7b63b7e813161a97fc9d4cd5a 100644 (file)
@@ -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 (file)
index 0000000..547fef0
--- /dev/null
@@ -0,0 +1,65 @@
+--TEST--
+env reset
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--POST--
+a=b
+--ENV--
+HTTP_HOST=foo.bar
+HTTP_ACCEPT=*/*
+--FILE--
+<?php
+
+var_dump(http\Env::getRequestHeader("nono"));
+var_dump(http\Env::getRequestHeader("Host"));
+var_dump(http\Env::getRequestHeader("content-type"));
+$hdr = http\Env::getRequestHeader();
+ksort($hdr);
+var_dump($hdr);
+
+$_SERVER["HTTP_NONO"] = "yesyes";
+unset($_SERVER["HTTP_HOST"]);
+
+var_dump(http\Env::getRequestHeader("nono"));
+var_dump(http\Env::getRequestHeader("Host"));
+
+http\Env::reset();
+
+var_dump(http\Env::getRequestHeader("nono"));
+var_dump(http\Env::getRequestHeader("Host"));
+var_dump(http\Env::getRequestHeader("content-type"));
+$hdr = http\Env::getRequestHeader();
+ksort($hdr);
+var_dump($hdr);
+?>
+==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==
index 8d48c9374276e812b3aa65eab3688aa0c76efe10..347621691e88269e4f27dd5df588b5bb6aa78e52 100644 (file)
@@ -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);
                }
index 452a715e2dfa51042ba9c9ee0a7c9797f862180d..59d258c46f8c9681e863ed82cc1d3e4e27eed59b 100644 (file)
@@ -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);
+                       }
+               }
+       }
+
+}
+?>
index f203ed6c50f1696253e1a06d6e3439e0db95cc7c..b5bc3b7f4564d014b8636870c2de1bd51bf92bba 100644 (file)
@@ -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())
        ));
 }
@@ -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);
@@ -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);
        }
index 573fdbd8a9ded3106f72c0a1f0f4ffdff8f038b1..da0b7996364f303c57494cd4e70d73eff9cacf0b 100644 (file)
@@ -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]=>
index 51272fbe575b16705e7cb24564e9154e494d6331..76c3bd793576f73639a62860629055f7c79c6367 100644 (file)
@@ -53,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;
                }
index e2e36db777065f472ee6dc734f1bb8758cc82328..c7f800af141f89577a15335a78ebcd683ab31364 100644 (file)
@@ -7,7 +7,9 @@ if (!defined("http\\Url::PARSE_MBLOC") or
        !utf8locale()) {
        die("skip need http\\Url::PARSE_MBLOC support and LC_CTYPE=*.UTF-8");
 }
-
+if (PHP_OS == "Darwin") {
+  die("skip Darwin\n");
+}
 ?>
 --FILE--
 <?php