# we dont want -z defs linker flag %undefine _strict_symbol_defs_build %global pecl_name curl_impersonate %global with_zts 0%{!?_without_zts:%{?__ztsphp:1}} %global ini_name 40-%{pecl_name}.ini Name: php-%{pecl_name} Version: 0.1.0 Release: 2.ci1.5.2%{?dist} Summary: Browser TLS/HTTP2 fingerprint impersonation for PHP License: MIT URL: https://github.com/DigitalCyberSoft/php-curl-cffi Source0: php-curl-cffi-%{version}.tar.gz Source1: curl-impersonate-1.5.2.tar.gz BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: make BuildRequires: cmake >= 3.12 BuildRequires: ninja-build BuildRequires: golang BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool BuildRequires: python3 BuildRequires: unzip BuildRequires: php-devel >= 8.0 BuildRequires: libcurl-devel BuildRequires: zlib-devel BuildRequires: brotli-devel BuildRequires: libnghttp2-devel BuildRequires: libzstd-devel BuildRequires: libidn2-devel Requires: php(zend-abi) = %{php_zend_api} Requires: php(api) = %{php_core_api} Requires: libstdc++ Requires: zlib Provides: bundled(libcurl-impersonate) = 1.5.2 %description PHP extension wrapping libcurl-impersonate to enable browser TLS and HTTP/2 fingerprint impersonation from PHP. Supports Chrome, Firefox, and Safari fingerprints to bypass anti-bot systems that inspect TLS Client Hello and HTTP/2 settings. Provides both a high-level Session API (similar to Python requests) and a low-level procedural API (compatible with PHP curl_* functions). The libcurl-impersonate static library (1.5.2) is bundled. %package devel Summary: Development files for %{name} Requires: %{name}%{?_isa} = %{version}-%{release} Requires: php-devel%{?_isa} %description devel These are the files needed to compile programs using %{name}. %prep %setup -q -n php-curl-cffi-%{version} -a 1 # Sanity check extver=$(sed -n '/#define PHP_CURL_IMPERSONATE_VERSION/{s/.* "//;s/".*$//;p}' php_curl_impersonate.h) if test "x${extver}" != "x%{version}"; then : Error: Upstream extension version is ${extver}, expecting %{version}. exit 1 fi %if %{with_zts} # Duplicate for ZTS build cp -pr . ../ZTS %endif %build # Build curl-impersonate from bundled source # BoringSSL, ngtcp2, nghttp3 and curl built from source; other deps use system packages CURL_IMP_DIR=$(pwd)/curl-impersonate cd "$CURL_IMP_DIR" mkdir -p build && cd build # Copy pre-fetched dependency archives so make does not try to download cp ../*.tar.gz ../*.tar.bz2 ../*.tar.xz ../*.zip . 2>/dev/null || : ../configure --prefix=$(pwd)/dist # Patch Makefile to use system libs where possible # Use system libs for brotli, nghttp2, zstd, zlib, idn2 # Build BoringSSL, ngtcp2, nghttp3 from source (need custom BoringSSL for QUIC) sed -i 's|^chrome_libs := .*|chrome_libs := $(boringssl_static_libs) $(ngtcp2_static_libs) $(nghttp3_static_libs)|' Makefile sed -i 's|--with-nghttp2=$(nghttp2_install_dir)|--with-nghttp2|' Makefile sed -i 's|--with-brotli=$(brotli_install_dir)|--with-brotli|' Makefile sed -i 's|--with-zstd=$(zstd_install_dir)|--with-zstd|' Makefile sed -i 's|--with-zlib=$(zlib_install_dir)|--with-zlib|' Makefile sed -i 's|--with-libidn2=$(libidn2_install_dir)|--with-libidn2|' Makefile # Ensure -fPIC for all static libs that end up in the shared .so export CFLAGS="$CFLAGS -fPIC" export CXXFLAGS="$CXXFLAGS -fPIC" make build make install cd ../../ # Find the built static libraries STATIC_LIB=$(find "$CURL_IMP_DIR" -name "libcurl-impersonate*.a" -type f | head -1) NGTCP2_LIB=$(find "$CURL_IMP_DIR" -name "libngtcp2.a" -not -name "libngtcp2_crypto*" -type f | head -1) NGTCP2_CRYPTO=$(find "$CURL_IMP_DIR" -name "libngtcp2_crypto_boringssl.a" -type f | head -1) NGHTTP3_LIB=$(find "$CURL_IMP_DIR" -name "libnghttp3.a" -type f | head -1) BSSL_SSL=$(find "$CURL_IMP_DIR" -name "libssl.a" -type f | head -1) BSSL_CRYPTO=$(find "$CURL_IMP_DIR" -name "libcrypto.a" -type f | head -1) if [ -z "$STATIC_LIB" ]; then echo "ERROR: libcurl-impersonate static library not found after build" find "$CURL_IMP_DIR" -name "*.a" -type f exit 1 fi echo "Built static libraries:" echo " curl: $STATIC_LIB" echo " ngtcp2: $NGTCP2_LIB" echo " ngtcp2_crypto: $NGTCP2_CRYPTO" echo " nghttp3: $NGHTTP3_LIB" echo " ssl: $BSSL_SSL" echo " crypto: $BSSL_CRYPTO" cp "$STATIC_LIB" libcurl-impersonate.a # Extra libs needed at link time: built static archives + system shared libs EXTRA_LIBS="$NGTCP2_CRYPTO $NGTCP2_LIB $NGHTTP3_LIB $BSSL_SSL $BSSL_CRYPTO -lnghttp2 -lbrotlidec -lbrotlicommon -lzstd -lidn2 -lpthread" # NTS build %{_bindir}/phpize %configure \ --with-php-config=%{_bindir}/php-config \ --with-libdir=%{_lib} \ --with-curl-impersonate=$PWD/libcurl-impersonate.a # Inject extra libs into the generated Makefile (config.m4 only links -lz -lpthread -ldl -lm -lstdc++) sed -i "s|^\\(CURL_IMPERSONATE_SHARED_LIBADD = .*\\)|\\1 $EXTRA_LIBS|" Makefile make %{?_smp_mflags} %if %{with_zts} # ZTS build cd ../ZTS cp "$STATIC_LIB" libcurl-impersonate.a %{_bindir}/zts-phpize %configure \ --with-php-config=%{_bindir}/zts-php-config \ --with-libdir=%{_lib} \ --with-curl-impersonate=$PWD/libcurl-impersonate.a sed -i "s|^\\(CURL_IMPERSONATE_SHARED_LIBADD = .*\\)|\\1 $EXTRA_LIBS|" Makefile make %{?_smp_mflags} %endif %install # Install NTS extension make install INSTALL_ROOT=%{buildroot} # Install config file install -d %{buildroot}%{php_inidir} cat > %{buildroot}%{php_inidir}/%{ini_name} << EOF ; Enable curl_impersonate extension module extension = %{pecl_name}.so EOF %if %{with_zts} # Install ZTS extension cd ../ZTS make install INSTALL_ROOT=%{buildroot} # Install ZTS config file install -d %{buildroot}%{php_ztsinidir} cp %{buildroot}%{php_inidir}/%{ini_name} \ %{buildroot}%{php_ztsinidir}/%{ini_name} %else # Remove any ZTS files that NTS make install may have created find %{buildroot} -name "%{pecl_name}.so" -not -path "%{buildroot}%{php_extdir}/*" -delete 2>/dev/null || : %endif # Install headers for devel package install -d %{buildroot}%{php_incldir}/ext/%{pecl_name} cp -p php_curl_impersonate.h %{buildroot}%{php_incldir}/ext/%{pecl_name}/ %check # Minimal load test for NTS extension %{__php} --no-php-ini \ --define extension=%{buildroot}%{php_extdir}/%{pecl_name}.so \ -m > /tmp/php_modules.txt 2>&1 || true cat /tmp/php_modules.txt grep "^%{pecl_name}$" /tmp/php_modules.txt %if %{with_zts} # Minimal load test for ZTS extension %{__ztsphp} --no-php-ini \ --define extension=%{buildroot}%{php_ztsextdir}/%{pecl_name}.so \ --modules | grep "^%{pecl_name}$" %endif %files %doc README.md %config(noreplace) %{php_inidir}/%{ini_name} %{php_extdir}/%{pecl_name}.so %if %{with_zts} %config(noreplace) %{php_ztsinidir}/%{ini_name} %{php_ztsextdir}/%{pecl_name}.so %endif %files devel %{php_incldir}/ext/%{pecl_name} %changelog * Mon Apr 06 2026 COPR Builder - 0.1.0-1.ci1.5.2 - Automated build from GitHub release 0.1.0 - Bundled libcurl-impersonate 1.5.2 - Browser TLS/HTTP2 fingerprint impersonation for PHP - Supports both NTS and ZTS builds