diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/curl | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/curl')
88 files changed, 7490 insertions, 0 deletions
diff --git a/ext/curl/CREDITS b/ext/curl/CREDITS new file mode 100644 index 0000000..610e036 --- /dev/null +++ b/ext/curl/CREDITS @@ -0,0 +1,2 @@ +cURL +Sterling Hughes diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 new file mode 100644 index 0000000..fbb4f5b --- /dev/null +++ b/ext/curl/config.m4 @@ -0,0 +1,161 @@ +dnl +dnl $Id$ +dnl + +PHP_ARG_WITH(curl, for cURL support, +[ --with-curl[=DIR] Include cURL support]) + +dnl Temporary option while we develop this aspect of the extension +PHP_ARG_WITH(curlwrappers, if we should use cURL for url streams, +[ --with-curlwrappers EXPERIMENTAL: Use cURL for url streams], no, no) + +if test "$PHP_CURL" != "no"; then + if test -r $PHP_CURL/include/curl/easy.h; then + CURL_DIR=$PHP_CURL + else + AC_MSG_CHECKING(for cURL in default path) + for i in /usr/local /usr; do + if test -r $i/include/curl/easy.h; then + CURL_DIR=$i + AC_MSG_RESULT(found in $i) + break + fi + done + fi + + if test -z "$CURL_DIR"; then + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Please reinstall the libcurl distribution - + easy.h should be in <curl-dir>/include/curl/) + fi + + CURL_CONFIG="curl-config" + AC_MSG_CHECKING(for cURL 7.10.5 or greater) + + if ${CURL_DIR}/bin/curl-config --libs > /dev/null 2>&1; then + CURL_CONFIG=${CURL_DIR}/bin/curl-config + else + if ${CURL_DIR}/curl-config --libs > /dev/null 2>&1; then + CURL_CONFIG=${CURL_DIR}/curl-config + fi + fi + + curl_version_full=`$CURL_CONFIG --version` + curl_version=`echo ${curl_version_full} | sed -e 's/libcurl //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test "$curl_version" -ge 7010005; then + AC_MSG_RESULT($curl_version_full) + CURL_LIBS=`$CURL_CONFIG --libs` + else + AC_MSG_ERROR(cURL version 7.10.5 or later is required to compile php with cURL support) + fi + + PHP_ADD_INCLUDE($CURL_DIR/include) + PHP_EVAL_LIBLINE($CURL_LIBS, CURL_SHARED_LIBADD) + PHP_ADD_LIBRARY_WITH_PATH(curl, $CURL_DIR/$PHP_LIBDIR, CURL_SHARED_LIBADD) + + AC_MSG_CHECKING([for SSL support in libcurl]) + CURL_SSL=`$CURL_CONFIG --feature | $EGREP SSL` + if test "$CURL_SSL" = "SSL"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_CURL_SSL], [1], [Have cURL with SSL support]) + + save_CFLAGS="$CFLAGS" + CFLAGS="`$CURL_CONFIG --cflags`" + + AC_PROG_CPP + AC_MSG_CHECKING([for openssl support in libcurl]) + AC_TRY_RUN([ +#include <curl/curl.h> + +int main(int argc, char *argv[]) +{ + curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); + + if (data && data->ssl_version && *data->ssl_version) { + const char *ptr = data->ssl_version; + + while(*ptr == ' ') ++ptr; + return strncasecmp(ptr, "OpenSSL", sizeof("OpenSSL")-1); + } + return 1; +} + ],[ + AC_MSG_RESULT([yes]) + AC_CHECK_HEADERS([openssl/crypto.h], [ + AC_DEFINE([HAVE_CURL_OPENSSL], [1], [Have cURL with OpenSSL support]) + ]) + ], [ + AC_MSG_RESULT([no]) + ], [ + AC_MSG_RESULT([no]) + ]) + + AC_MSG_CHECKING([for gnutls support in libcurl]) + AC_TRY_RUN([ +#include <curl/curl.h> + +int main(int argc, char *argv[]) +{ + curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); + + if (data && data->ssl_version && *data->ssl_version) { + const char *ptr = data->ssl_version; + + while(*ptr == ' ') ++ptr; + return strncasecmp(ptr, "GnuTLS", sizeof("GnuTLS")-1); + } + return 1; +} +], [ + AC_MSG_RESULT([yes]) + AC_CHECK_HEADER([gcrypt.h], [ + AC_DEFINE([HAVE_CURL_GNUTLS], [1], [Have cURL with GnuTLS support]) + ]) + ], [ + AC_MSG_RESULT([no]) + ], [ + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$save_CFLAGS" + else + AC_MSG_RESULT([no]) + fi + + PHP_CHECK_LIBRARY(curl,curl_easy_perform, + [ + AC_DEFINE(HAVE_CURL,1,[ ]) + ],[ + AC_MSG_ERROR(There is something wrong. Please check config.log for more information.) + ],[ + $CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR + ]) + + PHP_CHECK_LIBRARY(curl,curl_version_info, + [ + AC_DEFINE(HAVE_CURL_VERSION_INFO,1,[ ]) + ],[],[ + $CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR + ]) + + PHP_CHECK_LIBRARY(curl,curl_easy_strerror, + [ + AC_DEFINE(HAVE_CURL_EASY_STRERROR,1,[ ]) + ],[],[ + $CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR + ]) + + PHP_CHECK_LIBRARY(curl,curl_multi_strerror, + [ + AC_DEFINE(HAVE_CURL_MULTI_STRERROR,1,[ ]) + ],[],[ + $CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR + ]) + + if test "$PHP_CURLWRAPPERS" != "no" ; then + AC_DEFINE(PHP_CURL_URL_WRAPPERS,1,[ ]) + fi + + PHP_NEW_EXTENSION(curl, interface.c multi.c streams.c, $ext_shared) + PHP_SUBST(CURL_SHARED_LIBADD) +fi diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 new file mode 100644 index 0000000..930adcf --- /dev/null +++ b/ext/curl/config.w32 @@ -0,0 +1,28 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("curl", "cURL support", "no"); + +if (PHP_CURL != "no") { + if (CHECK_LIB("libcurl_a.lib;libcurl.lib", "curl", PHP_CURL) && + CHECK_HEADER_ADD_INCLUDE("curl/easy.h", "CFLAGS_CURL") && + CHECK_LIB("ssleay32.lib", "curl", PHP_CURL) && + CHECK_LIB("libeay32.lib", "curl", PHP_CURL) + && CHECK_LIB("winmm.lib", "curl", PHP_CURL) + && CHECK_LIB("wldap32.lib", "curl", PHP_CURL) + && (((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib;zlib.lib", "curl", PHP_CURL))) || + (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "curl", PHP_CURL)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED))) + ) { + EXTENSION("curl", "interface.c multi.c streams.c", true); + AC_DEFINE('HAVE_CURL', 1, 'Have cURL library'); + AC_DEFINE('HAVE_CURL_SSL', 1, 'Have SSL suppurt in cURL'); + AC_DEFINE('HAVE_CURL_EASY_STRERROR', 1, 'Have curl_easy_strerror in cURL'); + AC_DEFINE('HAVE_CURL_MULTI_STRERROR', 1, 'Have curl_multi_strerror in cURL'); + AC_DEFINE('HAVE_CURL_VERSION_INFO', 1, 'Have curl_version_info in cURL'); + ADD_FLAG("CFLAGS_CURL", "/D CURL_STATICLIB"); + // TODO: check for curl_version_info + // AC_DEFINE('PHP_CURL_URL_WRAPPERS', 0, 'Use curl for URL wrappers [experimental]'); + } else { + WARNING("curl not enabled; libraries and headers not found"); + } +} diff --git a/ext/curl/curl.dsp b/ext/curl/curl.dsp new file mode 100644 index 0000000..81d8231 --- /dev/null +++ b/ext/curl/curl.dsp @@ -0,0 +1,186 @@ +# Microsoft Developer Studio Project File - Name="curl" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=curl - Win32 Release_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "curl.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "curl.mak" CFG="curl - Win32 Release_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "curl - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "curl - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "curl - Win32 Debug_TS_SSL" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "curl - Win32 Release_TS_SSL" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "curl - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_CURL" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\php_build\curl\include" /D "WIN32" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D HAVE_CURL=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts.lib libcurl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /machine:I386 /nodefaultlib:"MSVCRT" /out:"..\..\Release_TS/php_curl.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\curl\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "curl - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_CURL" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\php_build\curl\include" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_CURL=1 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts_debug.lib libcurl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib wsock32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"MSVCRTD" /out:"..\..\Debug_TS/php_curl.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\curl\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "curl - Win32 Debug_TS_SSL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "curl___Win32_Debug_TS_SSL"
+# PROP BASE Intermediate_Dir "curl___Win32_Debug_TS_SSL"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS_SSL"
+# PROP Intermediate_Dir "Debug_TS_SSL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_CURL=1 /FR /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\php_build\curl\include" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_CURL=1 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 php5ts_debug.lib libcurl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"..\..\Debug_TS/php_curl.dll" /libpath:"..\..\Debug_TS"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 php5ts_debug.lib libcurl.lib ssleay32.lib libeay32.lib msvcrt.lib ws2_32.lib winmm.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"MSVCRTD" /out:"..\..\Debug_TS/php_curl.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\curl\lib"
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ELSEIF "$(CFG)" == "curl - Win32 Release_TS_SSL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "curl___Win32_Release_TS_SSL"
+# PROP BASE Intermediate_Dir "curl___Win32_Release_TS_SSL"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS_SSL"
+# PROP Intermediate_Dir "Release_TS_SSL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /D "WIN32" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D HAVE_CURL=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\php_build\curl\include" /D "WIN32" /D "CURL_EXPORTS" /D "COMPILE_DL_CURL" /D ZTS=1 /D HAVE_CURL=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 php5ts.lib libcurl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\..\Release_TS/php_curl.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 php5ts.lib libcurl.lib ssleay32.lib libeay32.lib msvcrt.lib ws2_32.lib winmm.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /machine:I386 /nodefaultlib:"MSVCRT" /out:"..\..\Release_TS/php_curl.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\curl\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "curl - Win32 Release_TS"
+# Name "curl - Win32 Debug_TS"
+# Name "curl - Win32 Debug_TS_SSL"
+# Name "curl - Win32 Release_TS_SSL"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\interface.c
+# End Source File
+
+# Begin Source File
+SOURCE=.\multi.c
+# End Source File
+
+# Begin Source File
+SOURCE=.\streams.c
+# End Source File
+
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_curl.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/ext/curl/interface.c b/ext/curl/interface.c new file mode 100644 index 0000000..531f15b --- /dev/null +++ b/ext/curl/interface.c @@ -0,0 +1,2753 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you 6 copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes <sterling@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_CURL + +#include <stdio.h> +#include <string.h> + +#ifdef PHP_WIN32 +#include <winsock2.h> +#include <sys/types.h> +#endif + +#include <curl/curl.h> +#include <curl/easy.h> + +/* As of curl 7.11.1 this is no longer defined inside curl.h */ +#ifndef HttpPost +#define HttpPost curl_httppost +#endif + +/* {{{ cruft for thread safe SSL crypto locks */ +#if defined(ZTS) && defined(HAVE_CURL_SSL) +# ifdef PHP_WIN32 +# define PHP_CURL_NEED_OPENSSL_TSL +# include <openssl/crypto.h> +# else /* !PHP_WIN32 */ +# if defined(HAVE_CURL_OPENSSL) +# if defined(HAVE_OPENSSL_CRYPTO_H) +# define PHP_CURL_NEED_OPENSSL_TSL +# include <openssl/crypto.h> +# else +# warning \ + "libcurl was compiled with OpenSSL support, but configure could not find " \ + "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# elif defined(HAVE_CURL_GNUTLS) +# if defined(HAVE_GCRYPT_H) +# define PHP_CURL_NEED_GNUTLS_TSL +# include <gcrypt.h> +# else +# warning \ + "libcurl was compiled with GnuTLS support, but configure could not find " \ + "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# else +# warning \ + "libcurl was compiled with SSL support, but configure could not determine which" \ + "library was used; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif /* HAVE_CURL_OPENSSL || HAVE_CURL_GNUTLS */ +# endif /* PHP_WIN32 */ +#endif /* ZTS && HAVE_CURL_SSL */ +/* }}} */ + +#define SMART_STR_PREALLOC 4096 + +#include "ext/standard/php_smart_str.h" +#include "ext/standard/info.h" +#include "ext/standard/file.h" +#include "ext/standard/url.h" +#include "php_curl.h" + +int le_curl; +int le_curl_multi_handle; + +#ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ +static MUTEX_T *php_curl_openssl_tsl = NULL; + +static void php_curl_ssl_lock(int mode, int n, const char * file, int line) +{ + if (mode & CRYPTO_LOCK) { + tsrm_mutex_lock(php_curl_openssl_tsl[n]); + } else { + tsrm_mutex_unlock(php_curl_openssl_tsl[n]); + } +} + +static unsigned long php_curl_ssl_id(void) +{ + return (unsigned long) tsrm_thread_id(); +} +#endif +/* }}} */ + +#ifdef PHP_CURL_NEED_GNUTLS_TSL /* {{{ */ +static int php_curl_ssl_mutex_create(void **m) +{ + if (*((MUTEX_T *) m) = tsrm_mutex_alloc()) { + return SUCCESS; + } else { + return FAILURE; + } +} + +static int php_curl_ssl_mutex_destroy(void **m) +{ + tsrm_mutex_free(*((MUTEX_T *) m)); + return SUCCESS; +} + +static int php_curl_ssl_mutex_lock(void **m) +{ + return tsrm_mutex_lock(*((MUTEX_T *) m)); +} + +static int php_curl_ssl_mutex_unlock(void **m) +{ + return tsrm_mutex_unlock(*((MUTEX_T *) m)); +} + +static struct gcry_thread_cbs php_curl_gnutls_tsl = { + GCRY_THREAD_OPTION_USER, + NULL, + php_curl_ssl_mutex_create, + php_curl_ssl_mutex_destroy, + php_curl_ssl_mutex_lock, + php_curl_ssl_mutex_unlock +}; +#endif +/* }}} */ + +static void _php_curl_close_ex(php_curl *ch TSRMLS_DC); +static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC); + + +#define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err; + +#define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s), (long) v); +#define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s), (double) v); +#define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s), (char *) (v ? v : ""), 1); +#define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s), (zval *) v); + +#if defined(PHP_WIN32) || defined(__GNUC__) +# define php_curl_ret(__ret) RETVAL_FALSE; return __ret; +#else +# define php_curl_ret(__ret) RETVAL_FALSE; return; +#endif + +static int php_curl_option_url(php_curl *ch, const char *url, const int len TSRMLS_DC) /* {{{ */ +{ + CURLcode error = CURLE_OK; +#if LIBCURL_VERSION_NUM < 0x071100 + char *copystr = NULL; +#endif + /* Disable file:// if open_basedir are used */ + if (PG(open_basedir) && *PG(open_basedir)) { +#if LIBCURL_VERSION_NUM >= 0x071304 + error = curl_easy_setopt(ch->cp, CURLOPT_PROTOCOLS, CURLPROTO_ALL & ~CURLPROTO_FILE); +#else + php_url *uri; + + if (!(uri = php_url_parse_ex(url, len))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL '%s'", url); + return 0; + } + + if (uri->scheme && !strncasecmp("file", uri->scheme, sizeof("file"))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol 'file' disabled in cURL"); + php_url_free(uri); + return 0; + } + php_url_free(uri); +#endif + } + /* Strings passed to libcurl as 'char *' arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ +#if LIBCURL_VERSION_NUM >= 0x071100 + error = curl_easy_setopt(ch->cp, CURLOPT_URL, url); +#else + copystr = estrndup(url, len); + error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr); + zend_llist_add_element(&ch->to_free->str, ©str); +#endif + + return (error == CURLE_OK ? 1 : 0); +} +/* }}} */ + +int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC) /* {{{ */ +{ + php_stream *stream; + if (!ch || !ch->handlers) { + return 0; + } + + if (ch->handlers->std_err) { + stream = (php_stream *) zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); + if (stream == NULL) { + if (reporterror) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr"); + } + zval_ptr_dtor(&ch->handlers->std_err); + ch->handlers->std_err = NULL; + + curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr); + } + } + if (ch->handlers->read && ch->handlers->read->stream) { + stream = (php_stream *) zend_fetch_resource(&ch->handlers->read->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); + if (stream == NULL) { + if (reporterror) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default"); + } + zval_ptr_dtor(&ch->handlers->read->stream); + ch->handlers->read->fd = 0; + ch->handlers->read->fp = 0; + ch->handlers->read->stream = NULL; + + curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); + } + } + if (ch->handlers->write_header && ch->handlers->write_header->stream) { + stream = (php_stream *) zend_fetch_resource(&ch->handlers->write_header->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); + if (stream == NULL) { + if (reporterror) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_WRITEHEADER resource has gone away, resetting to default"); + } + zval_ptr_dtor(&ch->handlers->write_header->stream); + ch->handlers->write_header->fp = 0; + ch->handlers->write_header->stream = NULL; + + ch->handlers->write_header->method = PHP_CURL_IGNORE; + curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); + } + } + if (ch->handlers->write && ch->handlers->write->stream) { + stream = (php_stream *) zend_fetch_resource(&ch->handlers->write->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); + if (stream == NULL) { + if (reporterror) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FILE resource has gone away, resetting to default"); + } + zval_ptr_dtor(&ch->handlers->write->stream); + ch->handlers->write->fp = 0; + ch->handlers->write->stream = NULL; + + ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers->write->type = PHP_CURL_ASCII; + curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); + } + } + return 1; +} +/* }}} */ + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_version, 0, 0, 0) + ZEND_ARG_INFO(0, version) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_init, 0, 0, 0) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_copy_handle, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_setopt, 0) + ZEND_ARG_INFO(0, ch) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_setopt_array, 0) + ZEND_ARG_INFO(0, ch) + ZEND_ARG_ARRAY_INFO(0, options, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_exec, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_getinfo, 0, 0, 1) + ZEND_ARG_INFO(0, ch) + ZEND_ARG_INFO(0, option) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_error, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_errno, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_close, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_init, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_add_handle, 0) + ZEND_ARG_INFO(0, mh) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_remove_handle, 0) + ZEND_ARG_INFO(0, mh) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_select, 0, 0, 1) + ZEND_ARG_INFO(0, mh) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_exec, 0, 0, 1) + ZEND_ARG_INFO(0, mh) + ZEND_ARG_INFO(1, still_running) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_getcontent, 0) + ZEND_ARG_INFO(0, ch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_multi_info_read, 0, 0, 1) + ZEND_ARG_INFO(0, mh) + ZEND_ARG_INFO(1, msgs_in_queue) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0) + ZEND_ARG_INFO(0, mh) +ZEND_END_ARG_INFO() +/* }}} */ + +/* {{{ curl_functions[] + */ +const zend_function_entry curl_functions[] = { + PHP_FE(curl_init, arginfo_curl_init) + PHP_FE(curl_copy_handle, arginfo_curl_copy_handle) + PHP_FE(curl_version, arginfo_curl_version) + PHP_FE(curl_setopt, arginfo_curl_setopt) + PHP_FE(curl_setopt_array, arginfo_curl_setopt_array) + PHP_FE(curl_exec, arginfo_curl_exec) + PHP_FE(curl_getinfo, arginfo_curl_getinfo) + PHP_FE(curl_error, arginfo_curl_error) + PHP_FE(curl_errno, arginfo_curl_errno) + PHP_FE(curl_close, arginfo_curl_close) + PHP_FE(curl_multi_init, arginfo_curl_multi_init) + PHP_FE(curl_multi_add_handle, arginfo_curl_multi_add_handle) + PHP_FE(curl_multi_remove_handle, arginfo_curl_multi_remove_handle) + PHP_FE(curl_multi_select, arginfo_curl_multi_select) + PHP_FE(curl_multi_exec, arginfo_curl_multi_exec) + PHP_FE(curl_multi_getcontent, arginfo_curl_multi_getcontent) + PHP_FE(curl_multi_info_read, arginfo_curl_multi_info_read) + PHP_FE(curl_multi_close, arginfo_curl_multi_close) + PHP_FE_END +}; +/* }}} */ + +/* {{{ curl_module_entry + */ +zend_module_entry curl_module_entry = { + STANDARD_MODULE_HEADER, + "curl", + curl_functions, + PHP_MINIT(curl), + PHP_MSHUTDOWN(curl), + NULL, + NULL, + PHP_MINFO(curl), + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_CURL +ZEND_GET_MODULE (curl) +#endif + +/* {{{ PHP_INI_BEGIN */ +PHP_INI_BEGIN() + PHP_INI_ENTRY("curl.cainfo", "", PHP_INI_SYSTEM, NULL) +PHP_INI_END() +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(curl) +{ + curl_version_info_data *d; + char **p; + char str[1024]; + size_t n = 0; + + d = curl_version_info(CURLVERSION_NOW); + php_info_print_table_start(); + php_info_print_table_row(2, "cURL support", "enabled"); + php_info_print_table_row(2, "cURL Information", d->version); + sprintf(str, "%d", d->age); + php_info_print_table_row(2, "Age", str); + + /* To update on each new cURL release using src/main.c in cURL sources */ + if (d->features) { + struct feat { + const char *name; + int bitmask; + }; + + unsigned int i; + + static const struct feat feats[] = { +#if LIBCURL_VERSION_NUM > 0x070a06 /* 7.10.7 */ + {"AsynchDNS", CURL_VERSION_ASYNCHDNS}, +#endif +#if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */ + {"Debug", CURL_VERSION_DEBUG}, + {"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE}, +#endif +#if LIBCURL_VERSION_NUM > 0x070b02 /* 7.12.0 */ + {"IDN", CURL_VERSION_IDN}, +#endif +#ifdef CURL_VERSION_IPV6 + {"IPv6", CURL_VERSION_IPV6}, +#endif +#if LIBCURL_VERSION_NUM > 0x070b00 /* 7.11.1 */ + {"Largefile", CURL_VERSION_LARGEFILE}, +#endif +#if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */ + {"NTLM", CURL_VERSION_NTLM}, +#endif +#if LIBCURL_VERSION_NUM > 0x070a07 /* 7.10.8 */ + {"SPNEGO", CURL_VERSION_SPNEGO}, +#endif +#ifdef CURL_VERSION_SSL + {"SSL", CURL_VERSION_SSL}, +#endif +#if LIBCURL_VERSION_NUM > 0x070d01 /* 7.13.2 */ + {"SSPI", CURL_VERSION_SSPI}, +#endif +#ifdef CURL_VERSION_KERBEROS4 + {"krb4", CURL_VERSION_KERBEROS4}, +#endif +#ifdef CURL_VERSION_LIBZ + {"libz", CURL_VERSION_LIBZ}, +#endif +#if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */ + {"CharConv", CURL_VERSION_CONV}, +#endif + {NULL, 0} + }; + + php_info_print_table_row(1, "Features"); + for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) { + if (feats[i].name) { + php_info_print_table_row(2, feats[i].name, d->features & feats[i].bitmask ? "Yes" : "No"); + } + } + } + + n = 0; + p = (char **) d->protocols; + while (*p != NULL) { + n += sprintf(str + n, "%s%s", *p, *(p + 1) != NULL ? ", " : ""); + p++; + } + php_info_print_table_row(2, "Protocols", str); + + php_info_print_table_row(2, "Host", d->host); + + if (d->ssl_version) { + php_info_print_table_row(2, "SSL Version", d->ssl_version); + } + + if (d->libz_version) { + php_info_print_table_row(2, "ZLib Version", d->libz_version); + } + +#if defined(CURLVERSION_SECOND) && CURLVERSION_NOW >= CURLVERSION_SECOND + if (d->ares) { + php_info_print_table_row(2, "ZLib Version", d->ares); + } +#endif + +#if defined(CURLVERSION_THIRD) && CURLVERSION_NOW >= CURLVERSION_THIRD + if (d->libidn) { + php_info_print_table_row(2, "libIDN Version", d->libidn); + } +#endif + +#if LIBCURL_VERSION_NUM >= 0x071300 + + if (d->iconv_ver_num) { + php_info_print_table_row(2, "IconV Version", d->iconv_ver_num); + } + + if (d->libssh_version) { + php_info_print_table_row(2, "libSSH Version", d->libssh_version); + } +#endif + php_info_print_table_end(); +} +/* }}} */ + +#define REGISTER_CURL_CONSTANT(__c) REGISTER_LONG_CONSTANT(#__c, __c, CONST_CS | CONST_PERSISTENT) + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(curl) +{ + le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); + le_curl_multi_handle = zend_register_list_destructors_ex(_php_curl_multi_close, NULL, "curl_multi", module_number); + + REGISTER_INI_ENTRIES(); + + /* See http://curl.haxx.se/lxr/source/docs/libcurl/symbols-in-versions + or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list + of options and which version they were introduced */ + + /* Constants for curl_setopt() */ +#if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */ + REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE); + REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER); + REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4); + REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE); + REGISTER_CURL_CONSTANT(CURLOPT_DNS_CACHE_TIMEOUT); + REGISTER_CURL_CONSTANT(CURLOPT_PORT); + REGISTER_CURL_CONSTANT(CURLOPT_FILE); + REGISTER_CURL_CONSTANT(CURLOPT_READDATA); + REGISTER_CURL_CONSTANT(CURLOPT_INFILE); + REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE); + REGISTER_CURL_CONSTANT(CURLOPT_URL); + REGISTER_CURL_CONSTANT(CURLOPT_PROXY); + REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE); + REGISTER_CURL_CONSTANT(CURLOPT_HEADER); + REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER); + REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS); + REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION); + REGISTER_CURL_CONSTANT(CURLOPT_NOBODY); + REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR); + REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD); + REGISTER_CURL_CONSTANT(CURLOPT_POST); + REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY); + REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND); + REGISTER_CURL_CONSTANT(CURLOPT_NETRC); + REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION); +#if CURLOPT_FTPASCII != 0 + REGISTER_CURL_CONSTANT(CURLOPT_FTPASCII); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_PUT); +#if CURLOPT_MUTE != 0 + REGISTER_CURL_CONSTANT(CURLOPT_MUTE); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_USERPWD); + REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERPWD); + REGISTER_CURL_CONSTANT(CURLOPT_RANGE); + REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT); +#if LIBCURL_VERSION_NUM > 0x071002 + REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS); + REGISTER_CURL_CONSTANT(CURLOPT_REFERER); + REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT); + REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT); + REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV); + REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT); + REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME); + REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM); + REGISTER_CURL_CONSTANT(CURLOPT_COOKIE); + REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION); + REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER); + REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT); + REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTPASSWD); + REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER); + REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST); + REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE); + REGISTER_CURL_CONSTANT(CURLOPT_SSLVERSION); + REGISTER_CURL_CONSTANT(CURLOPT_TIMECONDITION); + REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE); + REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST); + REGISTER_CURL_CONSTANT(CURLOPT_STDERR); + REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT); + REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER); + REGISTER_CURL_CONSTANT(CURLOPT_QUOTE); + REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE); + REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE); + REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL); + REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL); + REGISTER_CURL_CONSTANT(CURLOPT_FILETIME); + REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION); + REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION); +#if CURLOPT_PASSWDFUNCTION != 0 + REGISTER_CURL_CONSTANT(CURLOPT_PASSWDFUNCTION); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION); + REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS); + REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS); + REGISTER_CURL_CONSTANT(CURLOPT_CLOSEPOLICY); + REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT); + REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE); + REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE); + REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET); + REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT); +#if LIBCURL_VERSION_NUM > 0x071002 + REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER); + REGISTER_CURL_CONSTANT(CURLOPT_CAINFO); + REGISTER_CURL_CONSTANT(CURLOPT_CAPATH); + REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR); + REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST); + REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER); + REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL); + REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE); + REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE); + REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET); + REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION); + REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY); + REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE); + REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD); + REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE); + REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT); + REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE); + REGISTER_CURL_CONSTANT(CURLOPT_CRLF); + REGISTER_CURL_CONSTANT(CURLOPT_ENCODING); + REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT); + REGISTER_CURL_CONSTANT(CURLOPT_UNRESTRICTED_AUTH); + REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT); +#if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */ + REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY); +#endif + REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES); + REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE); + REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE); + REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD); + +#if LIBCURL_VERSION_NUM > 0x070f04 /* CURLOPT_MAX_RECV_SPEED_LARGE & CURLOPT_MAX_SEND_SPEED_LARGE are available since curl 7.15.5 */ + REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE); + REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE); +#endif + +#if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */ + REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH); + /* http authentication options */ + REGISTER_CURL_CONSTANT(CURLAUTH_BASIC); + REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST); + REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE); + REGISTER_CURL_CONSTANT(CURLAUTH_NTLM); + REGISTER_CURL_CONSTANT(CURLAUTH_ANY); + REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE); +#endif + +#if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */ + REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH); + REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS); +#endif + + REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE); + + /* Constants effecting the way CURLOPT_CLOSEPOLICY works */ + REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_RECENTLY_USED); + REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_TRAFFIC); + REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_SLOWEST); + REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_CALLBACK); + REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_OLDEST); + + /* Info constants */ + REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL); + REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE); + REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE); + REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE); + REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_FILETIME); + REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT); + REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD); + REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE); + REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME); + REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT); + REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT); + REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE); +#if LIBCURL_VERSION_NUM > 0x071301 + REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO); +#endif +#if LIBCURL_VERSION_NUM >= 0x071202 + REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL); +#endif +#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */ + REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_IP); +#endif +#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */ + REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_PORT); + REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_IP); + REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_PORT); +#endif + + + /* cURL protocol constants (curl_version) */ + REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6); + REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4); + REGISTER_CURL_CONSTANT(CURL_VERSION_SSL); + REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ); + + /* version constants */ + REGISTER_CURL_CONSTANT(CURLVERSION_NOW); + + /* Error Constants */ + REGISTER_CURL_CONSTANT(CURLE_OK); + REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL); + REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT); + REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT); + REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER); + REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY); + REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST); + REGISTER_CURL_CONSTANT(CURLE_COULDNT_CONNECT); + REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY); + REGISTER_CURL_CONSTANT(CURLE_FTP_ACCESS_DENIED); + REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT); + REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY); + REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY); + REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY); + REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT); + REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_GET_HOST); + REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_RECONNECT); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY); + REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE); + REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR); + REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR); + REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND); + REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR); + REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE); + REGISTER_CURL_CONSTANT(CURLE_READ_ERROR); + REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY); + REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_ASCII); + REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_USE_REST); + REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE); + REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR); + REGISTER_CURL_CONSTANT(CURLE_HTTP_POST_ERROR); + REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR); + REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME); + REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE); + REGISTER_CURL_CONSTANT(CURLE_LDAP_CANNOT_BIND); + REGISTER_CURL_CONSTANT(CURLE_LDAP_SEARCH_FAILED); + REGISTER_CURL_CONSTANT(CURLE_LIBRARY_NOT_FOUND); + REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND); + REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK); + REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT); + REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER); + REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED); + REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED); + REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS); + REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION); + REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX); + REGISTER_CURL_CONSTANT(CURLE_OBSOLETE); + REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE); + REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING); + REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND); + REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED); + REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR); + REGISTER_CURL_CONSTANT(CURLE_RECV_ERROR); + REGISTER_CURL_CONSTANT(CURLE_SHARE_IN_USE); + REGISTER_CURL_CONSTANT(CURLE_SSL_CERTPROBLEM); + REGISTER_CURL_CONSTANT(CURLE_SSL_CIPHER); + REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT); + REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING); +#if LIBCURL_VERSION_NUM >= 0x070a08 + REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL); + REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED); +#endif +#if LIBCURL_VERSION_NUM >= 0x070b00 + REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED); +#endif + REGISTER_CURL_CONSTANT(CURLPROXY_HTTP); + REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4); + REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5); + + REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL); + REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED); + REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED); + + REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE); + REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_0); + REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_1); + + REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM); + REGISTER_CURL_CONSTANT(CURLM_OK); + REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE); + REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE); + REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY); + REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR); + + REGISTER_CURL_CONSTANT(CURLMSG_DONE); + +#if LIBCURL_VERSION_NUM >= 0x070c02 + REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH); + REGISTER_CURL_CONSTANT(CURLFTPAUTH_DEFAULT); + REGISTER_CURL_CONSTANT(CURLFTPAUTH_SSL); + REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS); +#endif + +#if LIBCURL_VERSION_NUM > 0x070b00 + REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL); + REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE); + REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY); + REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL); + REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL); +#endif + +#if LIBCURL_VERSION_NUM > 0x071301 + REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO); + REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR); +#endif + +/* SSH support works in 7.19.0+ using libssh2 */ +#if LIBCURL_VERSION_NUM >= 0x071300 + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE); + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY); + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD); + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST); + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD); + REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT); + REGISTER_CURL_CONSTANT(CURLOPT_SSH_AUTH_TYPES); + REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD); + REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE); + REGISTER_CURL_CONSTANT(CURLOPT_SSH_PRIVATE_KEYFILE); + REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5); + REGISTER_CURL_CONSTANT(CURLE_SSH); +#endif + +#if LIBCURL_VERSION_NUM >= 0x071304 + REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS); + REGISTER_CURL_CONSTANT(CURLOPT_PROTOCOLS); + REGISTER_CURL_CONSTANT(CURLPROTO_HTTP); + REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS); + REGISTER_CURL_CONSTANT(CURLPROTO_FTP); + REGISTER_CURL_CONSTANT(CURLPROTO_FTPS); + REGISTER_CURL_CONSTANT(CURLPROTO_SCP); + REGISTER_CURL_CONSTANT(CURLPROTO_SFTP); + REGISTER_CURL_CONSTANT(CURLPROTO_TELNET); + REGISTER_CURL_CONSTANT(CURLPROTO_LDAP); + REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS); + REGISTER_CURL_CONSTANT(CURLPROTO_DICT); + REGISTER_CURL_CONSTANT(CURLPROTO_FILE); + REGISTER_CURL_CONSTANT(CURLPROTO_TFTP); + REGISTER_CURL_CONSTANT(CURLPROTO_ALL); +#endif + +#if LIBCURL_VERSION_NUM >= 0x070f01 + REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD); + REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP); +#endif + +#if LIBCURL_VERSION_NUM >= 0x071001 + REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD); + REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD); + REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD); +#endif + +#ifdef PHP_CURL_NEED_OPENSSL_TSL + if (!CRYPTO_get_id_callback()) { + int i, c = CRYPTO_num_locks(); + + php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T)); + if (!php_curl_openssl_tsl) { + return FAILURE; + } + + for (i = 0; i < c; ++i) { + php_curl_openssl_tsl[i] = tsrm_mutex_alloc(); + } + + CRYPTO_set_id_callback(php_curl_ssl_id); + CRYPTO_set_locking_callback(php_curl_ssl_lock); + } +#endif +#ifdef PHP_CURL_NEED_GNUTLS_TSL + gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl); +#endif + + if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK) { + return FAILURE; + } + +#ifdef PHP_CURL_URL_WRAPPERS +# if HAVE_CURL_VERSION_INFO + { + curl_version_info_data *info = curl_version_info(CURLVERSION_NOW); + char **p = (char **)info->protocols; + + while (*p != NULL) { + /* Do not enable cURL "file" protocol and make sure cURL is always used when --with-curlwrappers is enabled */ + if (strncasecmp(*p, "file", sizeof("file")-1) != 0) { + php_unregister_url_stream_wrapper(*p TSRMLS_CC); + php_register_url_stream_wrapper(*p, &php_curl_wrapper TSRMLS_CC); + } + (void) *p++; + } + } +# else + php_unregister_url_stream_wrapper("http"); + php_register_url_stream_wrapper("http", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("https"); + php_register_url_stream_wrapper("https", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ftp"); + php_register_url_stream_wrapper("ftp", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ftps"); + php_register_url_stream_wrapper("ftps", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ldap"); + php_register_url_stream_wrapper("ldap", &php_curl_wrapper TSRMLS_CC); +# endif +#endif + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(curl) +{ +#ifdef PHP_CURL_URL_WRAPPERS + php_unregister_url_stream_wrapper("http" TSRMLS_CC); + php_unregister_url_stream_wrapper("https" TSRMLS_CC); + php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); + php_unregister_url_stream_wrapper("ldap" TSRMLS_CC); +#endif + curl_global_cleanup(); +#ifdef PHP_CURL_NEED_OPENSSL_TSL + if (php_curl_openssl_tsl) { + int i, c = CRYPTO_num_locks(); + + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < c; ++i) { + tsrm_mutex_free(php_curl_openssl_tsl[i]); + } + + free(php_curl_openssl_tsl); + php_curl_openssl_tsl = NULL; + } +#endif + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +/* {{{ curl_write_nothing + * Used as a work around. See _php_curl_close_ex + */ +static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ctx) +{ + return size * nmemb; +} +/* }}} */ + +/* {{{ curl_write + */ +static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) +{ + php_curl *ch = (php_curl *) ctx; + php_curl_write *t = ch->handlers->write; + size_t length = size * nmemb; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_write() called\n"); + fprintf(stderr, "data = %s, size = %d, nmemb = %d, ctx = %x\n", data, size, nmemb, ctx); +#endif + + switch (t->method) { + case PHP_CURL_STDOUT: + PHPWRITE(data, length); + break; + case PHP_CURL_FILE: + return fwrite(data, size, nmemb, t->fp); + case PHP_CURL_RETURN: + if (length > 0) { + smart_str_appendl(&t->buf, data, (int) length); + } + break; + case PHP_CURL_USER: { + zval **argv[2]; + zval *retval_ptr = NULL; + zval *handle = NULL; + zval *zdata = NULL; + int error; + zend_fcall_info fci; + + MAKE_STD_ZVAL(handle); + ZVAL_RESOURCE(handle, ch->id); + zend_list_addref(ch->id); + argv[0] = &handle; + + MAKE_STD_ZVAL(zdata); + ZVAL_STRINGL(zdata, data, length, 1); + argv[1] = &zdata; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.object_ptr = NULL; + fci.function_name = t->func_name; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 2; + fci.params = argv; + fci.no_separation = 0; + fci.symbol_table = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION"); + length = -1; + } else if (retval_ptr) { + if (Z_TYPE_P(retval_ptr) != IS_LONG) { + convert_to_long_ex(&retval_ptr); + } + length = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + } + + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + break; + } + } + + return length; +} +/* }}} */ + +/* {{{ curl_progress + */ +static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + php_curl *ch = (php_curl *) clientp; + php_curl_progress *t = ch->handlers->progress; + int length = -1; + size_t rval = 0; + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_progress() called\n"); + fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); +#endif + + switch (t->method) { + case PHP_CURL_USER: { + zval **argv[4]; + zval *zdltotal = NULL; + zval *zdlnow = NULL; + zval *zultotal = NULL; + zval *zulnow = NULL; + zval *retval_ptr; + int error; + zend_fcall_info fci; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + MAKE_STD_ZVAL(zdltotal); + MAKE_STD_ZVAL(zdlnow); + MAKE_STD_ZVAL(zultotal); + MAKE_STD_ZVAL(zulnow); + + ZVAL_LONG(zdltotal, (long) dltotal); + ZVAL_LONG(zdlnow, (long) dlnow); + ZVAL_LONG(zultotal, (long) ultotal); + ZVAL_LONG(zulnow, (long) ulnow); + + argv[0] = &zdltotal; + argv[1] = &zdlnow; + argv[2] = &zultotal; + argv[3] = &zulnow; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = t->func_name; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 4; + fci.params = argv; + fci.no_separation = 0; + fci.symbol_table = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION"); + length = -1; + } else if (retval_ptr) { + if (Z_TYPE_P(retval_ptr) != IS_LONG) { + convert_to_long_ex(&retval_ptr); + } + if (0 != Z_LVAL_P(retval_ptr)) { + rval = 1; + } + zval_ptr_dtor(&retval_ptr); + } + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + zval_ptr_dtor(argv[2]); + zval_ptr_dtor(argv[3]); + break; + } + } + return rval; +} +/* }}} */ + +/* {{{ curl_read + */ +static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) +{ + php_curl *ch = (php_curl *) ctx; + php_curl_read *t = ch->handlers->read; + int length = 0; + + switch (t->method) { + case PHP_CURL_DIRECT: + if (t->fp) { + length = fread(data, size, nmemb, t->fp); + } + break; + case PHP_CURL_USER: { + zval **argv[3]; + zval *handle = NULL; + zval *zfd = NULL; + zval *zlength = NULL; + zval *retval_ptr; + int error; + zend_fcall_info fci; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + MAKE_STD_ZVAL(handle); + MAKE_STD_ZVAL(zfd); + MAKE_STD_ZVAL(zlength); + + ZVAL_RESOURCE(handle, ch->id); + zend_list_addref(ch->id); + ZVAL_RESOURCE(zfd, t->fd); + zend_list_addref(t->fd); + ZVAL_LONG(zlength, (int) size * nmemb); + + argv[0] = &handle; + argv[1] = &zfd; + argv[2] = &zlength; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = t->func_name; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 3; + fci.params = argv; + fci.no_separation = 0; + fci.symbol_table = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_READFUNCTION"); +#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */ + length = CURL_READFUNC_ABORT; +#endif + } else if (retval_ptr) { + if (Z_TYPE_P(retval_ptr) == IS_STRING) { + length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr)); + memcpy(data, Z_STRVAL_P(retval_ptr), length); + } + zval_ptr_dtor(&retval_ptr); + } + + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + zval_ptr_dtor(argv[2]); + break; + } + } + + return length; +} +/* }}} */ + +/* {{{ curl_write_header + */ +static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx) +{ + php_curl *ch = (php_curl *) ctx; + php_curl_write *t = ch->handlers->write_header; + size_t length = size * nmemb; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + switch (t->method) { + case PHP_CURL_STDOUT: + /* Handle special case write when we're returning the entire transfer + */ + if (ch->handlers->write->method == PHP_CURL_RETURN && length > 0) { + smart_str_appendl(&ch->handlers->write->buf, data, (int) length); + } else { + PHPWRITE(data, length); + } + break; + case PHP_CURL_FILE: + return fwrite(data, size, nmemb, t->fp); + case PHP_CURL_USER: { + zval **argv[2]; + zval *handle = NULL; + zval *zdata = NULL; + zval *retval_ptr; + int error; + zend_fcall_info fci; + + MAKE_STD_ZVAL(handle); + MAKE_STD_ZVAL(zdata); + + ZVAL_RESOURCE(handle, ch->id); + zend_list_addref(ch->id); + ZVAL_STRINGL(zdata, data, length, 1); + + argv[0] = &handle; + argv[1] = &zdata; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = t->func_name; + fci.symbol_table = NULL; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 2; + fci.params = argv; + fci.no_separation = 0; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION"); + length = -1; + } else if (retval_ptr) { + if (Z_TYPE_P(retval_ptr) != IS_LONG) { + convert_to_long_ex(&retval_ptr); + } + length = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + } + zval_ptr_dtor(argv[0]); + zval_ptr_dtor(argv[1]); + break; + } + + case PHP_CURL_IGNORE: + return length; + + default: + return -1; + } + + return length; +} +/* }}} */ + +static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx) /* {{{ */ +{ + php_curl *ch = (php_curl *) ctx; + + if (type == CURLINFO_HEADER_OUT) { + if (ch->header.str_len) { + efree(ch->header.str); + } + if (buf_len > 0) { + ch->header.str = estrndup(buf, buf_len); + ch->header.str_len = buf_len; + } + } + + return 0; +} +/* }}} */ + +#if CURLOPT_PASSWDFUNCTION != 0 +/* {{{ curl_passwd + */ +static size_t curl_passwd(void *ctx, char *prompt, char *buf, int buflen) +{ + php_curl *ch = (php_curl *) ctx; + zval *func = ch->handlers->passwd; + zval *argv[3]; + zval *retval = NULL; + int error; + int ret = -1; + TSRMLS_FETCH_FROM_CTX(ch->thread_ctx); + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(argv[2]); + + ZVAL_RESOURCE(argv[0], ch->id); + zend_list_addref(ch->id); + ZVAL_STRING(argv[1], prompt, 1); + ZVAL_LONG(argv[2], buflen); + + error = call_user_function(EG(function_table), NULL, func, retval, 2, argv TSRMLS_CC); + if (error == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_PASSWDFUNCTION"); + } else if (Z_TYPE_P(retval) == IS_STRING) { + if (Z_STRLEN_P(retval) > buflen) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Returned password is too long for libcurl to handle"); + } else { + strlcpy(buf, Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "User handler '%s' did not return a string", Z_STRVAL_P(func)); + } + + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&argv[2]); + zval_ptr_dtor(&retval); + + return ret; +} +/* }}} */ +#endif + +/* {{{ curl_free_string + */ +static void curl_free_string(void **string) +{ + efree(*string); +} +/* }}} */ + +/* {{{ curl_free_post + */ +static void curl_free_post(void **post) +{ + curl_formfree((struct HttpPost *) *post); +} +/* }}} */ + +/* {{{ curl_free_slist + */ +static void curl_free_slist(void **slist) +{ + curl_slist_free_all((struct curl_slist *) *slist); +} +/* }}} */ + +/* {{{ proto array curl_version([int version]) + Return cURL version information. */ +PHP_FUNCTION(curl_version) +{ + curl_version_info_data *d; + long uversion = CURLVERSION_NOW; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &uversion) == FAILURE) { + return; + } + + d = curl_version_info(uversion); + if (d == NULL) { + RETURN_FALSE; + } + + array_init(return_value); + + CAAL("version_number", d->version_num); + CAAL("age", d->age); + CAAL("features", d->features); + CAAL("ssl_version_number", d->ssl_version_num); + CAAS("version", d->version); + CAAS("host", d->host); + CAAS("ssl_version", d->ssl_version); + CAAS("libz_version", d->libz_version); + /* Add an array of protocols */ + { + char **p = (char **) d->protocols; + zval *protocol_list = NULL; + + MAKE_STD_ZVAL(protocol_list); + array_init(protocol_list); + + while (*p != NULL) { + add_next_index_string(protocol_list, *p, 1); + p++; + } + CAAZ("protocols", protocol_list); + } +} +/* }}} */ + +/* {{{ alloc_curl_handle + */ +static void alloc_curl_handle(php_curl **ch) +{ + *ch = emalloc(sizeof(php_curl)); + (*ch)->to_free = ecalloc(1, sizeof(struct _php_curl_free)); + (*ch)->handlers = ecalloc(1, sizeof(php_curl_handlers)); + (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); + (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); + (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); + (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); + + (*ch)->in_callback = 0; + (*ch)->header.str_len = 0; + + memset(&(*ch)->err, 0, sizeof((*ch)->err)); + (*ch)->handlers->write->stream = NULL; + (*ch)->handlers->write_header->stream = NULL; + (*ch)->handlers->read->stream = NULL; + + zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0); + zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist, 0); + zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0); +} +/* }}} */ + +#if LIBCURL_VERSION_NUM > 0x071301 +/* {{{ split_certinfo + */ +static void split_certinfo(char *string, zval *hash) +{ + char *org = estrdup(string); + char *s = org; + char *split; + + if(org) { + do { + char *key; + char *val; + char *tmp; + + split = strstr(s, "; "); + if(split) + *split = '\0'; + + key = s; + tmp = memchr(key, '=', 64); + if(tmp) { + *tmp = '\0'; + val = tmp+1; + add_assoc_string(hash, key, val, 1); + } + s = split+2; + } while(split); + efree(org); + } +} +/* }}} */ + +/* {{{ create_certinfo + */ +static void create_certinfo(struct curl_certinfo *ci, zval *listcode TSRMLS_DC) +{ + int i; + + if(ci) { + zval *certhash = NULL; + + for(i=0; i<ci->num_of_certs; i++) { + struct curl_slist *slist; + + MAKE_STD_ZVAL(certhash); + array_init(certhash); + for(slist = ci->certinfo[i]; slist; slist = slist->next) { + int len; + char s[64]; + char *tmp; + strncpy(s, slist->data, 64); + tmp = memchr(s, ':', 64); + if(tmp) { + *tmp = '\0'; + len = strlen(s); + if(!strcmp(s, "Subject") || !strcmp(s, "Issuer")) { + zval *hash; + + MAKE_STD_ZVAL(hash); + array_init(hash); + + split_certinfo(&slist->data[len+1], hash); + add_assoc_zval(certhash, s, hash); + } else { + add_assoc_string(certhash, s, &slist->data[len+1], 1); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not extract hash key from certificate info"); + } + } + add_next_index_zval(listcode, certhash); + } + } +} +/* }}} */ +#endif + +/* {{{ proto resource curl_init([string url]) + Initialize a cURL session */ +PHP_FUNCTION(curl_init) +{ + php_curl *ch; + CURL *cp; + zval *clone; + char *url = NULL; + int url_len = 0; + char *cainfo; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &url, &url_len) == FAILURE) { + return; + } + + cp = curl_easy_init(); + if (!cp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize a new cURL handle"); + RETURN_FALSE; + } + + alloc_curl_handle(&ch); + TSRMLS_SET_CTX(ch->thread_ctx); + + ch->cp = cp; + + ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers->write->type = PHP_CURL_ASCII; + ch->handlers->read->method = PHP_CURL_DIRECT; + ch->handlers->write_header->method = PHP_CURL_IGNORE; + + ch->uses = 0; + + MAKE_STD_ZVAL(clone); + ch->clone = clone; + + curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); + curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); + curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write); + curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read); + curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header); + curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); + curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120); + curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */ + + cainfo = INI_STR("curl.cainfo"); + if (cainfo && strlen(cainfo) > 0) { + curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo); + } + +#if defined(ZTS) + curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1); +#endif + + if (url) { + if (!php_curl_option_url(ch, url, url_len TSRMLS_CC)) { + _php_curl_close_ex(ch TSRMLS_CC); + RETURN_FALSE; + } + } + + ZEND_REGISTER_RESOURCE(return_value, ch, le_curl); + ch->id = Z_LVAL_P(return_value); +} +/* }}} */ + +/* {{{ proto resource curl_copy_handle(resource ch) + Copy a cURL handle along with all of it's preferences */ +PHP_FUNCTION(curl_copy_handle) +{ + CURL *cp; + zval *zid; + php_curl *ch, *dupch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + cp = curl_easy_duphandle(ch->cp); + if (!cp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot duplicate cURL handle"); + RETURN_FALSE; + } + + alloc_curl_handle(&dupch); + TSRMLS_SET_CTX(dupch->thread_ctx); + + dupch->cp = cp; + dupch->uses = 0; + ch->uses++; + if (ch->handlers->write->stream) { + Z_ADDREF_P(ch->handlers->write->stream); + } + dupch->handlers->write->stream = ch->handlers->write->stream; + dupch->handlers->write->method = ch->handlers->write->method; + dupch->handlers->write->type = ch->handlers->write->type; + if (ch->handlers->read->stream) { + Z_ADDREF_P(ch->handlers->read->stream); + } + dupch->handlers->read->stream = ch->handlers->read->stream; + dupch->handlers->read->method = ch->handlers->read->method; + dupch->handlers->write_header->method = ch->handlers->write_header->method; + if (ch->handlers->write_header->stream) { + Z_ADDREF_P(ch->handlers->write_header->stream); + } + dupch->handlers->write_header->stream = ch->handlers->write_header->stream; + + dupch->handlers->write->fp = ch->handlers->write->fp; + dupch->handlers->write_header->fp = ch->handlers->write_header->fp; + dupch->handlers->read->fp = ch->handlers->read->fp; + dupch->handlers->read->fd = ch->handlers->read->fd; +#if CURLOPT_PASSWDDATA != 0 + if (ch->handlers->passwd) { + zval_add_ref(&ch->handlers->passwd); + dupch->handlers->passwd = ch->handlers->passwd; + curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) dupch); + } +#endif + if (ch->handlers->write->func_name) { + zval_add_ref(&ch->handlers->write->func_name); + dupch->handlers->write->func_name = ch->handlers->write->func_name; + } + if (ch->handlers->read->func_name) { + zval_add_ref(&ch->handlers->read->func_name); + dupch->handlers->read->func_name = ch->handlers->read->func_name; + } + if (ch->handlers->write_header->func_name) { + zval_add_ref(&ch->handlers->write_header->func_name); + dupch->handlers->write_header->func_name = ch->handlers->write_header->func_name; + } + + if (ch->handlers->progress->func_name) { + zval_add_ref(&ch->handlers->progress->func_name); + dupch->handlers->progress->func_name = ch->handlers->progress->func_name; + } + dupch->handlers->progress->method = ch->handlers->progress->method; + + curl_easy_setopt(dupch->cp, CURLOPT_ERRORBUFFER, dupch->err.str); + curl_easy_setopt(dupch->cp, CURLOPT_FILE, (void *) dupch); + curl_easy_setopt(dupch->cp, CURLOPT_INFILE, (void *) dupch); + curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER, (void *) dupch); + curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch); + + efree(dupch->to_free); + dupch->to_free = ch->to_free; + + /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ + Z_ADDREF_P(ch->clone); + dupch->clone = ch->clone; + + ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl); + dupch->id = Z_LVAL_P(return_value); +} +/* }}} */ + +static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */ +{ + CURLcode error=CURLE_OK; + + switch (option) { + /* Long options */ + case CURLOPT_SSL_VERIFYHOST: + if(Z_BVAL_PP(zvalue) == 1) { +#if LIBCURL_VERSION_NUM <= 0x071c00 /* 7.28.0 */ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "CURLOPT_SSL_VERIFYHOST with value 1 is deprecated and will be removed as of libcurl 7.28.1. It is recommended to use value 2 instead"); +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead"); + error = curl_easy_setopt(ch->cp, option, 2); + break; +#endif + } + case CURLOPT_INFILESIZE: + case CURLOPT_VERBOSE: + case CURLOPT_HEADER: + case CURLOPT_NOPROGRESS: + case CURLOPT_NOBODY: + case CURLOPT_FAILONERROR: + case CURLOPT_UPLOAD: + case CURLOPT_POST: + case CURLOPT_FTPLISTONLY: + case CURLOPT_FTPAPPEND: + case CURLOPT_NETRC: + case CURLOPT_PUT: +#if CURLOPT_MUTE != 0 + case CURLOPT_MUTE: +#endif + case CURLOPT_TIMEOUT: +#if LIBCURL_VERSION_NUM > 0x071002 + case CURLOPT_TIMEOUT_MS: +#endif + case CURLOPT_FTP_USE_EPSV: + case CURLOPT_LOW_SPEED_LIMIT: + case CURLOPT_SSLVERSION: + case CURLOPT_LOW_SPEED_TIME: + case CURLOPT_RESUME_FROM: + case CURLOPT_TIMEVALUE: + case CURLOPT_TIMECONDITION: + case CURLOPT_TRANSFERTEXT: + case CURLOPT_HTTPPROXYTUNNEL: + case CURLOPT_FILETIME: + case CURLOPT_MAXREDIRS: + case CURLOPT_MAXCONNECTS: + case CURLOPT_CLOSEPOLICY: + case CURLOPT_FRESH_CONNECT: + case CURLOPT_FORBID_REUSE: + case CURLOPT_CONNECTTIMEOUT: +#if LIBCURL_VERSION_NUM > 0x071002 + case CURLOPT_CONNECTTIMEOUT_MS: +#endif + case CURLOPT_SSL_VERIFYPEER: + case CURLOPT_DNS_USE_GLOBAL_CACHE: + case CURLOPT_NOSIGNAL: + case CURLOPT_PROXYTYPE: + case CURLOPT_BUFFERSIZE: + case CURLOPT_HTTPGET: + case CURLOPT_HTTP_VERSION: + case CURLOPT_CRLF: + case CURLOPT_DNS_CACHE_TIMEOUT: + case CURLOPT_PROXYPORT: + case CURLOPT_FTP_USE_EPRT: +#if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */ + case CURLOPT_HTTPAUTH: +#endif +#if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */ + case CURLOPT_PROXYAUTH: + case CURLOPT_FTP_CREATE_MISSING_DIRS: +#endif + +#if LIBCURL_VERSION_NUM >= 0x070c02 + case CURLOPT_FTPSSLAUTH: +#endif +#if LIBCURL_VERSION_NUM > 0x070b00 + case CURLOPT_FTP_SSL: +#endif + case CURLOPT_UNRESTRICTED_AUTH: + case CURLOPT_PORT: + case CURLOPT_AUTOREFERER: + case CURLOPT_COOKIESESSION: +#if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */ + case CURLOPT_TCP_NODELAY: +#endif +#if LIBCURL_VERSION_NUM >= 0x71304 + case CURLOPT_REDIR_PROTOCOLS: + case CURLOPT_PROTOCOLS: +#endif +#if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */ + case CURLOPT_IPRESOLVE: +#endif +#if LIBCURL_VERSION_NUM >= 0x070f01 + case CURLOPT_FTP_FILEMETHOD: + case CURLOPT_FTP_SKIP_PASV_IP: +#endif +#if LIBCURL_VERSION_NUM > 0x071301 + case CURLOPT_CERTINFO: +#endif + convert_to_long_ex(zvalue); +#if LIBCURL_VERSION_NUM >= 0x71304 + if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) && + (PG(open_basedir) && *PG(open_basedir)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set"); + RETVAL_FALSE; + return 1; + } +#endif + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; +#if LIBCURL_VERSION_NUM > 0x070f04 + case CURLOPT_MAX_RECV_SPEED_LARGE: + case CURLOPT_MAX_SEND_SPEED_LARGE: + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_PP(zvalue)); + break; +#endif + case CURLOPT_FOLLOWLOCATION: + convert_to_long_ex(zvalue); + if (PG(open_basedir) && *PG(open_basedir)) { + if (Z_LVAL_PP(zvalue) != 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set"); + RETVAL_FALSE; + return 1; + } + } + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; +#if LIBCURL_VERSION_NUM > 0x071301 + case CURLOPT_POSTREDIR: + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_PP(zvalue) & CURL_REDIR_POST_ALL); + break; +#endif + case CURLOPT_PRIVATE: + case CURLOPT_URL: + case CURLOPT_PROXY: + case CURLOPT_USERPWD: + case CURLOPT_PROXYUSERPWD: + case CURLOPT_RANGE: + case CURLOPT_CUSTOMREQUEST: + case CURLOPT_USERAGENT: + case CURLOPT_FTPPORT: + case CURLOPT_COOKIE: + case CURLOPT_REFERER: + case CURLOPT_INTERFACE: + case CURLOPT_KRB4LEVEL: + case CURLOPT_EGDSOCKET: + case CURLOPT_CAINFO: + case CURLOPT_CAPATH: + case CURLOPT_SSL_CIPHER_LIST: + case CURLOPT_SSLKEY: + case CURLOPT_SSLKEYTYPE: + case CURLOPT_SSLKEYPASSWD: + case CURLOPT_SSLENGINE: + case CURLOPT_SSLENGINE_DEFAULT: + case CURLOPT_SSLCERTTYPE: + case CURLOPT_ENCODING: +#if LIBCURL_VERSION_NUM >= 0x071300 + case CURLOPT_SSH_PUBLIC_KEYFILE: + case CURLOPT_SSH_PRIVATE_KEYFILE: +#endif + { + convert_to_string_ex(zvalue); +#if LIBCURL_VERSION_NUM >= 0x071300 + if ( + option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE + + ) { + if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC)) { + RETVAL_FALSE; + return 1; + } + } +#endif + if (option == CURLOPT_URL) { + if (!php_curl_option_url(ch, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue) TSRMLS_CC)) { + RETVAL_FALSE; + return 1; + } + } else { + if (option == CURLOPT_PRIVATE) { + char *copystr; +#if LIBCURL_VERSION_NUM < 0x071100 +string_copy: +#endif + copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); + error = curl_easy_setopt(ch->cp, option, copystr); + zend_llist_add_element(&ch->to_free->str, ©str); + } else { +#if LIBCURL_VERSION_NUM >= 0x071100 + /* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ + error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue)); +#else + goto string_copy; +#endif + } + } + break; + } + case CURLOPT_FILE: + case CURLOPT_INFILE: + case CURLOPT_WRITEHEADER: + case CURLOPT_STDERR: { + FILE *fp = NULL; + int type; + void * what; + + what = zend_fetch_resource(zvalue TSRMLS_CC, -1, "File-Handle", &type, 1, php_file_le_stream(), php_file_le_pstream()); + if (!what) { + RETVAL_FALSE; + return 1; + } + + if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) { + RETVAL_FALSE; + return 1; + } + + if (!fp) { + RETVAL_FALSE; + return 1; + } + + error = CURLE_OK; + switch (option) { + case CURLOPT_FILE: + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (ch->handlers->write->stream) { + Z_DELREF_P(ch->handlers->write->stream); + } + Z_ADDREF_PP(zvalue); + ch->handlers->write->fp = fp; + ch->handlers->write->method = PHP_CURL_FILE; + ch->handlers->write->stream = *zvalue; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); + RETVAL_FALSE; + return 1; + } + break; + case CURLOPT_WRITEHEADER: + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (ch->handlers->write_header->stream) { + Z_DELREF_P(ch->handlers->write_header->stream); + } + Z_ADDREF_PP(zvalue); + ch->handlers->write_header->fp = fp; + ch->handlers->write_header->method = PHP_CURL_FILE; + ch->handlers->write_header->stream = *zvalue; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); + RETVAL_FALSE; + return 1; + } + break; + case CURLOPT_INFILE: + if (ch->handlers->read->stream) { + Z_DELREF_P(ch->handlers->read->stream); + } + Z_ADDREF_PP(zvalue); + ch->handlers->read->fp = fp; + ch->handlers->read->fd = Z_LVAL_PP(zvalue); + ch->handlers->read->stream = *zvalue; + break; + case CURLOPT_STDERR: + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + if (ch->handlers->std_err) { + zval_ptr_dtor(&ch->handlers->std_err); + } + zval_add_ref(zvalue); + ch->handlers->std_err = *zvalue; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); + RETVAL_FALSE; + return 1; + } + /* break omitted intentionally */ + default: + error = curl_easy_setopt(ch->cp, option, fp); + break; + } + + break; + } + case CURLOPT_RETURNTRANSFER: + convert_to_long_ex(zvalue); + + if (Z_LVAL_PP(zvalue)) { + ch->handlers->write->method = PHP_CURL_RETURN; + } else { + ch->handlers->write->method = PHP_CURL_STDOUT; + } + break; + case CURLOPT_BINARYTRANSFER: + convert_to_long_ex(zvalue); + + if (Z_LVAL_PP(zvalue)) { + ch->handlers->write->type = PHP_CURL_BINARY; + } else { + ch->handlers->write->type = PHP_CURL_ASCII; + } + break; + case CURLOPT_WRITEFUNCTION: + if (ch->handlers->write->func_name) { + zval_ptr_dtor(&ch->handlers->write->func_name); + ch->handlers->write->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->write->func_name = *zvalue; + ch->handlers->write->method = PHP_CURL_USER; + break; + case CURLOPT_READFUNCTION: + if (ch->handlers->read->func_name) { + zval_ptr_dtor(&ch->handlers->read->func_name); + ch->handlers->read->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->read->func_name = *zvalue; + ch->handlers->read->method = PHP_CURL_USER; + break; + case CURLOPT_PROGRESSFUNCTION: + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress); + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch); + if (ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + ch->handlers->progress->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->progress->func_name = *zvalue; + ch->handlers->progress->method = PHP_CURL_USER; + break; + case CURLOPT_HEADERFUNCTION: + if (ch->handlers->write_header->func_name) { + zval_ptr_dtor(&ch->handlers->write_header->func_name); + ch->handlers->write_header->fci_cache = empty_fcall_info_cache; + } + zval_add_ref(zvalue); + ch->handlers->write_header->func_name = *zvalue; + ch->handlers->write_header->method = PHP_CURL_USER; + break; +#if CURLOPT_PASSWDFUNCTION != 0 + case CURLOPT_PASSWDFUNCTION: + if (ch->handlers->passwd) { + zval_ptr_dtor(&ch->handlers->passwd); + } + zval_add_ref(zvalue); + ch->handlers->passwd = *zvalue; + error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd); + error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch); + break; +#endif + case CURLOPT_POSTFIELDS: + if (Z_TYPE_PP(zvalue) == IS_ARRAY || Z_TYPE_PP(zvalue) == IS_OBJECT) { + zval **current; + HashTable *postfields; + struct HttpPost *first = NULL; + struct HttpPost *last = NULL; + + postfields = HASH_OF(*zvalue); + if (!postfields) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS"); + RETVAL_FALSE; + return 1; + } + + for (zend_hash_internal_pointer_reset(postfields); + zend_hash_get_current_data(postfields, (void **) ¤t) == SUCCESS; + zend_hash_move_forward(postfields) + ) { + char *postval; + char *string_key = NULL; + uint string_key_len; + ulong num_key; + int numeric_key; + + SEPARATE_ZVAL(current); + convert_to_string_ex(current); + + zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL); + + /* Pretend we have a string_key here */ + if(!string_key) { + spprintf(&string_key, 0, "%ld", num_key); + string_key_len = strlen(string_key)+1; + numeric_key = 1; + } else { + numeric_key = 0; + } + + postval = Z_STRVAL_PP(current); + + /* The arguments after _NAMELENGTH and _CONTENTSLENGTH + * must be explicitly cast to long in curl_formadd + * use since curl needs a long not an int. */ + if (*postval == '@') { + char *type, *filename; + ++postval; + + if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + Z_STRLEN_PP(current)))) { + *type = '\0'; + } + if ((filename = php_memnstr(postval, ";filename=", sizeof(";filename=") - 1, postval + Z_STRLEN_PP(current)))) { + *filename = '\0'; + } + /* open_basedir check */ + if (php_check_open_basedir(postval TSRMLS_CC)) { + RETVAL_FALSE; + return 1; + } + error = curl_formadd(&first, &last, + CURLFORM_COPYNAME, string_key, + CURLFORM_NAMELENGTH, (long)string_key_len - 1, + CURLFORM_FILENAME, filename ? filename + sizeof(";filename=") - 1 : postval, + CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream", + CURLFORM_FILE, postval, + CURLFORM_END); + if (type) { + *type = ';'; + } + if (filename) { + *filename = ';'; + } + } else { + error = curl_formadd(&first, &last, + CURLFORM_COPYNAME, string_key, + CURLFORM_NAMELENGTH, (long)string_key_len - 1, + CURLFORM_COPYCONTENTS, postval, + CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(current), + CURLFORM_END); + } + + if (numeric_key) { + efree(string_key); + } + } + + SAVE_CURL_ERROR(ch, error); + if (error != CURLE_OK) { + RETVAL_FALSE; + return 1; + } + + if (Z_REFCOUNT_P(ch->clone) <= 1) { + zend_llist_clean(&ch->to_free->post); + } + zend_llist_add_element(&ch->to_free->post, &first); + error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first); + + } else { +#if LIBCURL_VERSION_NUM >= 0x071101 + convert_to_string_ex(zvalue); + /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */ + error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue)); + error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, Z_STRVAL_PP(zvalue)); +#else + char *post = NULL; + + convert_to_string_ex(zvalue); + post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); + zend_llist_add_element(&ch->to_free->str, &post); + + error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post); + error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue)); +#endif + } + break; + case CURLOPT_HTTPHEADER: + case CURLOPT_QUOTE: + case CURLOPT_HTTP200ALIASES: + case CURLOPT_POSTQUOTE: { + zval **current; + HashTable *ph; + struct curl_slist *slist = NULL; + + ph = HASH_OF(*zvalue); + if (!ph) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments"); + RETVAL_FALSE; + return 1; + } + + for (zend_hash_internal_pointer_reset(ph); + zend_hash_get_current_data(ph, (void **) ¤t) == SUCCESS; + zend_hash_move_forward(ph) + ) { + SEPARATE_ZVAL(current); + convert_to_string_ex(current); + + slist = curl_slist_append(slist, Z_STRVAL_PP(current)); + if (!slist) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not build curl_slist"); + RETVAL_FALSE; + return 1; + } + } + zend_llist_add_element(&ch->to_free->slist, &slist); + + error = curl_easy_setopt(ch->cp, option, slist); + + break; + } + /* the following options deal with files, therefore the open_basedir check + * is required. + */ + case CURLOPT_COOKIEJAR: + case CURLOPT_SSLCERT: + case CURLOPT_RANDOM_FILE: + case CURLOPT_COOKIEFILE: { +#if LIBCURL_VERSION_NUM < 0x071100 + char *copystr = NULL; +#endif + + convert_to_string_ex(zvalue); + + if (Z_STRLEN_PP(zvalue) && php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC)) { + RETVAL_FALSE; + return 1; + } + +#if LIBCURL_VERSION_NUM >= 0x071100 + error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue)); +#else + copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue)); + + error = curl_easy_setopt(ch->cp, option, copystr); + zend_llist_add_element(&ch->to_free->str, ©str); +#endif + break; + } + case CURLINFO_HEADER_OUT: + convert_to_long_ex(zvalue); + if (Z_LVAL_PP(zvalue) == 1) { + curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug); + curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch); + curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1); + } else { + curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL); + curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL); + curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); + } + break; + } + + SAVE_CURL_ERROR(ch, error); + if (error != CURLE_OK) { + return 1; + } else { + return 0; + } +} +/* }}} */ + +/* {{{ proto bool curl_setopt(resource ch, int option, mixed value) + Set an option for a cURL transfer */ +PHP_FUNCTION(curl_setopt) +{ + zval *zid, **zvalue; + long options; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &zid, &options, &zvalue) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + if (options <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl configuration option"); + RETURN_FALSE; + } + + if (!_php_curl_setopt(ch, options, zvalue, return_value TSRMLS_CC)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto bool curl_setopt_array(resource ch, array options) + Set an array of option for a cURL transfer */ +PHP_FUNCTION(curl_setopt_array) +{ + zval *zid, *arr, **entry; + php_curl *ch; + ulong option; + HashPosition pos; + char *string_key; + uint str_key_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &zid, &arr) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) { + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &string_key, &str_key_len, &option, 0, &pos) != HASH_KEY_IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array keys must be CURLOPT constants or equivalent integer values"); + RETURN_FALSE; + } + if (_php_curl_setopt(ch, (long) option, entry, return_value TSRMLS_CC)) { + RETURN_FALSE; + } + zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ _php_curl_cleanup_handle(ch) + Cleanup an execution phase */ +void _php_curl_cleanup_handle(php_curl *ch) +{ + if (ch->handlers->write->buf.len > 0) { + smart_str_free(&ch->handlers->write->buf); + } + if (ch->header.str_len) { + efree(ch->header.str); + ch->header.str_len = 0; + } + + memset(ch->err.str, 0, CURL_ERROR_SIZE + 1); + ch->err.no = 0; +} +/* }}} */ + +/* {{{ proto bool curl_exec(resource ch) + Perform a cURL session */ +PHP_FUNCTION(curl_exec) +{ + CURLcode error; + zval *zid; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); + + _php_curl_cleanup_handle(ch); + + error = curl_easy_perform(ch->cp); + SAVE_CURL_ERROR(ch, error); + /* CURLE_PARTIAL_FILE is returned by HEAD requests */ + if (error != CURLE_OK && error != CURLE_PARTIAL_FILE) { + if (ch->handlers->write->buf.len > 0) { + smart_str_free(&ch->handlers->write->buf); + } + RETURN_FALSE; + } + + if (ch->handlers->std_err) { + php_stream *stream; + stream = (php_stream*)zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream()); + if (stream) { + php_stream_flush(stream); + } + } + + if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) { + smart_str_0(&ch->handlers->write->buf); + RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 1); + } + + /* flush the file handle, so any remaining data is synched to disk */ + if (ch->handlers->write->method == PHP_CURL_FILE && ch->handlers->write->fp) { + fflush(ch->handlers->write->fp); + } + if (ch->handlers->write_header->method == PHP_CURL_FILE && ch->handlers->write_header->fp) { + fflush(ch->handlers->write_header->fp); + } + + if (ch->handlers->write->method == PHP_CURL_RETURN) { + RETURN_EMPTY_STRING(); + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ proto mixed curl_getinfo(resource ch [, int option]) + Get information regarding a specific transfer */ +PHP_FUNCTION(curl_getinfo) +{ + zval *zid; + php_curl *ch; + long option = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zid, &option) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + if (ZEND_NUM_ARGS() < 2) { + char *s_code; + long l_code; + double d_code; +#if LIBCURL_VERSION_NUM > 0x071301 + struct curl_certinfo *ci = NULL; + zval *listcode; +#endif + + array_init(return_value); + + if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &s_code) == CURLE_OK) { + CAAS("url", s_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_TYPE, &s_code) == CURLE_OK) { + if (s_code != NULL) { + CAAS("content_type", s_code); + } else { + zval *retnull; + MAKE_STD_ZVAL(retnull); + ZVAL_NULL(retnull); + CAAZ("content_type", retnull); + } + } + if (curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code) == CURLE_OK) { + CAAL("http_code", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code) == CURLE_OK) { + CAAL("header_size", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code) == CURLE_OK) { + CAAL("request_size", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code) == CURLE_OK) { + CAAL("filetime", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_SSL_VERIFYRESULT, &l_code) == CURLE_OK) { + CAAL("ssl_verify_result", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_COUNT, &l_code) == CURLE_OK) { + CAAL("redirect_count", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code) == CURLE_OK) { + CAAD("total_time", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code) == CURLE_OK) { + CAAD("namelookup_time", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code) == CURLE_OK) { + CAAD("connect_time", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code) == CURLE_OK) { + CAAD("pretransfer_time", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code) == CURLE_OK) { + CAAD("size_upload", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) { + CAAD("size_download", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) { + CAAD("speed_download", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code) == CURLE_OK) { + CAAD("speed_upload", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_code) == CURLE_OK) { + CAAD("download_content_length", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD, &d_code) == CURLE_OK) { + CAAD("upload_content_length", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME, &d_code) == CURLE_OK) { + CAAD("starttransfer_time", d_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) { + CAAD("redirect_time", d_code); + } +#if LIBCURL_VERSION_NUM > 0x071301 + if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) { + MAKE_STD_ZVAL(listcode); + array_init(listcode); + create_certinfo(ci, listcode TSRMLS_CC); + CAAZ("certinfo", listcode); + } +#endif +#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */ + if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) { + CAAS("primary_ip", s_code); + } +#endif +#if LIBCURL_VERSION_NUM > 0x071500 + if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_PORT, &l_code) == CURLE_OK) { + CAAL("primary_port", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_IP, &s_code) == CURLE_OK) { + CAAS("local_ip", s_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_LOCAL_PORT, &l_code) == CURLE_OK) { + CAAL("local_port", l_code); + } +#endif +#if LIBCURL_VERSION_NUM >= 0x071202 + if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) { + CAAS("redirect_url", s_code); + } +#endif + if (ch->header.str_len > 0) { + CAAS("request_header", ch->header.str); + } + } else { + switch (option) { + /* string variable types */ +#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */ + case CURLINFO_PRIMARY_IP: +#endif +#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */ + case CURLINFO_LOCAL_IP: +#endif + case CURLINFO_PRIVATE: + case CURLINFO_EFFECTIVE_URL: + case CURLINFO_CONTENT_TYPE: +#if LIBCURL_VERSION_NUM >= 0x071202 + case CURLINFO_REDIRECT_URL: +#endif + { + char *s_code = NULL; + + if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) { + RETURN_STRING(s_code, 1); + } else { + RETURN_FALSE; + } + break; + } + /* Long variable types */ +#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */ + case CURLINFO_PRIMARY_PORT: + case CURLINFO_LOCAL_PORT: +#endif + case CURLINFO_HTTP_CODE: + case CURLINFO_HEADER_SIZE: + case CURLINFO_REQUEST_SIZE: + case CURLINFO_FILETIME: + case CURLINFO_SSL_VERIFYRESULT: + case CURLINFO_REDIRECT_COUNT: { + long code = 0; + + if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) { + RETURN_LONG(code); + } else { + RETURN_FALSE; + } + break; + } + /* Double variable types */ + case CURLINFO_TOTAL_TIME: + case CURLINFO_NAMELOOKUP_TIME: + case CURLINFO_CONNECT_TIME: + case CURLINFO_PRETRANSFER_TIME: + case CURLINFO_SIZE_UPLOAD: + case CURLINFO_SIZE_DOWNLOAD: + case CURLINFO_SPEED_DOWNLOAD: + case CURLINFO_SPEED_UPLOAD: + case CURLINFO_CONTENT_LENGTH_DOWNLOAD: + case CURLINFO_CONTENT_LENGTH_UPLOAD: + case CURLINFO_STARTTRANSFER_TIME: + case CURLINFO_REDIRECT_TIME: { + double code = 0.0; + + if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) { + RETURN_DOUBLE(code); + } else { + RETURN_FALSE; + } + break; + } + case CURLINFO_HEADER_OUT: + if (ch->header.str_len > 0) { + RETURN_STRINGL(ch->header.str, ch->header.str_len, 1); + } else { + RETURN_FALSE; + } +#if LIBCURL_VERSION_NUM > 0x071301 + case CURLINFO_CERTINFO: { + struct curl_certinfo *ci = NULL; + + array_init(return_value); + + if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) { + create_certinfo(ci, return_value TSRMLS_CC); + } else { + RETURN_FALSE; + } + break; + } +#endif + } + } +} +/* }}} */ + +/* {{{ proto string curl_error(resource ch) + Return a string contain the last error for the current session */ +PHP_FUNCTION(curl_error) +{ + zval *zid; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + ch->err.str[CURL_ERROR_SIZE] = 0; + RETURN_STRING(ch->err.str, 1); +} +/* }}} */ + +/* {{{ proto int curl_errno(resource ch) + Return an integer containing the last error number */ +PHP_FUNCTION(curl_errno) +{ + zval *zid; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + RETURN_LONG(ch->err.no); +} +/* }}} */ + +/* {{{ proto void curl_close(resource ch) + Close a cURL session */ +PHP_FUNCTION(curl_close) +{ + zval *zid; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl); + + if (ch->in_callback) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to close cURL handle from a callback"); + return; + } + + if (ch->uses) { + ch->uses--; + } else { + zend_list_delete(Z_LVAL_P(zid)); + } +} +/* }}} */ + +/* {{{ _php_curl_close() + List destructor for curl handles */ +static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) +{ +#if PHP_CURL_DEBUG + fprintf(stderr, "DTOR CALLED, ch = %x\n", ch); +#endif + + _php_curl_verify_handlers(ch, 0 TSRMLS_CC); + + /* + * Libcurl is doing connection caching. When easy handle is cleaned up, + * if the handle was previously used by the curl_multi_api, the connection + * remains open un the curl multi handle is cleaned up. Some protocols are + * sending content like the FTP one, and libcurl try to use the + * WRITEFUNCTION or the HEADERFUNCTION. Since structures used in those + * callback are freed, we need to use an other callback to which avoid + * segfaults. + * + * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2 + */ + curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing); + curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing); + + curl_easy_cleanup(ch->cp); + + /* cURL destructors should be invoked only by last curl handle */ + if (Z_REFCOUNT_P(ch->clone) <= 1) { + zend_llist_clean(&ch->to_free->str); + zend_llist_clean(&ch->to_free->slist); + zend_llist_clean(&ch->to_free->post); + efree(ch->to_free); + FREE_ZVAL(ch->clone); + } else { + Z_DELREF_P(ch->clone); + } + + if (ch->handlers->write->buf.len > 0) { + smart_str_free(&ch->handlers->write->buf); + } + if (ch->handlers->write->func_name) { + zval_ptr_dtor(&ch->handlers->write->func_name); + } + if (ch->handlers->read->func_name) { + zval_ptr_dtor(&ch->handlers->read->func_name); + } + if (ch->handlers->write_header->func_name) { + zval_ptr_dtor(&ch->handlers->write_header->func_name); + } + if (ch->handlers->progress->func_name) { + zval_ptr_dtor(&ch->handlers->progress->func_name); + } + if (ch->handlers->passwd) { + zval_ptr_dtor(&ch->handlers->passwd); + } + if (ch->handlers->std_err) { + zval_ptr_dtor(&ch->handlers->std_err); + } + if (ch->header.str_len > 0) { + efree(ch->header.str); + } + + if (ch->handlers->write_header->stream) { + zval_ptr_dtor(&ch->handlers->write_header->stream); + } + if (ch->handlers->write->stream) { + zval_ptr_dtor(&ch->handlers->write->stream); + } + if (ch->handlers->read->stream) { + zval_ptr_dtor(&ch->handlers->read->stream); + } + + efree(ch->handlers->write); + efree(ch->handlers->write_header); + efree(ch->handlers->read); + efree(ch->handlers->progress); + efree(ch->handlers); + efree(ch); +} +/* }}} */ + +/* {{{ _php_curl_close() + List destructor for curl handles */ +static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_curl *ch = (php_curl *) rsrc->ptr; + _php_curl_close_ex(ch TSRMLS_CC); +} +/* }}} */ + +#endif /* HAVE_CURL */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: fdm=marker + * vim: noet sw=4 ts=4 + */ diff --git a/ext/curl/multi.c b/ext/curl/multi.c new file mode 100644 index 0000000..38c1f1a --- /dev/null +++ b/ext/curl/multi.c @@ -0,0 +1,371 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes <sterling@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_CURL + +#include "php_curl.h" + +#include <curl/curl.h> +#include <curl/multi.h> + +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +/* {{{ proto resource curl_multi_init(void) + Returns a new cURL multi handle */ +PHP_FUNCTION(curl_multi_init) +{ + php_curlm *mh; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + mh = ecalloc(1, sizeof(php_curlm)); + mh->multi = curl_multi_init(); + + zend_llist_init(&mh->easyh, sizeof(zval), _php_curl_multi_cleanup_list, 0); + + ZEND_REGISTER_RESOURCE(return_value, mh, le_curl_multi_handle); +} +/* }}} */ + +/* {{{ proto int curl_multi_add_handle(resource mh, resource ch) + Add a normal cURL handle to a cURL multi handle */ +PHP_FUNCTION(curl_multi_add_handle) +{ + zval *z_mh; + zval *z_ch; + php_curlm *mh; + php_curl *ch; + zval tmp_val; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &z_mh, &z_ch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + ZEND_FETCH_RESOURCE(ch, php_curl *, &z_ch, -1, le_curl_name, le_curl); + + _php_curl_cleanup_handle(ch); + ch->uses++; + + /* we want to create a copy of this zval that we store in the multihandle structure element "easyh" */ + tmp_val = *z_ch; + zval_copy_ctor(&tmp_val); + + zend_llist_add_element(&mh->easyh, &tmp_val); + + RETURN_LONG((long) curl_multi_add_handle(mh->multi, ch->cp)); +} +/* }}} */ + +void _php_curl_multi_cleanup_list(void *data) /* {{{ */ +{ + zval *z_ch = (zval *)data; + php_curl *ch; + TSRMLS_FETCH(); + + if (!z_ch) { + return; + } + + ch = (php_curl *) zend_fetch_resource(&z_ch TSRMLS_CC, -1, le_curl_name, NULL, 1, le_curl); + if (!ch) { + return; + } + + if (ch->uses) { + ch->uses--; + } else { + zend_list_delete(Z_LVAL_P(z_ch)); + } +} +/* }}} */ + +/* Used internally as comparison routine passed to zend_list_del_element */ +static int curl_compare_resources( zval *z1, zval **z2 ) /* {{{ */ +{ + return (Z_TYPE_P( z1 ) == Z_TYPE_PP( z2 ) && + Z_TYPE_P( z1 ) == IS_RESOURCE && + Z_LVAL_P( z1 ) == Z_LVAL_PP( z2 ) ); +} +/* }}} */ + +/* {{{ proto int curl_multi_remove_handle(resource mh, resource ch) + Remove a multi handle from a set of cURL handles */ +PHP_FUNCTION(curl_multi_remove_handle) +{ + zval *z_mh; + zval *z_ch; + php_curlm *mh; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &z_mh, &z_ch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + ZEND_FETCH_RESOURCE(ch, php_curl *, &z_ch, -1, le_curl_name, le_curl); + + --ch->uses; + + zend_llist_del_element( &mh->easyh, &z_ch, + (int (*)(void *, void *)) curl_compare_resources ); + + RETURN_LONG((long) curl_multi_remove_handle(mh->multi, ch->cp)); +} +/* }}} */ + +static void _make_timeval_struct(struct timeval *to, double timeout) /* {{{ */ +{ + unsigned long conv; + + conv = (unsigned long) (timeout * 1000000.0); + to->tv_sec = conv / 1000000; + to->tv_usec = conv % 1000000; +} +/* }}} */ + +/* {{{ proto int curl_multi_select(resource mh[, double timeout]) + Get all the sockets associated with the cURL extension, which can then be "selected" */ +PHP_FUNCTION(curl_multi_select) +{ + zval *z_mh; + php_curlm *mh; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + int maxfd; + double timeout = 1.0; + struct timeval to; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|d", &z_mh, &timeout) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + + _make_timeval_struct(&to, timeout); + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + + curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd); + if (maxfd == -1) { + RETURN_LONG(-1); + } + RETURN_LONG(select(maxfd + 1, &readfds, &writefds, &exceptfds, &to)); +} +/* }}} */ + +/* {{{ proto int curl_multi_exec(resource mh, int &still_running) + Run the sub-connections of the current cURL handle */ +PHP_FUNCTION(curl_multi_exec) +{ + zval *z_mh; + zval *z_still_running; + php_curlm *mh; + int still_running; + int result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_mh, &z_still_running) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + + { + zend_llist_position pos; + php_curl *ch; + zval *pz_ch; + + for(pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch; + pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) { + + ZEND_FETCH_RESOURCE(ch, php_curl *, &pz_ch, -1, le_curl_name, le_curl); + _php_curl_verify_handlers(ch, 1 TSRMLS_CC); + } + } + + convert_to_long_ex(&z_still_running); + still_running = Z_LVAL_P(z_still_running); + result = curl_multi_perform(mh->multi, &still_running); + ZVAL_LONG(z_still_running, still_running); + + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string curl_multi_getcontent(resource ch) + Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set */ +PHP_FUNCTION(curl_multi_getcontent) +{ + zval *z_ch; + php_curl *ch; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(ch, php_curl *, &z_ch, -1, le_curl_name, le_curl); + + if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) { + smart_str_0(&ch->handlers->write->buf); + RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 1); + } +} +/* }}} */ + +/* {{{ proto array curl_multi_info_read(resource mh [, long msgs_in_queue]) + Get information about the current transfers */ +PHP_FUNCTION(curl_multi_info_read) +{ + zval *z_mh; + php_curlm *mh; + CURLMsg *tmp_msg; + int queued_msgs; + zval *zmsgs_in_queue = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z", &z_mh, &zmsgs_in_queue) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + + tmp_msg = curl_multi_info_read(mh->multi, &queued_msgs); + if (tmp_msg == NULL) { + RETURN_FALSE; + } + if (zmsgs_in_queue) { + zval_dtor(zmsgs_in_queue); + ZVAL_LONG(zmsgs_in_queue, queued_msgs); + } + + array_init(return_value); + add_assoc_long(return_value, "msg", tmp_msg->msg); + add_assoc_long(return_value, "result", tmp_msg->data.result); + + /* find the original easy curl handle */ + { + zend_llist_position pos; + php_curl *ch; + zval *pz_ch; + + /* search the list of easy handles hanging off the multi-handle */ + for(pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch; + pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) { + ZEND_FETCH_RESOURCE(ch, php_curl *, &pz_ch, -1, le_curl_name, le_curl); + if (ch->cp == tmp_msg->easy_handle) { + + /* we are adding a reference to the underlying php_curl + resource, so we need to add one to the resource's refcount + in order to ensure it doesn't get destroyed when the + underlying curl easy handle goes out of scope. + Normally you would call zval_copy_ctor( pz_ch ), or + SEPARATE_ZVAL, but those create new zvals, which is already + being done in add_assoc_resource */ + + zend_list_addref( Z_RESVAL_P( pz_ch ) ); + + /* add_assoc_resource automatically creates a new zval to + wrap the "resource" represented by the current pz_ch */ + + add_assoc_resource(return_value, "handle", Z_RESVAL_P(pz_ch)); + + break; + } + } + } +} +/* }}} */ + +/* {{{ proto void curl_multi_close(resource mh) + Close a set of cURL handles */ +PHP_FUNCTION(curl_multi_close) +{ + zval *z_mh; + php_curlm *mh; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_mh) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle); + + zend_list_delete(Z_LVAL_P(z_mh)); +} +/* }}} */ + +void _php_curl_multi_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +{ + php_curlm *mh = (php_curlm *) rsrc->ptr; + if (mh) { + zend_llist_position pos; + php_curl *ch; + zval *pz_ch; + + for(pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch; + pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) { + + ch = (php_curl *) zend_fetch_resource(&pz_ch TSRMLS_CC, -1, le_curl_name, NULL, 1, le_curl); + _php_curl_verify_handlers(ch, 0 TSRMLS_CC); + } + + curl_multi_cleanup(mh->multi); + zend_llist_clean(&mh->easyh); + efree(mh); + rsrc->ptr = NULL; + } +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/curl/package.xml b/ext/curl/package.xml new file mode 100644 index 0000000..85cb634 --- /dev/null +++ b/ext/curl/package.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!DOCTYPE package SYSTEM "../pear/package.dtd"> +<package> + <name>curl</name> + <summary>Clib PDF functions</summary> + <maintainers> + <maintainer> + <user>sterling</user> + <name>Sterling Hughes</name> + <email>sterling@php.net</email> + <role>lead</role> + </maintainer> + </maintainers> + <description> +PHP supports libcurl, a library created by Daniel Stenberg, +that allows you to connect and communicate to many different +types of servers with many different types of protocols. +libcurl currently supports the http, https, ftp, gopher, +telnet, dict, file, and ldap protocols. libcurl also supports +HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading (this +can also be done with PHP's ftp extension), HTTP form based +upload, proxies, cookies, and user+password authentication. + </description> + <license>PHP</license> + <release> + <state>beta</state> + <version>5.0rc1</version> + <date>2004-03-19</date> + <notes> +package.xml added to support installation using pear installer + </notes> + <configureoptions> + <configureoption name="with-curl" default="autodetect" prompt="path to curl installation?"/> + </configureoptions> + <filelist> + <file role="doc" name="CREDITS"/> + <file role="src" name="config.m4"/> + <file role="src" name="config.mw32"/> + <file role="src" name="curl.dsp"/> + <file role="src" name="interface.c"/> + <file role="src" name="multi.c"/> + <file role="src" name="streams.c"/> + <file role="src" name="php_curl.h"/> + </filelist> + <deps> + <dep type="php" rel="ge" version="5" /> + </deps> + </release> +</package> +<!-- +vim:et:ts=1:sw=1 +--> diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h new file mode 100644 index 0000000..945f0a4 --- /dev/null +++ b/ext/curl/php_curl.h @@ -0,0 +1,192 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes <sterling@php.net> | + | Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef _PHP_CURL_H +#define _PHP_CURL_H + +#include "php.h" +#include "ext/standard/php_smart_str.h" + +#ifdef COMPILE_DL_CURL +#undef HAVE_CURL +#define HAVE_CURL 1 +#endif + +#if HAVE_CURL + +#define PHP_CURL_DEBUG 0 + +#include <curl/curl.h> +#include <curl/multi.h> + +extern zend_module_entry curl_module_entry; +#define curl_module_ptr &curl_module_entry + +#define CURLOPT_RETURNTRANSFER 19913 +#define CURLOPT_BINARYTRANSFER 19914 +#define PHP_CURL_STDOUT 0 +#define PHP_CURL_FILE 1 +#define PHP_CURL_USER 2 +#define PHP_CURL_DIRECT 3 +#define PHP_CURL_RETURN 4 +#define PHP_CURL_ASCII 5 +#define PHP_CURL_BINARY 6 +#define PHP_CURL_IGNORE 7 + +extern int le_curl; +#define le_curl_name "cURL handle" +extern int le_curl_multi_handle; +#define le_curl_multi_handle_name "cURL Multi Handle" + +PHP_MINIT_FUNCTION(curl); +PHP_MSHUTDOWN_FUNCTION(curl); +PHP_MINFO_FUNCTION(curl); +PHP_FUNCTION(curl_version); +PHP_FUNCTION(curl_init); +PHP_FUNCTION(curl_copy_handle); +PHP_FUNCTION(curl_setopt); +PHP_FUNCTION(curl_setopt_array); +PHP_FUNCTION(curl_exec); +PHP_FUNCTION(curl_getinfo); +PHP_FUNCTION(curl_error); +PHP_FUNCTION(curl_errno); +PHP_FUNCTION(curl_close); +PHP_FUNCTION(curl_multi_init); +PHP_FUNCTION(curl_multi_add_handle); +PHP_FUNCTION(curl_multi_remove_handle); +PHP_FUNCTION(curl_multi_select); +PHP_FUNCTION(curl_multi_exec); +PHP_FUNCTION(curl_multi_getcontent); +PHP_FUNCTION(curl_multi_info_read); +PHP_FUNCTION(curl_multi_close); +void _php_curl_multi_close(zend_rsrc_list_entry * TSRMLS_DC); + +typedef struct { + zval *func_name; + zend_fcall_info_cache fci_cache; + FILE *fp; + smart_str buf; + int method; + int type; + zval *stream; +} php_curl_write; + +typedef struct { + zval *func_name; + zend_fcall_info_cache fci_cache; + FILE *fp; + long fd; + int method; + zval *stream; +} php_curl_read; + +typedef struct { + zval *func_name; + zend_fcall_info_cache fci_cache; + int method; +} php_curl_progress; + +typedef struct { + php_curl_write *write; + php_curl_write *write_header; + php_curl_read *read; + zval *passwd; + zval *std_err; + php_curl_progress *progress; +} php_curl_handlers; + +struct _php_curl_error { + char str[CURL_ERROR_SIZE + 1]; + int no; +}; + +struct _php_curl_send_headers { + char *str; + size_t str_len; +}; + +struct _php_curl_free { + zend_llist str; + zend_llist post; + zend_llist slist; +}; + +typedef struct { + struct _php_curl_error err; + struct _php_curl_free *to_free; + struct _php_curl_send_headers header; + void ***thread_ctx; + CURL *cp; + php_curl_handlers *handlers; + long id; + unsigned int uses; + zend_bool in_callback; + zval *clone; +} php_curl; + +typedef struct { + int still_running; + CURLM *multi; + zend_llist easyh; +} php_curlm; + +void _php_curl_cleanup_handle(php_curl *); +void _php_curl_multi_cleanup_list(void *data); +int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC); + +/* streams support */ + +extern php_stream_ops php_curl_stream_ops; +#define PHP_STREAM_IS_CURL &php_curl_stream_ops + +php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); + +extern php_stream_wrapper php_curl_wrapper; + +struct php_curl_buffer { + off_t readpos, writepos; + php_stream *buf; +}; + +typedef struct { + CURL *curl; + CURLM *multi; + char *url; + struct php_curl_buffer readbuffer; /* holds downloaded data */ + struct php_curl_buffer writebuffer; /* holds data to upload */ + + fd_set readfds, writefds, excfds; + int maxfd; + + char errstr[CURL_ERROR_SIZE + 1]; + CURLMcode mcode; + int pending; + zval *headers; + struct curl_slist *headers_slist; /* holds custom headers sent out in the request */ +} php_curl_stream; + + +#else +#define curl_module_ptr NULL +#endif /* HAVE_CURL */ +#define phpext_curl_ptr curl_module_ptr +#endif /* _PHP_CURL_H */ diff --git a/ext/curl/streams.c b/ext/curl/streams.c new file mode 100644 index 0000000..2683ae0 --- /dev/null +++ b/ext/curl/streams.c @@ -0,0 +1,542 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +/* This file implements cURL based wrappers. + * NOTE: If you are implementing your own streams that are intended to + * work independently of wrappers, this is not a good example to follow! + **/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_memory_streams.h" + +#if HAVE_CURL + +#include <stdio.h> +#include <string.h> + +#ifdef PHP_WIN32 +#include <winsock2.h> +#include <sys/types.h> +#endif + +#include <curl/curl.h> +#include <curl/easy.h> + +#define SMART_STR_PREALLOC 4096 + +#include "ext/standard/php_smart_str.h" +#include "ext/standard/info.h" +#include "ext/standard/file.h" +#include "ext/standard/php_string.h" +#include "php_curl.h" + +static size_t on_data_available(char *data, size_t size, size_t nmemb, void *ctx) +{ + php_stream *stream = (php_stream *) ctx; + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + size_t wrote; + TSRMLS_FETCH(); + + /* TODO: I'd like to deprecate this. + * This code is here because until we start getting real data, we don't know + * if we have had all of the headers + * */ + if (curlstream->readbuffer.writepos == 0) { + zval *sym; + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + } + MAKE_STD_ZVAL(sym); + *sym = *curlstream->headers; + zval_copy_ctor(sym); + ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", sym); + } + + php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.writepos, SEEK_SET); + wrote = php_stream_write(curlstream->readbuffer.buf, data, size * nmemb); + curlstream->readbuffer.writepos = php_stream_tell(curlstream->readbuffer.buf); + + return wrote; +} + +/* cURL guarantees that headers are written as complete lines, with this function + * called once for each header */ +static size_t on_header_available(char *data, size_t size, size_t nmemb, void *ctx) +{ + size_t length = size * nmemb; + zval *header; + php_stream *stream = (php_stream *) ctx; + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + TSRMLS_FETCH(); + + if (length < 2) { + /* invalid header ? */ + return length; + } + + if (!(length == 2 && data[0] == '\r' && data[1] == '\n')) { + MAKE_STD_ZVAL(header); + Z_STRLEN_P(header) = length; + Z_STRVAL_P(header) = estrndup(data, length); + if (Z_STRVAL_P(header)[length-1] == '\n') { + Z_STRVAL_P(header)[length-1] = '\0'; + Z_STRLEN_P(header)--; + + if (Z_STRVAL_P(header)[length-2] == '\r') { + Z_STRVAL_P(header)[length-2] = '\0'; + Z_STRLEN_P(header)--; + } + } + Z_TYPE_P(header) = IS_STRING; + zend_hash_next_index_insert(Z_ARRVAL_P(curlstream->headers), &header, sizeof(zval *), NULL); + + /* based on the header, we might need to trigger a notification */ + if (!strncasecmp(data, "Location: ", 10)) { + php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_REDIRECTED, data + 10, 0); + } else if (!strncasecmp(data, "Content-Type: ", 14)) { + php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, data + 14, 0); + } else if (!strncasecmp(data, "Context-Length: ", 16)) { + php_stream_notify_file_size(stream->context, atoi(data + 16), data, 0); + php_stream_notify_progress_init(stream->context, 0, 0); + } + } + return length; + +} + +static int on_progress_avail(php_stream *stream, double dltotal, double dlnow, double ultotal, double ulnow) +{ + TSRMLS_FETCH(); + + /* our notification system only works in a single direction; we should detect which + * direction is important and use the correct values in this call */ + php_stream_notify_progress(stream->context, (size_t) dlnow, (size_t) dltotal); + return 0; +} + +static size_t php_curl_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +{ + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + + if (curlstream->writebuffer.buf) { + return php_stream_write(curlstream->writebuffer.buf, buf, count); + } + + return 0; +} + +static size_t php_curl_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +{ + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + size_t didread = 0; + + if (curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending) { + /* we need to read some more data */ + struct timeval tv; + + /* fire up the connection */ + if (curlstream->readbuffer.writepos == 0) { + while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlstream->multi, &curlstream->pending)); + } + + do { + FD_ZERO(&curlstream->readfds); + FD_ZERO(&curlstream->writefds); + FD_ZERO(&curlstream->excfds); + + /* get the descriptors from curl */ + curl_multi_fdset(curlstream->multi, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &curlstream->maxfd); + + /* if we are in blocking mode, set a timeout */ + tv.tv_usec = 0; + tv.tv_sec = 15; /* TODO: allow this to be configured from the script */ + + /* wait for data */ + switch ((curlstream->maxfd < 0) ? 1 : + select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) { + case -1: + /* error */ + return 0; + case 0: + /* no data yet: timed-out */ + return 0; + default: + /* fetch the data */ + do { + curlstream->mcode = curl_multi_perform(curlstream->multi, &curlstream->pending); + } while (curlstream->mcode == CURLM_CALL_MULTI_PERFORM); + } + } while (curlstream->maxfd >= 0 && + curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0); + + } + + /* if there is data in the buffer, try and read it */ + if (curlstream->readbuffer.writepos > 0 && curlstream->readbuffer.readpos < curlstream->readbuffer.writepos) { + php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.readpos, SEEK_SET); + didread = php_stream_read(curlstream->readbuffer.buf, buf, count); + curlstream->readbuffer.readpos = php_stream_tell(curlstream->readbuffer.buf); + } + + if (didread == 0) { + stream->eof = 1; + } + + return didread; +} + +static int php_curl_stream_close(php_stream *stream, int close_handle TSRMLS_DC) +{ + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + + /* TODO: respect the close_handle flag here, so that casting to a FILE* on + * systems without fopencookie will work properly */ + + curl_multi_remove_handle(curlstream->multi, curlstream->curl); + curl_easy_cleanup(curlstream->curl); + curl_multi_cleanup(curlstream->multi); + + if (curlstream->headers_slist) { + curl_slist_free_all(curlstream->headers_slist); + } + + /* we are not closing curlstream->readbuf here, because we export + * it as a zval with the wrapperdata - the engine will garbage collect it */ + + efree(curlstream->url); + efree(curlstream); + + return 0; +} + +static int php_curl_stream_flush(php_stream *stream TSRMLS_DC) +{ +#ifdef ilia_0 + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; +#endif + return 0; +} + +static int php_curl_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + /* TODO: fill in details based on Data: and Content-Length: headers, and/or data + * from curl_easy_getinfo(). + * For now, return -1 to indicate that it doesn't make sense to stat this stream */ + return -1; +} + +static int php_curl_stream_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) +{ + php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; + /* delegate to the readbuffer stream */ + return php_stream_cast(curlstream->readbuffer.buf, castas, ret, 0); +} + +php_stream_ops php_curl_stream_ops = { + php_curl_stream_write, + php_curl_stream_read, + php_curl_stream_close, + php_curl_stream_flush, + "cURL", + NULL, /* seek */ + php_curl_stream_cast, /* cast */ + php_curl_stream_stat /* stat */ +}; + + +php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + php_stream *stream; + php_curl_stream *curlstream; + zval *tmp, **ctx_opt = NULL; + + curlstream = emalloc(sizeof(php_curl_stream)); + memset(curlstream, 0, sizeof(php_curl_stream)); + + stream = php_stream_alloc(&php_curl_stream_ops, curlstream, 0, mode); + php_stream_context_set(stream, context); + + curlstream->curl = curl_easy_init(); + curlstream->multi = curl_multi_init(); + curlstream->pending = 1; + curlstream->headers_slist = NULL; + + /* if opening for an include statement, ensure that the local storage will + * have a FILE* associated with it. + * Otherwise, use the "smart" memory stream that will turn itself into a file + * when it gets large */ +#ifndef HAVE_FOPENCOOKIE + if (options & STREAM_WILL_CAST) { + curlstream->readbuffer.buf = php_stream_fopen_tmpfile(); + } else +#endif + { + curlstream->readbuffer.buf = php_stream_temp_new(); + } + + /* curl requires the URL to be valid throughout it's operation, so dup it */ + curlstream->url = estrdup(filename); + curl_easy_setopt(curlstream->curl, CURLOPT_URL, curlstream->url); + + /* feed curl data into our read buffer */ + curl_easy_setopt(curlstream->curl, CURLOPT_WRITEFUNCTION, on_data_available); + curl_easy_setopt(curlstream->curl, CURLOPT_FILE, stream); + + /* feed headers */ + curl_easy_setopt(curlstream->curl, CURLOPT_HEADERFUNCTION, on_header_available); + curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); + + curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); + curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); + + /* enable progress notification */ + curl_easy_setopt(curlstream->curl, CURLOPT_PROGRESSFUNCTION, on_progress_avail); + curl_easy_setopt(curlstream->curl, CURLOPT_PROGRESSDATA, stream); + curl_easy_setopt(curlstream->curl, CURLOPT_NOPROGRESS, 0); + + curl_easy_setopt(curlstream->curl, CURLOPT_USERAGENT, FG(user_agent) ? FG(user_agent) : "PHP/" PHP_VERSION); + + /* TODO: read cookies and options from context */ + if (context && !strncasecmp(filename, "http", sizeof("http")-1)) { + /* Protocol version */ + if (SUCCESS == php_stream_context_get_option(context, "http", "protocol_version", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_DOUBLE) { + if (Z_DVAL_PP(ctx_opt) == 1.1) { + curl_easy_setopt(curlstream->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + } + } + + if (SUCCESS == php_stream_context_get_option(context, "http", "curl_verify_ssl_host", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 2); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 0); + } + if (SUCCESS == php_stream_context_get_option(context, "http", "curl_verify_ssl_peer", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 1); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 0); + } + + /* HTTP(S) */ + if (SUCCESS == php_stream_context_get_option(context, "http", "user_agent", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) { + curl_easy_setopt(curlstream->curl, CURLOPT_USERAGENT, Z_STRVAL_PP(ctx_opt)); + } + if (SUCCESS == php_stream_context_get_option(context, "http", "header", &ctx_opt)) { + if (Z_TYPE_PP(ctx_opt) == IS_ARRAY) { + HashPosition pos; + zval **header = NULL; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(ctx_opt), &pos); + SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(ctx_opt), (void *)&header, &pos); + zend_hash_move_forward_ex(Z_ARRVAL_PP(ctx_opt), &pos) + ) { + if (Z_TYPE_PP(header) == IS_STRING) { + curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, Z_STRVAL_PP(header)); + } + } + } else if (Z_TYPE_PP(ctx_opt) == IS_STRING && Z_STRLEN_PP(ctx_opt)) { + char *p, *token, *trimmed, *copy_ctx_opt; + + copy_ctx_opt = php_trim(Z_STRVAL_PP(ctx_opt), Z_STRLEN_PP(ctx_opt), NULL, 0, NULL, 3 TSRMLS_CC); + p = php_strtok_r(copy_ctx_opt, "\r\n", &token); + while (p) { + trimmed = php_trim(p, strlen(p), NULL, 0, NULL, 3 TSRMLS_CC); + curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, trimmed); + efree(trimmed); + p = php_strtok_r(NULL, "\r\n", &token); + } + efree(copy_ctx_opt); + } + if (curlstream->headers_slist) { + curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, curlstream->headers_slist); + } + } + if (SUCCESS == php_stream_context_get_option(context, "http", "method", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) { + if (strcasecmp(Z_STRVAL_PP(ctx_opt), "get")) { + if (!strcasecmp(Z_STRVAL_PP(ctx_opt), "head")) { + curl_easy_setopt(curlstream->curl, CURLOPT_NOBODY, 1); + } else { + if (!strcasecmp(Z_STRVAL_PP(ctx_opt), "post")) { + curl_easy_setopt(curlstream->curl, CURLOPT_POST, 1); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_CUSTOMREQUEST, Z_STRVAL_PP(ctx_opt)); + } + if (SUCCESS == php_stream_context_get_option(context, "http", "content", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) { + curl_easy_setopt(curlstream->curl, CURLOPT_POSTFIELDS, Z_STRVAL_PP(ctx_opt)); + curl_easy_setopt(curlstream->curl, CURLOPT_POSTFIELDSIZE, (long)Z_STRLEN_PP(ctx_opt)); + } + } + } + } + if (SUCCESS == php_stream_context_get_option(context, "http", "proxy", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) { + curl_easy_setopt(curlstream->curl, CURLOPT_PROXY, Z_STRVAL_PP(ctx_opt)); + } + if (SUCCESS == php_stream_context_get_option(context, "http", "max_redirects", &ctx_opt)) { + long mr = 20; + if (Z_TYPE_PP(ctx_opt) != IS_STRING || !is_numeric_string(Z_STRVAL_PP(ctx_opt), Z_STRLEN_PP(ctx_opt), &mr, NULL, 1)) { + if (Z_TYPE_PP(ctx_opt) == IS_LONG) { + mr = Z_LVAL_PP(ctx_opt); + } + } + if (mr > 1) { + if (PG(open_basedir) && *PG(open_basedir)) { + curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); + } + curl_easy_setopt(curlstream->curl, CURLOPT_MAXREDIRS, mr); + } + } else { + if (PG(open_basedir) && *PG(open_basedir)) { + curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); + } + curl_easy_setopt(curlstream->curl, CURLOPT_MAXREDIRS, 20L); + } + } else if (context && !strncasecmp(filename, "ftps", sizeof("ftps")-1)) { + if (SUCCESS == php_stream_context_get_option(context, "ftp", "curl_verify_ssl_host", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 2); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 0); + } + if (SUCCESS == php_stream_context_get_option(context, "ftp", "curl_verify_ssl_peer", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 1); + } else { + curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 0); + } + } + + /* prepare for "pull" mode */ + curl_multi_add_handle(curlstream->multi, curlstream->curl); + + /* Prepare stuff for file_get_wrapper_data: the data is an array: + * + * data = array( + * "headers" => array("Content-Type: text/html", "Xxx: Yyy"), + * "readbuf" => resource (equivalent to curlstream->readbuffer) + * ); + * */ + MAKE_STD_ZVAL(stream->wrapperdata); + array_init(stream->wrapperdata); + + MAKE_STD_ZVAL(curlstream->headers); + array_init(curlstream->headers); + + add_assoc_zval(stream->wrapperdata, "headers", curlstream->headers); + + MAKE_STD_ZVAL(tmp); + php_stream_to_zval(curlstream->readbuffer.buf, tmp); + add_assoc_zval(stream->wrapperdata, "readbuf", tmp); + +#ifndef HAVE_FOPENCOOKIE + if (options & STREAM_WILL_CAST) { + /* we will need to download the whole resource now, + * since we cannot get the actual FD for the download, + * so we won't be able to drive curl via stdio. */ + +/* TODO: this needs finishing */ + + curl_easy_perform(curlstream->curl); + } + else +#endif + { + /* fire up the connection; we need to detect a connection error here, + * otherwise the curlstream we return ends up doing nothing useful. */ + CURLMcode m; + CURLMsg *msg; + int msgs_left, msg_found = 0; + + while (CURLM_CALL_MULTI_PERFORM == (m = curl_multi_perform(curlstream->multi, &curlstream->pending))) { + ; /* spin */ + } + + if (m != CURLM_OK) { +#if HAVE_CURL_MULTI_STRERROR + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(m)); +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error mcode=%d", m); +#endif + goto exit_fail; + } + + /* we have only one curl handle here, even though we use multi syntax, + * so it's ok to fail on any error */ + while ((msg = curl_multi_info_read(curlstream->multi, &msgs_left))) { + if (msg->data.result == CURLE_OK) { + continue; + } else { +#if HAVE_CURL_EASY_STRERROR + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_easy_strerror(msg->data.result)); +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error mcode=%d", msg->data.result); +#endif + msg_found++; + } + } + if (msg_found) { + goto exit_fail; + } + } + + return stream; + +exit_fail: + php_stream_close(stream); + return NULL; +} + +static php_stream_wrapper_ops php_curl_wrapper_ops = { + php_curl_stream_opener, + NULL, /* stream_close: curl streams know how to clean themselves up */ + NULL, /* stream_stat: curl streams know how to stat themselves */ + NULL, /* stat url */ + NULL, /* opendir */ + "cURL", /* label */ + NULL, /* unlink */ + NULL, /* rename */ + NULL, /* mkdir */ + NULL /* rmdir */ +}; + +php_stream_wrapper php_curl_wrapper = { + &php_curl_wrapper_ops, + NULL, + 1 /* is_url */ +}; + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/curl/tests/bug27023.phpt b/ext/curl/tests/bug27023.phpt new file mode 100644 index 0000000..b738c95 --- /dev/null +++ b/ext/curl/tests/bug27023.phpt @@ -0,0 +1,48 @@ +--TEST-- +Bug #27023 (CURLOPT_POSTFIELDS does not parse content types for files) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +$ch = curl_init(); +curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=file"); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + +$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt'); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt;type=text/plain'); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt;filename=foo.txt'); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt;type=text/plain;filename=foo.txt'); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + +$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt;filename=foo.txt;type=text/plain'); +curl_setopt($ch, CURLOPT_POSTFIELDS, $params); +var_dump(curl_exec($ch)); + + +curl_close($ch); +?> +--EXPECTF-- +string(%d) "curl_testdata1.txt|application/octet-stream" +string(%d) "curl_testdata1.txt|text/plain" +string(%d) "foo.txt|application/octet-stream" +string(%d) "foo.txt|text/plain" +string(%d) "foo.txt|text/plain" diff --git a/ext/curl/tests/bug45161.phpt b/ext/curl/tests/bug45161.phpt new file mode 100644 index 0000000..9fdc7a7 --- /dev/null +++ b/ext/curl/tests/bug45161.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #45161 (Reusing a curl handle leaks memory) +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) == 'WIN') { + exit("skip not for Windows"); +} +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +$curl_version = curl_version(); +if ($curl_version['version_number'] < 0x071100) { + exit("skip: test works only with curl >= 7.17.0"); +} +?> +--FILE-- +<?php + +// Fill memory for test +$ch = curl_init(); +$fp = fopen('/dev/null', 'w'); + +/* +$i = $start = $end = 100000.00; +for ($i = 0; $i < 100; $i++) { + curl_setopt($ch, CURLOPT_URL, 'http://127.0.0.1:9/'); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_exec($ch); +} +*/ + +// Start actual test +$start = memory_get_usage() + 1024; +for($i = 0; $i < 1024; $i++) { + curl_setopt($ch, CURLOPT_URL, 'http://127.0.0.1:9/'); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_exec($ch); +} +if ($start < memory_get_usage()) { + echo 'FAIL'; +} else { + echo 'PASS'; +} +echo "\n"; +fclose($fp); +unset($fp); +?> +--EXPECT-- +PASS diff --git a/ext/curl/tests/bug46711.phpt b/ext/curl/tests/bug46711.phpt new file mode 100644 index 0000000..8eef556 --- /dev/null +++ b/ext/curl/tests/bug46711.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #46711 (lost memory when foreach is used for values passed to curl_setopt()) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php +$ch = curl_init(); + +$opt = array( + CURLOPT_AUTOREFERER => TRUE, + CURLOPT_BINARYTRANSFER => TRUE +); + +curl_setopt( $ch, CURLOPT_AUTOREFERER , TRUE ); + +foreach( $opt as $option => $value ) { + curl_setopt( $ch, $option, $value ); +} + +var_dump($opt); // with this bug, $opt[58] becomes NULL + +?> +--EXPECT-- +array(2) { + [58]=> + bool(true) + [19914]=> + bool(true) +} diff --git a/ext/curl/tests/bug46739.phpt b/ext/curl/tests/bug46739.phpt new file mode 100644 index 0000000..895bba7 --- /dev/null +++ b/ext/curl/tests/bug46739.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #46739 (array returned by curl_getinfo should contain content_type key) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +?> +--FILE-- +<?php +$ch = curl_init('http://127.0.0.1:9/'); + +curl_exec($ch); +$info = curl_getinfo($ch); + +echo (array_key_exists('content_type', $info)) ? "set" : "not set"; +?> +--EXPECT-- +set diff --git a/ext/curl/tests/bug48203.phpt b/ext/curl/tests/bug48203.phpt new file mode 100644 index 0000000..d8f4d22 --- /dev/null +++ b/ext/curl/tests/bug48203.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #48203 (Crash when CURLOPT_STDERR is set to regular file) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php + +$fp = fopen(dirname(__FILE__) . '/bug48203.tmp', 'w'); + +$ch = curl_init(); + +curl_setopt($ch, CURLOPT_VERBOSE, 1); +curl_setopt($ch, CURLOPT_STDERR, $fp); +curl_setopt($ch, CURLOPT_URL, getenv('PHP_CURL_HTTP_REMOTE_SERVER')); + +fclose($fp); // <-- premature close of $fp caused a crash! + +curl_exec($ch); +curl_close($ch); + +echo "Ok\n"; + +?> +--CLEAN-- +<?php @unlink(dirname(__FILE__) . '/bug48203.tmp'); ?> +--EXPECTF-- +Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug48203.php on line %d +%A +Ok diff --git a/ext/curl/tests/bug48203_multi.phpt b/ext/curl/tests/bug48203_multi.phpt new file mode 100644 index 0000000..7d4ee47 --- /dev/null +++ b/ext/curl/tests/bug48203_multi.phpt @@ -0,0 +1,90 @@ +--TEST-- +Variation of bug #48203 with curl_multi_exec (Crash when file pointers passed to curl are closed before calling curl_multi_exec) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php + +function checkForClosedFilePointer($curl_option, $description) { + $fp = fopen(dirname(__FILE__) . '/bug48203.tmp', 'w'); + + $ch1 = curl_init(); + $ch2 = curl_init(); + + $options = array( + CURLOPT_RETURNTRANSFER => 1, + $curl_option => $fp, + CURLOPT_URL => getenv("PHP_CURL_HTTP_REMOTE_SERVER") + ); + + // we also need to set CURLOPT_VERBOSE to test CURLOPT_STDERR properly + if (CURLOPT_STDERR == $curl_option) { + $options[CURLOPT_VERBOSE] = 1; + } + + if (CURLOPT_INFILE == $curl_option) { + $options[CURLOPT_UPLOAD] = 1; + } + + curl_setopt_array($ch1, $options); + curl_setopt_array($ch2, $options); + + fclose($fp); // <-- premature close of $fp caused a crash! + + $mh = curl_multi_init(); + + curl_multi_add_handle($mh, $ch1); + curl_multi_add_handle($mh, $ch2); + + $active = 0; + do { + curl_multi_exec($mh, $active); + } while ($active > 0); + + curl_multi_remove_handle($mh, $ch1); + curl_multi_remove_handle($mh, $ch2); + curl_multi_close($mh); + + echo "Ok for $description\n"; +} + +$options_to_check = array( + "CURLOPT_STDERR", "CURLOPT_WRITEHEADER", "CURLOPT_FILE", "CURLOPT_INFILE" +); + +foreach($options_to_check as $option) { + checkForClosedFilePointer(constant($option), $option); +} + +?> +--CLEAN-- +<?php @unlink(dirname(__FILE__) . '/bug48203.tmp'); ?> +--EXPECTF-- +Warning: curl_multi_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug48203_multi.php on line 36 + +Warning: curl_multi_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug48203_multi.php on line 36 +%A +Ok for CURLOPT_STDERR +%A +Warning: curl_multi_exec(): CURLOPT_WRITEHEADER resource has gone away, resetting to default in %sbug48203_multi.php on line 36 + +Warning: curl_multi_exec(): CURLOPT_WRITEHEADER resource has gone away, resetting to default in %sbug48203_multi.php on line 36 +Ok for CURLOPT_WRITEHEADER + +Warning: curl_multi_exec(): CURLOPT_FILE resource has gone away, resetting to default in %sbug48203_multi.php on line 36 + +Warning: curl_multi_exec(): CURLOPT_FILE resource has gone away, resetting to default in %sbug48203_multi.php on line 36 +%A +Ok for CURLOPT_FILE + +Warning: curl_multi_exec(): CURLOPT_INFILE resource has gone away, resetting to default in %sbug48203_multi.php on line 36 + +Warning: curl_multi_exec(): CURLOPT_INFILE resource has gone away, resetting to default in %sbug48203_multi.php on line 36 +Ok for CURLOPT_INFILE diff --git a/ext/curl/tests/bug48207.phpt b/ext/curl/tests/bug48207.phpt new file mode 100644 index 0000000..6ac16f5 --- /dev/null +++ b/ext/curl/tests/bug48207.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test curl_setopt() CURLOPT_FILE readonly file handle +--CREDITS-- +Mark van der Velden +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php +/* + * Description : Adds a file which stores the received data from curl_exec(); + * Source code : ext/curl/multi.c + * Test documentation: http://wiki.php.net/qa/temp/ext/curl + */ + +// Figure out what handler to use +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +if(!empty($host)) { + + // Use the set Environment variable + $url = "$host/get.php?test=1"; + +} else { + + // Create a temporary file for the test + $tempname = tempnam(sys_get_temp_dir(), 'CURL_HANDLE'); + $url = 'file://'. $tempname; + + // add the test data to the file + file_put_contents($tempname, "Hello World!\nHello World!"); +} + + +$tempfile = tempnam(sys_get_temp_dir(), 'CURL_FILE_HANDLE'); + +$ch = curl_init($url); +$fp = fopen($tempfile, "r"); // Opening 'fubar' with the incorrect readonly flag +curl_setopt($ch, CURLOPT_FILE, $fp); +curl_exec($ch); +curl_close($ch); +is_file($tempfile) and @unlink($tempfile); +isset($tempname) and is_file($tempname) and @unlink($tempname); +?> +--EXPECTF-- +Warning: curl_setopt(): the provided file handle is not writable in %s on line %d +Hello World! +Hello World! diff --git a/ext/curl/tests/bug48514.phpt b/ext/curl/tests/bug48514.phpt new file mode 100644 index 0000000..0ea2575 --- /dev/null +++ b/ext/curl/tests/bug48514.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #48514 (cURL extension uses same resource name for simple and multi APIs) +--SKIPIF-- +<?php + +if (!extension_loaded('curl')) { + exit("skip curl extension not loaded"); +} + +?> +--FILE-- +<?php + +$ch1 = curl_init(); +var_dump($ch1); +var_dump(get_resource_type($ch1)); + +$ch2 = curl_multi_init(); +var_dump($ch2); +var_dump(get_resource_type($ch2)); + +?> +--EXPECTF-- +resource(%d) of type (curl) +%string|unicode%(4) "curl" +resource(%d) of type (curl_multi) +%string|unicode%(10) "curl_multi" diff --git a/ext/curl/tests/bug52202.phpt b/ext/curl/tests/bug52202.phpt new file mode 100644 index 0000000..a304d7f --- /dev/null +++ b/ext/curl/tests/bug52202.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #52202 (CURLOPT_PRIVATE gets clobbered) +--SKIPIF-- +<?php +if (!extension_loaded('curl')) exit("skip curl extension not loaded"); +?> +--FILE-- +<?php +$curl = curl_init("http://www.google.com"); +curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); +curl_setopt($curl, CURLOPT_PRIVATE, "123"); +curl_exec($curl); + +var_dump(curl_getinfo($curl, CURLINFO_PRIVATE)); +--EXPECT-- +string(3) "123" diff --git a/ext/curl/tests/bug52827.phpt b/ext/curl/tests/bug52827.phpt new file mode 100644 index 0000000..85a73fa --- /dev/null +++ b/ext/curl/tests/bug52827.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #52827 (curl_setopt with CURLOPT_STDERR erroneously increments the resource refcount) +--SKIPIF-- +<?php + +if (!extension_loaded('curl')) { + exit("skip curl extension not loaded"); +} + +?> +--FILE-- +<?php +$s = fopen('php://temp/maxmemory=1024','wb+'); + +/* force conversion of inner stream to STDIO. + * This is not necessary in Windows because the + * cast to a FILE* handle in curl_setopt already + * forces the conversion in that platform. The + * reason for this conversion is that the memory + * stream has an ugly but working mechanism to + * prevent being double freed when it's encapsulated, + * while STDIO streams don't. */ +$i = 0; +while ($i++ < 5000) { +fwrite($s, str_repeat('a',1024)); +} +$handle=curl_init('http://www.example.com'); +curl_setopt($handle, CURLOPT_STDERR, $s); + +echo "Done."; +--EXPECTF-- +Done. diff --git a/ext/curl/tests/bug54798.phpt b/ext/curl/tests/bug54798.phpt new file mode 100644 index 0000000..7ec84ad --- /dev/null +++ b/ext/curl/tests/bug54798.phpt @@ -0,0 +1,72 @@ +--TEST-- +Bug #54798 (Segfault when CURLOPT_STDERR file pointer is closed before calling curl_exec) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php + +function checkForClosedFilePointer($host, $curl_option, $description) { + $fp = fopen(dirname(__FILE__) . '/bug54798.tmp', 'w+'); + + $ch = curl_init(); + + // we also need CURLOPT_VERBOSE to be set to test CURLOPT_STDERR properly + if (CURLOPT_STDERR == $curl_option) { + curl_setopt($ch, CURLOPT_VERBOSE, 1); + } + + if (CURLOPT_INFILE == $curl_option) { + curl_setopt($ch, CURLOPT_UPLOAD, 1); + } + + curl_setopt($ch, $curl_option, $fp); + + curl_setopt($ch, CURLOPT_URL, $host); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + + fclose($fp); // <-- premature close of $fp caused a crash! + + curl_exec($ch); + + curl_close($ch); + + echo "Ok for $description\n"; +} + +$options_to_check = array( + "CURLOPT_STDERR", + "CURLOPT_WRITEHEADER", + "CURLOPT_FILE", + "CURLOPT_INFILE" +); + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +foreach($options_to_check as $option) { + checkForClosedFilePointer($host, constant($option), $option); +} + +?> +--CLEAN-- +<?php @unlink(dirname(__FILE__) . '/bug54798.tmp'); ?> +--EXPECTF-- +Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug54798.php on line %d +* About to connect() %a +* Closing connection #%d +Ok for CURLOPT_STDERR + +Warning: curl_exec(): CURLOPT_WRITEHEADER resource has gone away, resetting to default in %sbug54798.php on line 24 +Ok for CURLOPT_WRITEHEADER + +Warning: curl_exec(): CURLOPT_FILE resource has gone away, resetting to default in %sbug54798.php on line 24 +%a +Ok for CURLOPT_FILE + +Warning: curl_exec(): CURLOPT_INFILE resource has gone away, resetting to default in %sbug54798.php on line %d +Ok for CURLOPT_INFILE diff --git a/ext/curl/tests/bug55767.phpt b/ext/curl/tests/bug55767.phpt new file mode 100644 index 0000000..321f67b --- /dev/null +++ b/ext/curl/tests/bug55767.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test curl_opt() function with POST params from array with a numeric key +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl sending through GET an POST ***' . "\n"; + + $url = "{$host}/get.php?test=getpost&get_param=Hello%20World"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, array('Hello'=>'World','Foo'=>'Bar',100=>'John Doe')); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl sending through GET an POST *** +string(203) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + [100]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/bug61948-win32.phpt b/ext/curl/tests/bug61948-win32.phpt new file mode 100644 index 0000000..dc86526 --- /dev/null +++ b/ext/curl/tests/bug61948-win32.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #61948 (CURLOPT_COOKIEFILE '' raises open_basedir restriction) +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; +if(substr(PHP_OS, 0, 3) != 'WIN' ) + die("skip Not Valid for Linux"); +?> +--INI-- +open_basedir="c:/tmp" +--FILE-- +<?php + $ch = curl_init(); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "")); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "c:/tmp/foo")); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "c:/xxx/bar")); + curl_close($ch); +?> +--EXPECTF-- +%a + +Warning: curl_setopt(): open_basedir restriction in effect. File(c:/tmp/foo) is not within the allowed path(s): (c:/tmp) in %sbug61948-win32.php on line %d +bool(false) + +Warning: curl_setopt(): open_basedir restriction in effect. File(c:/xxx/bar) is not within the allowed path(s): (c:/tmp) in %sbug61948-win32.php on line %d +bool(false) diff --git a/ext/curl/tests/bug61948.phpt b/ext/curl/tests/bug61948.phpt new file mode 100644 index 0000000..00df07d --- /dev/null +++ b/ext/curl/tests/bug61948.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #61948 (CURLOPT_COOKIEFILE '' raises open_basedir restriction) +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; +if(substr(PHP_OS, 0, 3) == 'WIN' ) + die("skip Not Valid for Windows"); +?> +--INI-- +open_basedir="/tmp" +--FILE-- +<?php + $ch = curl_init(); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "")); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/foo")); + var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "/xxx/bar")); + curl_close($ch); +?> +--EXPECTF-- +bool(true) +bool(true) + +Warning: curl_setopt(): open_basedir restriction in effect. File(/xxx/bar) is not within the allowed path(s): (/tmp) in %sbug61948.php on line %d +bool(false) diff --git a/ext/curl/tests/bug62839.phpt b/ext/curl/tests/bug62839.phpt new file mode 100644 index 0000000..e6988d6 --- /dev/null +++ b/ext/curl/tests/bug62839.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #62839 (curl_copy_handle segfault with CURLOPT_FILE) +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; +?> +--FILE-- +<?php +$curl = curl_init(); + +$fd = tmpfile(); +curl_setopt($curl, CURLOPT_FILE, $fd); + +curl_copy_handle($curl); + +echo 'DONE!'; +?> +--EXPECTF-- +DONE! diff --git a/ext/curl/tests/bug63363.phpt b/ext/curl/tests/bug63363.phpt new file mode 100644 index 0000000..36abc5e --- /dev/null +++ b/ext/curl/tests/bug63363.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #63363 (CURL silently accepts boolean value for SSL_VERIFYHOST) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +$curl_version = curl_version(); +if ($curl_version['version_number'] >= 0x071c01) { + exit("skip: test valid for libcurl < 7.28.1"); +} +?> +--FILE-- +<?php +$ch = curl_init(); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false)); +/* Case that should throw an error */ +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2)); + +curl_close($ch); +?> +--EXPECTF-- +bool(true) + +Notice: curl_setopt(): CURLOPT_SSL_VERIFYHOST with value 1 is deprecated and will be removed as of libcurl 7.28.1. It is recommended to use value 2 instead in %s on line %d +bool(true) +bool(true) + +Notice: curl_setopt(): CURLOPT_SSL_VERIFYHOST with value 1 is deprecated and will be removed as of libcurl 7.28.1. It is recommended to use value 2 instead in %s on line %d +bool(true) +bool(true) diff --git a/ext/curl/tests/bug63795.phpt b/ext/curl/tests/bug63795.phpt new file mode 100644 index 0000000..798faa6 --- /dev/null +++ b/ext/curl/tests/bug63795.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #63795 (CURL >= 7.28.0 no longer support value 1 for CURLOPT_SSL_VERIFYHOST) +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + exit("skip curl extension not loaded"); +} +$curl_version = curl_version(); +if ($curl_version['version_number'] < 0x071c01) { + exit("skip: test valid for libcurl >= 7.28.1"); +} +?> +--FILE-- +<?php +$ch = curl_init(); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false)); +/* Case that should throw an error */ +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1)); +var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2)); + +curl_close($ch); +?> +--EXPECTF-- +bool(true) + +Notice: curl_setopt(): CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead in %s on line %d +bool(true) +bool(true) + +Notice: curl_setopt(): CURLOPT_SSL_VERIFYHOST no longer accepts the value 1, value 2 will be used instead in %s on line %d +bool(true) +bool(true) diff --git a/ext/curl/tests/curl_CURLOPT_READDATA.phpt b/ext/curl/tests/curl_CURLOPT_READDATA.phpt new file mode 100644 index 0000000..ea63d44 --- /dev/null +++ b/ext/curl/tests/curl_CURLOPT_READDATA.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test CURLOPT_READDATA without a callback function +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + +// The URL to POST to +$url = getenv('PHP_CURL_HTTP_REMOTE_SERVER') . '/get.php?test=post'; + +// Create a temporary file to read the data from +$tempname = tempnam(sys_get_temp_dir(), 'CURL_DATA'); +$datalen = file_put_contents($tempname, "hello=world&smurf=blue"); + +ob_start(); + +$ch = curl_init($url); +curl_setopt($ch, CURLOPT_URL, $url); +curl_setopt($ch, CURLOPT_POST, true); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_READDATA, fopen($tempname, 'rb')); +curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:', "Content-Length: {$datalen}")); + +if (false === $response = curl_exec($ch)) { + echo 'Error #' . curl_errno($ch) . ': ' . curl_error($ch); +} else { + echo $response; +} + +curl_close($ch); + +// Clean the temporary file +@unlink($tempname); + +--EXPECT-- +array(2) { + ["hello"]=> + string(5) "world" + ["smurf"]=> + string(4) "blue" +} diff --git a/ext/curl/tests/curl_basic_001.phpt b/ext/curl/tests/curl_basic_001.phpt new file mode 100644 index 0000000..fa362b3 --- /dev/null +++ b/ext/curl/tests/curl_basic_001.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test curl_exec() function with basic functionality +--CREDITS-- +Sebastian Deutsch <sebastian.deutsch@9elements.com> +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_exec(resource ch) + * Description: Perform a cURL session + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo "*** Testing curl_exec() : basic functionality ***\n"; + + $url = "{$host}/get.php?test=get"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + $ok = curl_exec($ch); + curl_close($ch); + $curl_content = ob_get_contents(); + ob_end_clean(); + + if($ok) { + var_dump( $curl_content ); + } else { + echo "curl_exec returned false"; + } +?> +===DONE=== +--EXPECTF-- +*** Testing curl_exec() : basic functionality *** +string(25) "Hello World! +Hello World!" +===DONE=== diff --git a/ext/curl/tests/curl_basic_002.phpt b/ext/curl/tests/curl_basic_002.phpt new file mode 100644 index 0000000..e46f323 --- /dev/null +++ b/ext/curl/tests/curl_basic_002.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test curl_opt() function with CURLOPT_RETURNTRANSFER parameter set to 1 +--CREDITS-- +Sebastian Deutsch <sebastian.deutsch@9elements.com> +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); ***' . "\n"; + + $url = "{$host}/get.php?test=get"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); *** +string(25) "Hello World! +Hello World!" +===DONE=== diff --git a/ext/curl/tests/curl_basic_003.phpt b/ext/curl/tests/curl_basic_003.phpt new file mode 100644 index 0000000..eb2aecd --- /dev/null +++ b/ext/curl/tests/curl_basic_003.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test curl_opt() function with POST parameters +--CREDITS-- +Sebastian Deutsch <sebastian.deutsch@9elements.com> +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl sending through GET an POST ***' . "\n"; + + $url = "{$host}/get.php?test=getpost&get_param=Hello%20World"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, "Hello=World&Foo=Bar&Person=John%20Doe"); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl sending through GET an POST *** +string(208) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_basic_004.phpt b/ext/curl/tests/curl_basic_004.phpt new file mode 100644 index 0000000..ea2eeca --- /dev/null +++ b/ext/curl/tests/curl_basic_004.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test curl_opt() function with setting referer +--CREDITS-- +Sebastian Deutsch <sebastian.deutsch@9elements.com> +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl setting referer ***' . "\n"; + + $url = "{$host}/get.php?test=referer"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_REFERER, 'http://www.refer.er'); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl setting referer *** +string(19) "http://www.refer.er" +===DONE=== diff --git a/ext/curl/tests/curl_basic_005.phpt b/ext/curl/tests/curl_basic_005.phpt new file mode 100644 index 0000000..9285c10 --- /dev/null +++ b/ext/curl/tests/curl_basic_005.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test curl_opt() function with user agent +--CREDITS-- +Sebastian Deutsch <sebastian.deutsch@9elements.com> +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl with user agent ***' . "\n"; + + $url = "{$host}/get.php?test=useragent"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_USERAGENT, 'cURL phpt'); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl with user agent *** +string(9) "cURL phpt" +===DONE=== diff --git a/ext/curl/tests/curl_basic_006.phpt b/ext/curl/tests/curl_basic_006.phpt new file mode 100644 index 0000000..5f1a4f4 --- /dev/null +++ b/ext/curl/tests/curl_basic_006.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test curl_opt() function with CURLOPT_WRITEFUNCTION parameter set to a closure +--CREDITS-- +? +TestFest 2009 - AFUP - Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl_setopt($ch, CURLOPT_WRITEFUNCTION, <closure>); ***' . "\n"; + + $url = "{$host}/get.php?test=get"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) { + echo 'Data: '.$data; + return strlen ($data); + }); + + curl_exec($ch); + curl_close($ch); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_setopt($ch, CURLOPT_WRITEFUNCTION, <closure>); *** +Data: Hello World! +Hello World!===DONE=== diff --git a/ext/curl/tests/curl_basic_007.phpt b/ext/curl/tests/curl_basic_007.phpt new file mode 100644 index 0000000..b7eba4b --- /dev/null +++ b/ext/curl/tests/curl_basic_007.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test curl_error() & curl_errno() function without url +--CREDITS-- +TestFest 2009 - AFUP - Perrick Penet <perrick@noparking.net> +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +//In January 2008 , level 7.18.0 of the curl lib, many of the messages changed. +//The final crlf was removed. This test is coded to work with or without the crlf. + +$ch = curl_init(); + +curl_exec($ch); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); +curl_close($ch); + + +?> +--EXPECTF-- +%string|unicode%(%d) "No URL set!%w" +int(3) diff --git a/ext/curl/tests/curl_basic_008.phpt b/ext/curl/tests/curl_basic_008.phpt new file mode 100644 index 0000000..29e3343 --- /dev/null +++ b/ext/curl/tests/curl_basic_008.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test curl_error() & curl_errno() function with problematic host +--CREDITS-- +TestFest 2009 - AFUP - Perrick Penet <perrick@noparking.net> +--SKIPIF-- +<?php + if (!extension_loaded("curl")) print "skip"; + $addr = "www.".uniqid().".".uniqid(); + if (gethostbyname($addr) != $addr) { + print "skip catch all dns"; + } +?> +--FILE-- +<?php + +$url = "http://www.".uniqid().".".uniqid(); +$ch = curl_init(); +curl_setopt($ch, CURLOPT_URL, $url); + +curl_exec($ch); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); +curl_close($ch); + + +?> +--EXPECTF-- +%unicode|string%(%d) "%r(Couldn't resolve host|Could not resolve host:)%r %Swww.%s" +int(6) diff --git a/ext/curl/tests/curl_basic_009.phpt b/ext/curl/tests/curl_basic_009.phpt new file mode 100644 index 0000000..529e590 --- /dev/null +++ b/ext/curl/tests/curl_basic_009.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test curl_error() & curl_errno() function with problematic protocol +--CREDITS-- +TestFest 2009 - AFUP - Perrick Penet <perrick@noparking.net> +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +$url = uniqid()."://www.".uniqid().".".uniqid(); +$ch = curl_init(); +curl_setopt($ch, CURLOPT_URL, $url); + +curl_exec($ch); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); +curl_close($ch); + + +?> +--EXPECTF-- +%unicode|string%(%d) "%Srotocol%s" +int(1) diff --git a/ext/curl/tests/curl_basic_010.phpt b/ext/curl/tests/curl_basic_010.phpt new file mode 100644 index 0000000..0fc2fe6 --- /dev/null +++ b/ext/curl/tests/curl_basic_010.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl_error() & curl_errno() function with problematic proxy +--CREDITS-- +TestFest 2009 - AFUP - Perrick Penet <perrick@noparking.net> +--SKIPIF-- +<?php + if (!extension_loaded("curl")) print "skip"; + $addr = "www.".uniqid().".".uniqid(); + if (gethostbyname($addr) != $addr) { + print "skip catch all dns"; + } +?> +--FILE-- +<?php + +$url = "http://www.example.org"; +$ch = curl_init(); +curl_setopt($ch, CURLOPT_PROXY, uniqid().":".uniqid()); +curl_setopt($ch, CURLOPT_URL, $url); + +curl_exec($ch); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); +curl_close($ch); + + +?> +--EXPECTF-- +%unicode|string%(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:)%r %s" +int(5) diff --git a/ext/curl/tests/curl_basic_011.phpt b/ext/curl/tests/curl_basic_011.phpt new file mode 100644 index 0000000..10c90b1 --- /dev/null +++ b/ext/curl/tests/curl_basic_011.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test curl_opt() function with COOKIE +--CREDITS-- +TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl with cookie ***' . "\n"; + + $url = "{$host}/get.php?test=cookie"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_COOKIE, 'foo=bar'); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl with cookie *** +string(3) "bar" +===DONE=== + diff --git a/ext/curl/tests/curl_basic_012.phpt b/ext/curl/tests/curl_basic_012.phpt new file mode 100644 index 0000000..e4706fa --- /dev/null +++ b/ext/curl/tests/curl_basic_012.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test curl_opt() function with CURLOPT_HTTP_VERSION/CURL_HTTP_VERSION_1_0 +--CREDITS-- +TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl with HTTP/1.0 ***' . "\n"; + + $url = "{$host}/get.php?test=httpversion"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl with HTTP/1.0 *** +string(8) "HTTP/1.0" +===DONE=== +
\ No newline at end of file diff --git a/ext/curl/tests/curl_basic_013.phpt b/ext/curl/tests/curl_basic_013.phpt new file mode 100644 index 0000000..c49d187 --- /dev/null +++ b/ext/curl/tests/curl_basic_013.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test curl_opt() function with CURLOPT_HTTP_VERSION/CURL_HTTP_VERSION_1_1 +--CREDITS-- +TestFest 2009 - AFUP - Xavier Gorse <xgorse@elao.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo '*** Testing curl with HTTP/1.1 ***' . "\n"; + + $url = "{$host}/get.php?test=httpversion"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $curl_content = curl_exec($ch); + curl_close($ch); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl with HTTP/1.1 *** +string(8) "HTTP/1.1" +===DONE=== +
\ No newline at end of file diff --git a/ext/curl/tests/curl_basic_014.phpt b/ext/curl/tests/curl_basic_014.phpt new file mode 100644 index 0000000..4037970 --- /dev/null +++ b/ext/curl/tests/curl_basic_014.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test curl_init() function with basic functionality +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?> +--FILE-- +<?php + $ch = curl_init(); + var_dump($ch); +?> +===DONE=== +--EXPECTF-- +resource(%d) of type (curl) +===DONE=== diff --git a/ext/curl/tests/curl_basic_015.phpt b/ext/curl/tests/curl_basic_015.phpt new file mode 100644 index 0000000..e8e43e5 --- /dev/null +++ b/ext/curl/tests/curl_basic_015.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test curl_init() function with $url parameter defined +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?> +--FILE-- +<?php + $url = 'http://www.example.com/'; + $ch = curl_init($url); + var_dump($url == curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); +?> +===DONE=== +--EXPECTF-- +bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_basic_016.phpt b/ext/curl/tests/curl_basic_016.phpt new file mode 100644 index 0000000..b5890c0 --- /dev/null +++ b/ext/curl/tests/curl_basic_016.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test curl_getinfo() function with basic functionality +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +$curl_version = curl_version(); +if ($curl_version['version_number'] > 0x071201) { + exit("skip: tests works only on older versions of curl"); +} +?> +--FILE-- +<?php + $ch = curl_init(); + $info = curl_getinfo($ch); + var_dump($info); +?> +===DONE=== +--EXPECTF-- +array(2%d) { + [%u|b%"url"]=> + string(0) "" + ["content_type"]=> + NULL + ["http_code"]=> + int(0) + ["header_size"]=> + int(0) + ["request_size"]=> + int(0) + ["filetime"]=> + int(0) + ["ssl_verify_result"]=> + int(0) + ["redirect_count"]=> + int(0) + ["total_time"]=> + float(0) + ["namelookup_time"]=> + float(0) + ["connect_time"]=> + float(0) + ["pretransfer_time"]=> + float(0) + ["size_upload"]=> + float(0) + ["size_download"]=> + float(0) + ["speed_download"]=> + float(0) + ["speed_upload"]=> + float(0) + ["download_content_length"]=> + float(%f) + ["upload_content_length"]=> + float(%f) + ["starttransfer_time"]=> + float(0) + ["redirect_time"]=> + float(0) +} +===DONE=== diff --git a/ext/curl/tests/curl_basic_017.phpt b/ext/curl/tests/curl_basic_017.phpt new file mode 100644 index 0000000..09247b2 --- /dev/null +++ b/ext/curl/tests/curl_basic_017.phpt @@ -0,0 +1,69 @@ +--TEST-- +Test curl_multi_exec() function with basic functionality +--CREDITS-- +TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +--FILE-- +<?php +/* Prototype : bool curl_multi_exec(resource ch) + * Description: Perform a cURL session + * Source code: ext/curl/multi.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo "*** Testing curl_exec() : basic functionality ***\n"; + + $url = "{$host}/get.php?test=get"; + $chs = array( + 0 => curl_init(), + 1 => curl_init(), + 2 => curl_init(), + ); + + ob_start(); // start output buffering + + curl_setopt($chs[0], CURLOPT_URL, $url); //set the url we want to use + curl_setopt($chs[1], CURLOPT_URL, $url); //set the url we want to use + curl_setopt($chs[2], CURLOPT_URL, $url); //set the url we want to use + + $mh = curl_multi_init(); + + // add handlers + curl_multi_add_handle($mh, $chs[0]); + curl_multi_add_handle($mh, $chs[1]); + curl_multi_add_handle($mh, $chs[2]); + + $running=null; + //execute the handles + $state = null; + do { + $state = curl_multi_exec($mh, $running); + } while ($running > 0); + + //close the handles + curl_multi_remove_handle($mh, $chs[0]); + curl_multi_remove_handle($mh, $chs[1]); + curl_multi_remove_handle($mh, $chs[2]); + curl_multi_close($mh); + + $curl_content = ob_get_contents(); + ob_end_clean(); + + if($state === CURLM_OK) { + var_dump( $curl_content ); + } else { + echo "curl_exec returned false"; + } +?> +===DONE=== +--EXPECTF-- +*** Testing curl_exec() : basic functionality *** +string(75) "Hello World! +Hello World!Hello World! +Hello World!Hello World! +Hello World!" +===DONE=== diff --git a/ext/curl/tests/curl_basic_018.phpt b/ext/curl/tests/curl_basic_018.phpt new file mode 100644 index 0000000..7cffb89 --- /dev/null +++ b/ext/curl/tests/curl_basic_018.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test curl_setopt() with curl_multi function with basic functionality +--CREDITS-- +TestFest 2009 - AFUP - Thomas Rabaix <thomas.rabaix@gmail.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +--FILE-- +<?php +/* Prototype : bool curl_setopt(resource ch, int option, mixed value) + * Description: Set an option for a cURL transfer + * Source code: ext/curl/interface.c + * Alias to functions: + */ + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + // start testing + echo "*** Testing curl_exec() : basic functionality ***\n"; + + $url = "{$host}/get.php?test=get"; + $chs = array( + 0 => curl_init(), + 1 => curl_init(), + 2 => curl_init(), + ); + + ob_start(); // start output buffering + + $options = array( + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_URL => $url, + ); + + curl_setopt_array($chs[0], $options); //set the options + curl_setopt_array($chs[1], $options); //set the options + curl_setopt_array($chs[2], $options); //set the options + + $mh = curl_multi_init(); + + // add handlers + curl_multi_add_handle($mh, $chs[0]); + curl_multi_add_handle($mh, $chs[1]); + curl_multi_add_handle($mh, $chs[2]); + + $running=null; + //execute the handles + do { + curl_multi_exec($mh, $running); + } while ($running > 0); + + $curl_content = ''; + $curl_content .= curl_multi_getcontent($chs[0]); + $curl_content .= curl_multi_getcontent($chs[1]); + $curl_content .= curl_multi_getcontent($chs[2]); + + //close the handles + curl_multi_remove_handle($mh, $chs[0]); + curl_multi_remove_handle($mh, $chs[1]); + curl_multi_remove_handle($mh, $chs[2]); + curl_multi_close($mh); + + var_dump( $curl_content ); + +?> +===DONE=== +--EXPECTF-- +*** Testing curl_exec() : basic functionality *** +%unicode|string%(75) "Hello World! +Hello World!Hello World! +Hello World!Hello World! +Hello World!" +===DONE=== diff --git a/ext/curl/tests/curl_basic_019.phpt b/ext/curl/tests/curl_basic_019.phpt new file mode 100644 index 0000000..ab605a8 --- /dev/null +++ b/ext/curl/tests/curl_basic_019.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test curl_getinfo() function with CURLINFO_EFFECTIVE_URL parameter +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + $url = "{$host}/get.php?test="; + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_exec($ch); + $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + var_dump($url == $info); + + curl_close($ch); +?> +===DONE=== +--EXPECTF-- +Hello World! +Hello World!bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_basic_020.phpt b/ext/curl/tests/curl_basic_020.phpt new file mode 100644 index 0000000..d622053 --- /dev/null +++ b/ext/curl/tests/curl_basic_020.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test curl_getinfo() function with CURLINFO_HTTP_CODE parameter +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + $url = "{$host}/get.php?test="; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_exec($ch); + var_dump(curl_getinfo($ch, CURLINFO_HTTP_CODE)); + curl_close($ch); +?> +===DONE=== +--EXPECTF-- +Hello World! +Hello World!int(200) +===DONE=== diff --git a/ext/curl/tests/curl_basic_021.phpt b/ext/curl/tests/curl_basic_021.phpt new file mode 100644 index 0000000..3b4798d --- /dev/null +++ b/ext/curl/tests/curl_basic_021.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test curl_getinfo() function with CURLINFO_CONTENT_TYPE parameter +--CREDITS-- +Jean-Marc Fontaine <jmf@durcommefaire.net> +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + $url = "{$host}/get.php?test=contenttype"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_exec($ch); + var_dump(curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); + curl_close($ch); +?> +===DONE=== +--EXPECTF-- +%unicode|string%(24) "text/plain;charset=utf-8" +===DONE=== diff --git a/ext/curl/tests/curl_close_basic.phpt b/ext/curl/tests/curl_close_basic.phpt new file mode 100644 index 0000000..9c01b02 --- /dev/null +++ b/ext/curl/tests/curl_close_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +curl_close +--CREDITS-- +Stefan Koopmanschap <stefan@php.net> +#testfest Utrecht 2009 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php +$ch = curl_init(); +curl_close($ch); +var_dump($ch); +?> +===DONE=== +--EXPECTF-- +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic.phpt b/ext/curl/tests/curl_copy_handle_basic.phpt new file mode 100644 index 0000000..1a6ff41 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl_copy_handle() function with basic functionality +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- +<?php + if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +?> +--FILE-- +<?php +echo "*** Testing curl_copy_handle(): basic ***\n"; + +// create a new cURL resource +$ch = curl_init(); + +// set URL and other appropriate options +curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/'); +curl_setopt($ch, CURLOPT_HEADER, 0); + +// copy the handle +$ch2 = curl_copy_handle($ch); + +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): basic *** +bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_001.phpt b/ext/curl/tests/curl_copy_handle_basic_001.phpt new file mode 100644 index 0000000..f1b4db3 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_001.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test curl_copy_handle() with simple get +--CREDITS-- +Rick Buitenman <rick@meritos.nl> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Testing curl copy handle with simple GET ***' . "\n"; + + $url = "{$host}/get.php?test=getpost&get_param=Hello%20World"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple GET *** +string(106) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(0) { +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_002.phpt b/ext/curl/tests/curl_copy_handle_basic_002.phpt new file mode 100644 index 0000000..9ab3363 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_002.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test curl_copy_handle() with simple POST +--CREDITS-- +Rick Buitenman <rick@meritos.nl> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Testing curl copy handle with simple POST ***' . "\n"; + + $url = "{$host}/get.php?test=getpost"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, "Hello=World&Foo=Bar&Person=John%20Doe"); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple POST *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_004.phpt b/ext/curl/tests/curl_copy_handle_basic_004.phpt new file mode 100644 index 0000000..9b794e9 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_004.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test curl_copy_handle() after exec() +--CREDITS-- +Rick Buitenman <rick@meritos.nl> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Test curl_copy_handle() after exec() ***' . "\n"; + + $url = "{$host}/get.php?test=getpost&get_param=Hello%20World"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + + $curl_content = curl_exec($ch); + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content_copy = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content_copy ); +?> +===DONE=== +--EXPECTF-- +*** Test curl_copy_handle() after exec() *** +string(106) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(0) { +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_005.phpt b/ext/curl/tests/curl_copy_handle_basic_005.phpt new file mode 100644 index 0000000..aa9e2fa --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_005.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test curl_copy_handle() after exec() with POST +--CREDITS-- +Rick Buitenman <rick@meritos.nl> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Test curl_copy_handle() after exec() with POST ***' . "\n"; + + $url = "{$host}/get.php?test=getpost"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, "Hello=World&Foo=Bar&Person=John%20Doe"); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + + $curl_content = curl_exec($ch); + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content_copy = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content_copy ); +?> +===DONE=== +--EXPECTF-- +*** Test curl_copy_handle() after exec() with POST *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_006.phpt b/ext/curl/tests/curl_copy_handle_basic_006.phpt new file mode 100644 index 0000000..defc0f2 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_006.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test curl_copy_handle() with User Agent +--CREDITS-- +Rick Buitenman <rick@meritos.nl> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Testing curl copy handle with User Agent ***' . "\n"; + + $url = "{$host}/get.php?test=useragent"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_USERAGENT, 'cURL phpt'); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + + var_dump( curl_exec($ch) ); + var_dump( curl_exec($copy) ); + + curl_close($ch); // can not close original handle before curl_exec($copy) since it causes char * inputs to be invalid (see also: http://curl.haxx.se/libcurl/c/curl_easy_duphandle.html) + curl_close($copy); + +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with User Agent *** +string(9) "cURL phpt" +string(9) "cURL phpt" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_007.phpt b/ext/curl/tests/curl_copy_handle_basic_007.phpt new file mode 100644 index 0000000..aa7306c --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_007.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test curl_copy_handle() with simple POST +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + echo '*** Testing curl copy handle with simple POST using array as arguments ***' . "\n"; + + $url = "{$host}/get.php?test=getpost"; + $ch = curl_init(); + + ob_start(); // start output buffering + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, array("Hello" => "World", "Foo" => "Bar", "Person" => "John Doe")); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // Disable Expect: header (lighttpd does not support it :) + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple POST using array as arguments *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_008.phpt b/ext/curl/tests/curl_copy_handle_basic_008.phpt new file mode 100644 index 0000000..692c2df --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_008.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test curl_copy_handle() with CURLOPT_PROGRESSFUNCTION +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + + $url = "{$host}/get.php"; + $ch = curl_init($url); + + curl_setopt($ch, CURLOPT_NOPROGRESS, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function() { }); + $ch2 = curl_copy_handle($ch); + echo curl_exec($ch), PHP_EOL; + unset($ch); + echo curl_exec($ch2); + +?> +--EXPECTF-- +Hello World! +Hello World! +Hello World! +Hello World! diff --git a/ext/curl/tests/curl_copy_handle_variation1.phpt b/ext/curl/tests/curl_copy_handle_variation1.phpt new file mode 100644 index 0000000..da45221 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_variation1.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test curl_copy_handle() change options in one handle +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- +<?php + if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +?> +--FILE-- +<?php +echo "*** Testing curl_copy_handle(): basic ***\n"; + +// create a new cURL resource +$ch = curl_init(); + +// set URL and other appropriate options +curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/'); + +// copy the handle +$ch2 = curl_copy_handle($ch); + +// change the CURLOPT_URL for the second handle +curl_setopt($ch2, CURLOPT_URL, 'http://www.bar.com/'); + +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): basic *** +bool(false) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_variation2.phpt b/ext/curl/tests/curl_copy_handle_variation2.phpt new file mode 100644 index 0000000..924bf6a --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_variation2.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test curl_copy_handle() add options to the handles +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- +<?php + if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +?> +--COMMENT-- +the only way to test if a option is setten on a curl handle is using the curl_getinfo() function. +but this can only check on a limited amount of options... +--FILE-- +<?php +echo "*** Testing curl_copy_handle(): add options after copy ***\n"; + +// create a new cURL resource +$ch = curl_init(); + +// copy the handle +$ch2 = curl_copy_handle($ch); +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); + +// add some CURLOPT to the second handle +curl_setopt($ch2, CURLOPT_URL, 'http://www.example.com/'); + +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); + +// add same CURLOPT to the first handle +curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/'); +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); + +// change a CURLOPT in the second handle +curl_setopt($ch2, CURLOPT_URL, 'http://www.bar.com/'); +var_dump(curl_getinfo($ch) === curl_getinfo($ch2)); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): add options after copy *** +bool(true) +bool(false) +bool(true) +bool(false) +===DONE=== diff --git a/ext/curl/tests/curl_error_basic.phpt b/ext/curl/tests/curl_error_basic.phpt new file mode 100644 index 0000000..3d35023 --- /dev/null +++ b/ext/curl/tests/curl_error_basic.phpt @@ -0,0 +1,41 @@ +--TEST-- +curl_error() function - basic test for curl_error using a fake url +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- +<?php + +if (!extension_loaded("curl")) die("skip\n"); + +$url = "fakeURL"; +$ip = gethostbyname($url); +if ($ip != $url) die("skip 'fakeURL' resolves to $ip\n"); + +?> +--FILE-- +<?php +/* + * Prototype: string curl_error(resource $ch) + * Description: Returns a clear text error message for the last cURL operation. + * Source: ext/curl/interface.c + * Documentation: http://wiki.php.net/qa/temp/ext/curl + */ + +// Fake URL to trigger an error +$url = "fakeURL"; + +echo "== Testing curl_error with a fake URL ==\n"; + +// cURL handler +$ch = curl_init($url); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + +curl_exec($ch); +var_dump(curl_error($ch)); +curl_close($ch); + +?> +--EXPECTF-- +== Testing curl_error with a fake URL == +string(%d) "%sfakeURL%S" diff --git a/ext/curl/tests/curl_file_deleted_before_curl_close.phpt b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt new file mode 100644 index 0000000..592f110 --- /dev/null +++ b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt @@ -0,0 +1,38 @@ +--TEST-- +Memory corruption error if fp of just created file is closed before curl_close. +--CREDITS-- +Alexey Shein <confik@gmail.com> +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?> +--FILE-- +<?php + +$ch = curl_init(getenv('PHP_CURL_HTTP_REMOTE_SERVER')); + +$temp_file = dirname(__FILE__) . '/curl_file_deleted_before_curl_close.tmp'; +if (file_exists($temp_file)) { + unlink($temp_file); // file should not exist before test +} + +$handle = fopen($temp_file, 'w'); + +curl_setopt($ch, CURLOPT_STDERR, $handle); +curl_setopt($ch, CURLOPT_VERBOSE, 1); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + +curl_exec($ch); + +fclose($handle); // causes glibc memory error + +//unlink($temp_file); // uncomment to test segfault (file not found on iowrite.c) + +curl_close($ch); +echo "Closed correctly\n"; +?> +--CLEAN-- +<?php +unlink(dirname(__FILE__) . '/curl_file_deleted_before_curl_close.tmp'); +?> +--EXPECTF-- +* Closing connection #%d +Closed correctly diff --git a/ext/curl/tests/curl_ftp_pasv.phpt b/ext/curl/tests/curl_ftp_pasv.phpt new file mode 100644 index 0000000..6cd7429 --- /dev/null +++ b/ext/curl/tests/curl_ftp_pasv.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test curl_exec() function with basic functionality +--CREDITS-- +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_FTP_REMOTE_SERVER')) exit("skip PHP_CURL_FTP_REMOTE_SERVER env variable is not defined"); +if (false === getenv('PHP_CURL_FTP_REMOTE_USER')) exit("skip PHP_CURL_FTP_REMOTE_USER env variable is not defined"); +if (false === getenv('PHP_CURL_FTP_REMOTE_PASSWD')) exit("skip PHP_CURL_FTP_REMOTE_PASSWD env variable is not defined"); +?> +--FILE-- +<?php + $host = getenv('PHP_CURL_FTP_REMOTE_SERVER'); + $username = getenv('PHP_CURL_FTP_REMOTE_USER'); + $password = getenv('PHP_CURL_FTP_REMOTE_PASSWD'); + + // FTP this script to a server + $fp = fopen ( __FILE__ , "r" ); + $url = "ftp://$username:$password@$host/test.phpt" ; + + $ch = curl_init (); + + // enable below to get the output in verbose mode. + // curl_setopt ( $ch , CURLOPT_VERBOSE, 1 ); + + /* Without enabling SKIP_PASV_IP flag, the following output will be seen.. + < 227 Entering Passive Mode (10,5,80,146,100,199) + * Trying 10.5.80.146... * connected + * Connecting to 10.5.80.146 (10.5.80.146) port 25799 + */ + + /* After enabling SKIP_PASV_IP flag, the following output will be seen.. + < 227 Entering Passive Mode (10,5,80,146,50,229) + * Skips 10.5.80.146 for data connection, uses 10.5.80.146 instead + * Trying 10.5.80.146... * connected + */ + + curl_setopt ( $ch , CURLOPT_URL, $url ); + curl_setopt ( $ch , CURLOPT_TRANSFERTEXT, 1 ); + + //force passive connection + curl_setopt ( $ch , CURLOPT_FTP_USE_EPSV, 0 ); + curl_setopt ( $ch , CURLOPT_FTP_SKIP_PASV_IP, 1 ); + + // mark the file for upload.. + curl_setopt ( $ch , CURLOPT_INFILE, $fp ); + curl_setopt ( $ch , CURLOPT_INFILESIZE, filesize(__FILE__) ); + curl_setopt ( $ch , CURLOPT_PUT, 1 ); + curl_setopt ( $ch , CURLOPT_UPLOAD, 1 ); + + $result = curl_exec ( $ch ); + var_dump ( $result ); + curl_close ( $ch ); + +?> +===DONE=== +--EXPECTF-- +bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_multi_close_basic.phpt b/ext/curl/tests/curl_multi_close_basic.phpt new file mode 100644 index 0000000..28865bc --- /dev/null +++ b/ext/curl/tests/curl_multi_close_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +curl_multi_close +--CREDITS-- +Stefan Koopmanschap <stefan@php.net> +#testfest Utrecht 2009 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php +$ch = curl_multi_init(); +curl_multi_close($ch); +var_dump($ch); +?> +===DONE=== +--EXPECTF-- +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_multi_getcontent_basic3.phpt b/ext/curl/tests/curl_multi_getcontent_basic3.phpt new file mode 100644 index 0000000..ac2a371 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_basic3.phpt @@ -0,0 +1,62 @@ +--TEST-- +Curl_multi_getcontent() basic test with different sources (local file/http) +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip need ext/curl'; +if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); +} +?> +--FILE-- +<?php + //CURL_MULTI_GETCONTENT TEST + + //CREATE RESOURCES + $ch1=curl_init(); + $ch2=curl_init(); + + //SET URL AND OTHER OPTIONS + $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + curl_setopt($ch1, CURLOPT_URL, "{$host}/get.php?test=getpost&get_param=Hello%20World"); + curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); + curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); + + //CREATE MULTIPLE CURL HANDLE + $mh=curl_multi_init(); + + //ADD THE 2 HANDLES + curl_multi_add_handle($mh,$ch1); + curl_multi_add_handle($mh,$ch2); + + //EXECUTE + $running=0; + do { + curl_multi_exec($mh,$running); + } while ($running>0); + + $results1=curl_multi_getcontent($ch1); + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(0) { +} +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error1.phpt b/ext/curl/tests/curl_multi_getcontent_error1.phpt new file mode 100644 index 0000000..2fb11b3 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error1.phpt @@ -0,0 +1,51 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php + //CURL_MULTI_GETCONTENT TEST + + //CREATE RESOURCES + $ch1=curl_init(); + $ch2=curl_init(); + + //SET URL AND OTHER OPTIONS + curl_setopt($ch1, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata1.txt"); + curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); + curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); + + //CREATE MULTIPLE CURL HANDLE + $mh=curl_multi_init(); + + //ADD THE 2 HANDLES + curl_multi_add_handle($mh,$ch1); + curl_multi_add_handle($mh,$ch2); + + //EXECUTE + $running=0; + do { + curl_multi_exec($mh,$running); + } while ($running>0); + + $results1=curl_multi_getcontent(); //no parameter + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects exactly 1 parameter, 0 given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error2.phpt b/ext/curl/tests/curl_multi_getcontent_error2.phpt new file mode 100644 index 0000000..0145d6a --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error2.phpt @@ -0,0 +1,51 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php + //CURL_MULTI_GETCONTENT TEST + + //CREATE RESOURCES + $ch1=curl_init(); + $ch2=curl_init(); + + //SET URL AND OTHER OPTIONS + curl_setopt($ch1, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata1.txt"); + curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); + curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); + + //CREATE MULTIPLE CURL HANDLE + $mh=curl_multi_init(); + + //ADD THE 2 HANDLES + curl_multi_add_handle($mh,$ch1); + curl_multi_add_handle($mh,$ch2); + + //EXECUTE + $running=0; + do { + curl_multi_exec($mh,$running); + } while ($running>0); + + $results1=curl_multi_getcontent($ch1,$ch2); //no parameter + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects exactly 1 parameter, 2 given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error3.phpt b/ext/curl/tests/curl_multi_getcontent_error3.phpt new file mode 100644 index 0000000..2ad1480 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error3.phpt @@ -0,0 +1,53 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php + //CURL_MULTI_GETCONTENT TEST + + //CREATE RESOURCES + $ch1=curl_init(); + $ch2=curl_init(); + + //SET URL AND OTHER OPTIONS + curl_setopt($ch1, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata1.txt"); + curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); + curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); + + //CREATE MULTIPLE CURL HANDLE + $mh=curl_multi_init(); + + //ADD THE 2 HANDLES + curl_multi_add_handle($mh,$ch1); + curl_multi_add_handle($mh,$ch2); + + //EXECUTE + $running=0; + do { + curl_multi_exec($mh,$running); + } while ($running>0); + + $ch1="string"; + + $results1=curl_multi_getcontent($ch1); //incorrect parameter type + $results2=curl_multi_getcontent($ch2); + + //CLOSE + //curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error4.phpt b/ext/curl/tests/curl_multi_getcontent_error4.phpt new file mode 100644 index 0000000..68bda37 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error4.phpt @@ -0,0 +1,66 @@ +--TEST-- +Curl_multi_getcontent() error test with undefined handle +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- +<?php +if (!extension_loaded('curl')) print 'skip'; +?> +--FILE-- +<?php + //CURL_MULTI_GETCONTENT TEST + + //CREATE RESOURCES + //$ch1=undefined; + $ch2=curl_init(); + + //SET URL AND OTHER OPTIONS + curl_setopt($ch1, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata1.txt"); + curl_setopt($ch2, CURLOPT_URL, "file://".dirname(__FILE__). DIRECTORY_SEPARATOR . "curl_testdata2.txt"); + curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); + + //CREATE MULTIPLE CURL HANDLE + $mh=curl_multi_init(); + + //ADD THE 2 HANDLES + curl_multi_add_handle($mh,$ch1); + curl_multi_add_handle($mh,$ch2); + + //EXECUTE + $running=0; + do { + curl_multi_exec($mh,$running); + } while ($running>0); + + + $results1=curl_multi_getcontent($ch1); //incorrect parameter type + $results2=curl_multi_getcontent($ch2); + + //CLOSE + //curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_multi_add_handle() expects parameter 2 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_multi_getcontent() expects parameter 1 to be resource, null given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_init_basic.phpt b/ext/curl/tests/curl_multi_init_basic.phpt new file mode 100644 index 0000000..0fd865d --- /dev/null +++ b/ext/curl/tests/curl_multi_init_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test curl_multi_init() +--CREDITS-- +Mark van der Velden +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php +/* Prototype : resource curl_multi_init(void) + * Description : Returns a new cURL multi handle + * Source code : ext/curl/multi.c + * Test documentation: http://wiki.php.net/qa/temp/ext/curl + */ + +// start testing +echo "*** Testing curl_multi_init(void); ***\n"; + +//create the multiple cURL handle +$mh = curl_multi_init(); +var_dump($mh); + +curl_multi_close($mh); +var_dump($mh); +?> +===DONE=== +--EXPECTF-- +*** Testing curl_multi_init(void); *** +resource(%d) of type (curl_multi) +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_multi_segfault.phpt b/ext/curl/tests/curl_multi_segfault.phpt new file mode 100644 index 0000000..dde8189 --- /dev/null +++ b/ext/curl/tests/curl_multi_segfault.phpt @@ -0,0 +1,56 @@ +--TEST-- +Segfault due to libcurl connection caching +--CREDITS-- +--SKIPIF-- +<?php +if (!extension_loaded("curl")) exit("skip curl extension not loaded"); +if (false === getenv('PHP_CURL_FTP_REMOTE_SERVER')) exit("skip PHP_CURL_FTP_REMOTE_SERVER env variable is not defined"); +if (false === getenv('PHP_CURL_FTP_REMOTE_USER')) exit("skip PHP_CURL_FTP_REMOTE_USER env variable is not defined"); +if (false === getenv('PHP_CURL_FTP_REMOTE_PASSWD')) exit("skip PHP_CURL_FTP_REMOTE_PASSWD env variable is not defined"); +?> +--FILE-- +<?php + $host = getenv('PHP_CURL_FTP_REMOTE_SERVER'); + $username = getenv('PHP_CURL_FTP_REMOTE_USER'); + $password = getenv('PHP_CURL_FTP_REMOTE_PASSWD'); + + // FTP this script to a server + $fp = fopen ( __FILE__ , "r" ); + $url = "ftp://$username:$password@$host/" ; + + $ch = curl_init (); + + curl_setopt ( $ch , CURLOPT_URL, $url ); + curl_setopt ( $ch , CURLOPT_RETURNTRANSFER, 1 ); + + //force passive connection + curl_setopt ( $ch , CURLOPT_FTP_USE_EPSV, 0 ); + curl_setopt ( $ch , CURLOPT_FTP_SKIP_PASV_IP, 1 ); + + $cmh = curl_multi_init(); + curl_multi_add_handle($cmh, $ch); + + $active = null; + + do { + $mrc = curl_multi_exec($cmh, $active); + } while ($mrc == CURLM_CALL_MULTI_PERFORM); + + + while ($active && $mrc == CURLM_OK) { + if (curl_multi_select($cmh) != -1) { + do { + $mrc = curl_multi_exec($cmh, $active); + } while ($mrc == CURLM_CALL_MULTI_PERFORM); + } + } + + var_dump(is_string(curl_multi_getcontent($ch))); + curl_multi_remove_handle($cmh, $ch); + curl_close($ch); + curl_multi_close($cmh); +?> +===DONE=== +--EXPECTF-- +bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_multi_select_basic1.phpt b/ext/curl/tests/curl_multi_select_basic1.phpt new file mode 100644 index 0000000..7ae8124 --- /dev/null +++ b/ext/curl/tests/curl_multi_select_basic1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test curl_multi_select() +--CREDITS-- +Ivo Jansch <ivo@ibuildings.com> +#testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php +/* Prototype : resource curl_multi_select($mh, $timeout=1.0]) + * Description : Get all the sockets associated with the cURL extension, which can then be + * "selected" + * Source code : ? + * Test documentation: http://wiki.php.net/qa/temp/ext/curl + */ + + +//create the multiple cURL handle +$mh = curl_multi_init(); +echo curl_multi_select($mh)."\n"; + +curl_multi_close($mh); +?> +===DONE=== +--EXPECTF-- +%r(0|-1)%r +===DONE=== diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt new file mode 100644 index 0000000..7a778f3 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt @@ -0,0 +1,22 @@ +--TEST-- +CURLOPT_FOLLOWLOCATION case check open_basedir +--CREDITS-- +WHITE new media architects - Dennis +--INI-- +open_basedir = DIRECTORY_SEPARATOR."tmp"; +--SKIPIF-- +<?php +if (!extension_loaded("curl")) print "skip cURL not loaded"; +?> +--FILE-- +<?php +print (ini_get("OPEN_BASEDIR")); +$ch = curl_init(); +$succes = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); +curl_close($ch); +var_dump($succes); +?> +--EXPECTF-- +Warning: curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set in %s.php on line %d +bool(false) + diff --git a/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt new file mode 100644 index 0000000..9de2c0f --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt @@ -0,0 +1,54 @@ +--TEST-- +cURL option CURLOPT_READFUNCTION +--CREDITS-- +WHITE new media architects - Jeroen Vermeulen +#testfest Utrecht 2009 +--SKIPIF-- +<?php +if (!extension_loaded("curl")) print "skip cURL extension not loaded"; +?> +--FILE-- +<?php +function custom_readfunction($oCurl, $hReadHandle, $iMaxOut) +{ + $sData = fread($hReadHandle,$iMaxOut-10); # -10 to have space to add "custom:" + if (!empty($sData)) + { + $sData = "custom:".$sData; + } + return $sData; +} + +$sFileBase = dirname(__FILE__).DIRECTORY_SEPARATOR.'curl_opt_CURLOPT_READFUNCTION'; +$sReadFile = $sFileBase.'_in.tmp'; +$sWriteFile = $sFileBase.'_out.tmp'; +$sWriteUrl = 'file://'.$sWriteFile; + +file_put_contents($sReadFile,'contents of tempfile'); +$hReadHandle = fopen($sReadFile, 'r'); + +$oCurl = curl_init(); +curl_setopt($oCurl, CURLOPT_URL, $sWriteUrl); +curl_setopt($oCurl, CURLOPT_UPLOAD, 1); +curl_setopt($oCurl, CURLOPT_READFUNCTION, "custom_readfunction" ); +curl_setopt($oCurl, CURLOPT_INFILE, $hReadHandle ); +curl_exec($oCurl); +curl_close($oCurl); + +fclose ($hReadHandle); + +$sOutput = file_get_contents($sWriteFile); +var_dump($sOutput); +?> +===DONE=== +--CLEAN-- +<?php +$sFileBase = dirname(__FILE__).DIRECTORY_SEPARATOR.'curl_opt_CURLOPT_READFUNCTION'; +$sReadFile = $sFileBase.'_in.tmp'; +$sWriteFile = $sFileBase.'_out.tmp'; +unlink($sReadFile); +unlink($sWriteFile); +?> +--EXPECT-- +string(27) "custom:contents of tempfile" +===DONE=== diff --git a/ext/curl/tests/curl_setopt_array_basic.phpt b/ext/curl/tests/curl_setopt_array_basic.phpt new file mode 100644 index 0000000..427de7f --- /dev/null +++ b/ext/curl/tests/curl_setopt_array_basic.phpt @@ -0,0 +1,56 @@ +--TEST-- +curl_setopt_array() function - tests setting multiple cURL options with curl_setopt_array() +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php +/* + * Prototype: bool curl_setopt_array(resource $ch, array $options) + * Description: Sets multiple options for a cURL session. + * Source: ext/curl/interface.c + * Documentation: http://wiki.php.net/qa/temp/ext/curl + */ + +// Figure out what handler to use +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); +if (!empty($host)) { + // Use the set Environment variable + $url = "{$host}/get.php?test=get"; +} else { + // Create a temporary file for the test + $tempname = tempnam(sys_get_temp_dir(), 'CURL_HANDLE'); + $url = 'file://'. $tempname; + // add the test data to the file + file_put_contents($tempname, "Hello World!\nHello World!"); +} + +// Start the test +echo '== Starting test curl_setopt_array($ch, $options); ==' . "\n"; + +// curl handler +$ch = curl_init(); + +// options for the curl handler +$options = array ( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => 1 +); + +ob_start(); // start output buffering + +curl_setopt_array($ch, $options); +$returnContent = curl_exec($ch); +curl_close($ch); + +var_dump($returnContent); +isset($tempname) and is_file($tempname) and @unlink($tempname); + +?> +--EXPECT-- +== Starting test curl_setopt_array($ch, $options); == +string(25) "Hello World! +Hello World!" + diff --git a/ext/curl/tests/curl_setopt_basic002.phpt b/ext/curl/tests/curl_setopt_basic002.phpt new file mode 100644 index 0000000..d90ecb7 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic002.phpt @@ -0,0 +1,52 @@ +--TEST-- +curl_setopt basic tests with CURLOPT_STDERR. +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + +// start testing +echo "*** Testing curl_setopt with CURLOPT_STDERR\n"; + +$temp_file = tempnam(sys_get_temp_dir(), 'CURL_STDERR'); + +$handle = fopen($temp_file, 'w'); + +$url = "{$host}/"; +$ch = curl_init(); + +curl_setopt($ch, CURLOPT_VERBOSE, 1); +curl_setopt($ch, CURLOPT_STDERR, $handle); +$curl_content = curl_exec($ch); + +fclose($handle); +unset($handle); +var_dump(preg_replace('/[\r\n]/', ' ', file_get_contents($temp_file))); +@unlink($temp_file); + +ob_start(); // start output buffering +$handle = fopen($temp_file, 'w'); +curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use +curl_setopt($ch, CURLOPT_STDERR, $handle); +$data = curl_exec($ch); +ob_end_clean(); + +fclose($handle); +unset($handle); +var_dump(preg_replace('/[\r\n]/', ' ', file_get_contents($temp_file))); +@unlink($temp_file); + +curl_close($ch); + +?> +--EXPECTF-- +*** Testing curl_setopt with CURLOPT_STDERR +string(%d) "%S" +string(%d) "%S" +* Closing connection #%d + diff --git a/ext/curl/tests/curl_setopt_basic003.phpt b/ext/curl/tests/curl_setopt_basic003.phpt new file mode 100644 index 0000000..7849140 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic003.phpt @@ -0,0 +1,43 @@ +--TEST-- +curl_setopt() call with CURLOPT_HTTPHEADER +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + +// start testing +echo "*** curl_setopt() call with CURLOPT_HTTPHEADER\n"; + +$url = "{$host}/"; +$ch = curl_init(); + +curl_setopt($ch, CURLOPT_HTTPHEADER, 1); + +$curl_content = curl_exec($ch); +curl_close($ch); + +var_dump( $curl_content ); + +$ch = curl_init(); + +ob_start(); // start output buffering +curl_setopt($ch, CURLOPT_HTTPHEADER, array()); +curl_setopt($ch, CURLOPT_URL, $host); + +$curl_content = curl_exec($ch); +ob_end_clean(); +curl_close($ch); + +var_dump( $curl_content ); +?> +--EXPECTF-- +*** curl_setopt() call with CURLOPT_HTTPHEADER + +Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments in %s on line %d +bool(false) +bool(true) diff --git a/ext/curl/tests/curl_setopt_basic004.phpt b/ext/curl/tests/curl_setopt_basic004.phpt new file mode 100644 index 0000000..97b4115 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic004.phpt @@ -0,0 +1,44 @@ +--TEST-- +curl_setopt() call with CURLOPT_RETURNTRANSFER +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- +<?php if (!extension_loaded("curl") || false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; ?> +--FILE-- +<?php + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + +// start testing +echo "*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 1\n"; + +$url = "{$host}/"; +$ch = curl_init(); + +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +curl_setopt($ch, CURLOPT_URL, $url); + +$curl_content = curl_exec($ch); +curl_close($ch); + +var_dump( $curl_content ); + +echo "*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 0\n"; + +$ch = curl_init(); + +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); +curl_setopt($ch, CURLOPT_URL, $url); +ob_start(); +$curl_content = curl_exec($ch); +ob_end_clean(); +curl_close($ch); + +var_dump( $curl_content ); +?> +--EXPECTF-- +*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 1 +string(%d) "%a" +*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 0 +bool(true) diff --git a/ext/curl/tests/curl_setopt_error.phpt b/ext/curl/tests/curl_setopt_error.phpt new file mode 100644 index 0000000..ad73318 --- /dev/null +++ b/ext/curl/tests/curl_setopt_error.phpt @@ -0,0 +1,45 @@ +--TEST-- +curl_setopt() basic parameter test +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php +echo "*** curl_setopt() call with incorrect parameters\n"; +$ch = curl_init(); +curl_setopt(); +curl_setopt(false); + +curl_setopt($ch); +curl_setopt($ch, false); +curl_setopt($ch, -1); +curl_setopt($ch, ''); +curl_setopt($ch, 1, false); + +curl_setopt(false, false, false); +curl_setopt($ch, '', false); +curl_setopt($ch, 1, ''); +curl_setopt($ch, -1, 0); +?> +--EXPECTF-- +*** curl_setopt() call with incorrect parameters + +Warning: curl_setopt() expects exactly 3 parameters, 0 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 1 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 1 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, boolean given in %s on line %d + +Warning: curl_setopt() expects parameter 2 to be long, %unicode_string_optional% given in %s on line %d + +Warning: curl_setopt(): Invalid curl configuration option in %scurl_setopt_error.php on line %d diff --git a/ext/curl/tests/curl_testdata1.txt b/ext/curl/tests/curl_testdata1.txt new file mode 100644 index 0000000..dc1e446 --- /dev/null +++ b/ext/curl/tests/curl_testdata1.txt @@ -0,0 +1 @@ +CURL1 diff --git a/ext/curl/tests/curl_testdata2.txt b/ext/curl/tests/curl_testdata2.txt new file mode 100644 index 0000000..3b9f76f --- /dev/null +++ b/ext/curl/tests/curl_testdata2.txt @@ -0,0 +1 @@ +CURL2 diff --git a/ext/curl/tests/curl_version_error.phpt b/ext/curl/tests/curl_version_error.phpt new file mode 100644 index 0000000..fb4793a --- /dev/null +++ b/ext/curl/tests/curl_version_error.phpt @@ -0,0 +1,35 @@ +--TEST--
+Test curl_version() function : error conditions
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ die('skip - curl extension not available in this build');
+}
+if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
+ echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable";
+}
+?>
+--FILE--
+<?php
+
+/* Prototype : array curl_version ([ int $age ] )
+ * Description: Returns information about the cURL version.
+ * Source code: ext/curl/interface.c
+*/
+
+echo "*** Testing curl_version() : error conditions ***\n";
+
+echo "\n-- Testing curl_version() function with more than expected no. of arguments --\n";
+$extra_arg = 10;
+var_dump( curl_version(1, $extra_arg) );
+
+?>
+===Done===
+--EXPECTF--
+*** Testing curl_version() : error conditions ***
+
+-- Testing curl_version() function with more than expected no. of arguments --
+
+Warning: curl_version() expects at most 1 parameter, 2 given in %s on line %d
+NULL
+===Done===
diff --git a/ext/curl/tests/curl_version_variation1.phpt b/ext/curl/tests/curl_version_variation1.phpt new file mode 100644 index 0000000..cd912c4 --- /dev/null +++ b/ext/curl/tests/curl_version_variation1.phpt @@ -0,0 +1,165 @@ +--TEST--
+Test curl_version() function : usage variations - test values for $ascii argument
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ echo "skip - curl extension not available in this build";
+}
+if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
+ echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable";
+}
+?>
+--FILE--
+<?php
+
+/* Prototype : array curl_version ([ int $age ] )
+ * Description: Returns information about the cURL version.
+ * Source code: ext/curl/interface.c
+*/
+
+echo "*** Testing curl_version() function: with unexpected inputs for 'age' argument ***\n";
+
+//get an unset variable
+$unset_var = 'string_val';
+unset($unset_var);
+
+//defining a class
+class sample {
+ public function __toString() {
+ return "sample object";
+ }
+}
+
+//getting the resource
+$file_handle = fopen(__FILE__, "r");
+
+// array with different values for $input
+$inputs = array (
+
+ // integer values
+ 0,
+ 1,
+ 255,
+ 256,
+ PHP_INT_MAX,
+ -PHP_INT_MAX,
+
+ // float values
+ 10.5,
+ -20.5,
+ 10.1234567e10,
+
+ // array values
+ array(),
+ array(0),
+ array(1, 2),
+
+ //string values
+ "ABC",
+ 'abc',
+ "2abc",
+
+ // boolean values
+ true,
+ false,
+ TRUE,
+ FALSE,
+
+ // null values
+ NULL,
+ null,
+
+ // objects
+ new sample(),
+
+ // resource
+ $file_handle,
+
+ // undefined variable
+ @$undefined_var,
+
+ // unset variable
+ @$unset_var
+);
+
+// loop through with each element of the $inputs array to test curl_version() function
+$count = 1;
+foreach($inputs as $input) {
+ echo "-- Iteration $count --\n";
+ var_dump( is_array(curl_version($input)) );
+ $count ++;
+}
+
+fclose($file_handle); //closing the file handle
+
+?>
+===Done===
+--EXPECTF--
+*** Testing curl_version() function: with unexpected inputs for 'age' argument ***
+-- Iteration 1 --
+bool(true)
+-- Iteration 2 --
+bool(true)
+-- Iteration 3 --
+bool(true)
+-- Iteration 4 --
+bool(true)
+-- Iteration 5 --
+bool(true)
+-- Iteration 6 --
+bool(true)
+-- Iteration 7 --
+bool(true)
+-- Iteration 8 --
+bool(true)
+-- Iteration 9 --
+bool(true)
+-- Iteration 10 --
+
+Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d
+bool(false)
+-- Iteration 11 --
+
+Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d
+bool(false)
+-- Iteration 12 --
+
+Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d
+bool(false)
+-- Iteration 13 --
+
+Warning: curl_version() expects parameter 1 to be long, string given in %s on line %d
+bool(false)
+-- Iteration 14 --
+
+Warning: curl_version() expects parameter 1 to be long, string given in %s on line %d
+bool(false)
+-- Iteration 15 --
+
+Notice: A non well formed numeric value encountered in %s on line %d
+bool(true)
+-- Iteration 16 --
+bool(true)
+-- Iteration 17 --
+bool(true)
+-- Iteration 18 --
+bool(true)
+-- Iteration 19 --
+bool(true)
+-- Iteration 20 --
+bool(true)
+-- Iteration 21 --
+bool(true)
+-- Iteration 22 --
+
+Warning: curl_version() expects parameter 1 to be long, object given in %s on line %d
+bool(false)
+-- Iteration 23 --
+
+Warning: curl_version() expects parameter 1 to be long, resource given in %s on line %d
+bool(false)
+-- Iteration 24 --
+bool(true)
+-- Iteration 25 --
+bool(true)
+===Done===
diff --git a/ext/curl/tests/curl_write_callback.phpt b/ext/curl/tests/curl_write_callback.phpt new file mode 100644 index 0000000..c0b733e --- /dev/null +++ b/ext/curl/tests/curl_write_callback.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test curl option CURLOPT_WRITEFUNCTION +--CREDITS-- +Mathieu Kooiman <mathieuk@gmail.com> +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file, passing the output into a callback. Tests the PHP_CURL_USER case in curl_write. +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +function curl_callback($curl_handle, $received_data) +{ + echo $received_data; + return strlen($received_data); +} + +$log_file = tempnam(sys_get_temp_dir(), 'php-curl-test'); + +$fp = fopen($log_file, 'w+'); +fwrite($fp, "test"); +fclose($fp); + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'curl_callback'); +curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); +curl_exec($ch); +curl_close($ch); + +// cleanup +unlink($log_file); + +?> +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_file.phpt b/ext/curl/tests/curl_write_file.phpt new file mode 100644 index 0000000..95d2b0e --- /dev/null +++ b/ext/curl/tests/curl_write_file.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test curl option CURLOPT_FILE +--CREDITS-- +Mathieu Kooiman <mathieuk@gmail.com> +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and store the output in another temporary file. Tests the PHP_CURL_FILE case in curl_write(). +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +$test_file = tempnam(sys_get_temp_dir(), 'php-curl-test'); +$log_file = tempnam(sys_get_temp_dir(), 'php-curl-test'); + +$fp = fopen($log_file, 'w+'); +fwrite($fp, "test"); +fclose($fp); + +$testfile_fp = fopen($test_file, 'w+'); + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_FILE, $testfile_fp); +curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); +curl_exec($ch); +curl_close($ch); + +fclose($testfile_fp); + +echo file_get_contents($test_file); + +// cleanup +unlink($test_file); +unlink($log_file); + +?> +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_return.phpt b/ext/curl/tests/curl_write_return.phpt new file mode 100644 index 0000000..1ddc551 --- /dev/null +++ b/ext/curl/tests/curl_write_return.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test curl option CURLOPT_RETURNTRANSFER +--CREDITS-- +Mathieu Kooiman <mathieuk@gmail.com> +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and have it return the content from curl_exec(). Tests the PHP_CURL_RETURN case +of curl_write(). +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +$log_file = tempnam(sys_get_temp_dir(), 'php-curl-test'); + +$fp = fopen($log_file, 'w+'); +fwrite($fp, "test"); +fclose($fp); + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); +$result = curl_exec($ch); +curl_close($ch); + +echo $result; + +// cleanup +unlink($log_file); + +?> +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_stdout.phpt b/ext/curl/tests/curl_write_stdout.phpt new file mode 100644 index 0000000..893b27e --- /dev/null +++ b/ext/curl/tests/curl_write_stdout.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl option CURLOPT_FILE with STDOUT handle +--CREDITS-- +Mathieu Kooiman <mathieuk@gmail.com> +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and store the output in another temporary file. Tests the PHP_CURL_FILE case in curl_write(). +--SKIPIF-- +<?php if (!extension_loaded("curl")) print "skip"; ?> +--FILE-- +<?php + +$log_file = tempnam(sys_get_temp_dir(), 'php-curl-test'); + +$fp = fopen($log_file, 'w+'); +fwrite($fp, "test"); +fclose($fp); + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_FILE, STDOUT); +curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); +curl_exec($ch); +curl_close($ch); + +// cleanup +unlink($log_file); + +?> +--EXPECT-- +test diff --git a/ext/curl/tests/curl_writeheader_callback.phpt b/ext/curl/tests/curl_writeheader_callback.phpt new file mode 100644 index 0000000..fa27363 --- /dev/null +++ b/ext/curl/tests/curl_writeheader_callback.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test curl option CURLOPT_HEADERFUNCTION +--CREDITS-- +Mathieu Kooiman <mathieuk@gmail.com> +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Hit the host identified by PHP_CURL_HTTP_REMOTE_SERVER and determine that the headers are sent to the callback specified for CURLOPT_HEADERFUNCTION. Different test servers specified for PHP_CURL_HTTP_REMOTE_SERVER might return different sets of headers. Just test for HTTP/1.1 200 OK. +--SKIPIF-- +<?php +if (!extension_loaded("curl")) { + echo "skip - curl extension not available in this build"; +} +if (!getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { + echo "skip need PHP_CURL_HTTP_REMOTE_SERVER environment variable"; +} +?> +--FILE-- +<?php + +function curl_header_callback($curl_handle, $data) +{ + if (strtolower(substr($data,0, 4)) == 'http') + echo $data; +} + +$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER'); + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'curl_header_callback'); +curl_setopt($ch, CURLOPT_URL, $host); +curl_exec($ch); +curl_close($ch); + +?> +--EXPECTF-- +HTTP/1.1 %d %s diff --git a/ext/curl/tests/responder/get.php b/ext/curl/tests/responder/get.php new file mode 100644 index 0000000..9e13d6a --- /dev/null +++ b/ext/curl/tests/responder/get.php @@ -0,0 +1,39 @@ +<?php + $test = isset($_GET['test']) ? $_GET['test'] : null; + switch($test) { + case 'post': + var_dump($_POST); + break; + case 'getpost': + var_dump($_GET); + var_dump($_POST); + break; + case 'referer': + echo $_SERVER['HTTP_REFERER']; + break; + case 'useragent': + echo $_SERVER['HTTP_USER_AGENT']; + break; + case 'httpversion': + echo $_SERVER['SERVER_PROTOCOL']; + break; + case 'cookie': + echo $_COOKIE['foo']; + break; + case 'encoding': + echo $_SERVER['HTTP_ACCEPT_ENCODING']; + break; + case 'contenttype': + header('Content-Type: text/plain;charset=utf-8'); + break; + case 'file': + if (isset($_FILES['file'])) { + echo $_FILES['file']['name'] . '|' . $_FILES['file']['type']; + } + break; + default: + echo "Hello World!\n"; + echo "Hello World!"; + break; + } +?> |