diff options
-rw-r--r-- | ext/curl/curl.c | 1212 | ||||
-rw-r--r-- | ext/curl/php_curl.h | 49 |
2 files changed, 721 insertions, 540 deletions
diff --git a/ext/curl/curl.c b/ext/curl/curl.c index d4685b4121..627ea59370 100644 --- a/ext/curl/curl.c +++ b/ext/curl/curl.c @@ -23,36 +23,27 @@ #if HAVE_CURL -/* Standard Includes */ #include <stdio.h> #include <string.h> -#include <sys/stat.h> - -#if HAVE_UNISTD_H -#include <unistd.h> -#endif #ifdef PHP_WIN32 #include <winsock.h> #include <sys/types.h> -#define fstat(handle, buff) _fstat(handle, buff) -#define stat _stat #endif -/* CURL Includes */ #include <curl/curl.h> #include <curl/easy.h> -/* PHP Includes */ #include "ext/standard/info.h" #include "ext/standard/file.h" #include "php_curl.h" -static int le_curl; +static int le_curl; +static char le_curl_name[] = "cURL handle"; static void _php_curl_close(zend_rsrc_list_entry *rsrc); -#define SAVE_CURL_ERROR(__handle, __err) \ - __handle->cerrno = (int)__err; + +#define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err; #ifdef PHP_WIN32 /* {{{ win32_cleanup() @@ -95,11 +86,7 @@ function_entry curl_functions[] = { PHP_FE(curl_version, NULL) PHP_FE(curl_setopt, NULL) PHP_FE(curl_exec, NULL) -#if LIBCURL_VERSION_NUM >= 0x070401 PHP_FE(curl_getinfo, NULL) -#else - PHP_FALIAS(curl_getinfo, warn_not_available, NULL) -#endif PHP_FE(curl_error, NULL) PHP_FE(curl_errno, NULL) PHP_FE(curl_close, NULL) @@ -129,129 +116,147 @@ PHP_MINFO_FUNCTION(curl) php_info_print_table_end(); } +#define REGISTER_CURL_CONSTANT(name, value) REGISTER_LONG_CONSTANT(name, value, CONST_CS | CONST_PERSISTENT) + PHP_MINIT_FUNCTION(curl) { le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); /* Constants for curl_setopt() */ - REGISTER_LONG_CONSTANT("CURLOPT_PORT", CURLOPT_PORT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FILE", CURLOPT_FILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_INFILE", CURLOPT_INFILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_INFILESIZE", CURLOPT_INFILESIZE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_URL", CURLOPT_URL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_PROXY", CURLOPT_PROXY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_VERBOSE", CURLOPT_VERBOSE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_HEADER", CURLOPT_HEADER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_NOBODY", CURLOPT_NOBODY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FAILONERROR", CURLOPT_FAILONERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_UPLOAD", CURLOPT_UPLOAD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_POST", CURLOPT_POST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_NETRC", CURLOPT_NETRC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FTPASCII", CURLOPT_FTPASCII, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_PUT", CURLOPT_PUT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_MUTE", CURLOPT_MUTE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_USERPWD", CURLOPT_USERPWD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_RANGE", CURLOPT_RANGE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_TIMEOUT", CURLOPT_TIMEOUT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_REFERER", CURLOPT_REFERER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_USERAGENT", CURLOPT_USERAGENT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_FTPPORT", CURLOPT_FTPPORT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_COOKIE", CURLOPT_COOKIE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_SSLCERT", CURLOPT_SSLCERT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_WRITEHEADER", CURLOPT_WRITEHEADER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_SSLVERSION", CURLOPT_SSLVERSION, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_STDERR", CURLOPT_STDERR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_RETURNTRANSFER", CURLOPT_RETURNTRANSFER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_QUOTE", CURLOPT_QUOTE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE, CONST_CS | CONST_PERSISTENT); -#if LIBCURL_VERSION_NUM >= 0x070300 - REGISTER_LONG_CONSTANT("CURLOPT_INTERFACE", CURLOPT_INTERFACE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CONST_CS | CONST_PERSISTENT); -#endif + REGISTER_CURL_CONSTANT("CURLOPT_PORT", CURLOPT_PORT); + REGISTER_CURL_CONSTANT("CURLOPT_FILE", CURLOPT_FILE); + REGISTER_CURL_CONSTANT("CURLOPT_INFILE", CURLOPT_INFILE); + REGISTER_CURL_CONSTANT("CURLOPT_INFILESIZE", CURLOPT_INFILESIZE); + REGISTER_CURL_CONSTANT("CURLOPT_URL", CURLOPT_URL); + REGISTER_CURL_CONSTANT("CURLOPT_PROXY", CURLOPT_PROXY); + REGISTER_CURL_CONSTANT("CURLOPT_VERBOSE", CURLOPT_VERBOSE); + REGISTER_CURL_CONSTANT("CURLOPT_HEADER", CURLOPT_HEADER); + REGISTER_CURL_CONSTANT("CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER); + REGISTER_CURL_CONSTANT("CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS); + REGISTER_CURL_CONSTANT("CURLOPT_NOBODY", CURLOPT_NOBODY); + REGISTER_CURL_CONSTANT("CURLOPT_FAILONERROR", CURLOPT_FAILONERROR); + REGISTER_CURL_CONSTANT("CURLOPT_UPLOAD", CURLOPT_UPLOAD); + REGISTER_CURL_CONSTANT("CURLOPT_POST", CURLOPT_POST); + REGISTER_CURL_CONSTANT("CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY); + REGISTER_CURL_CONSTANT("CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND); + REGISTER_CURL_CONSTANT("CURLOPT_NETRC", CURLOPT_NETRC); + REGISTER_CURL_CONSTANT("CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION); + REGISTER_CURL_CONSTANT("CURLOPT_FTPASCII", CURLOPT_FTPASCII); + REGISTER_CURL_CONSTANT("CURLOPT_PUT", CURLOPT_PUT); + REGISTER_CURL_CONSTANT("CURLOPT_MUTE", CURLOPT_MUTE); + REGISTER_CURL_CONSTANT("CURLOPT_USERPWD", CURLOPT_USERPWD); + REGISTER_CURL_CONSTANT("CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD); + REGISTER_CURL_CONSTANT("CURLOPT_RANGE", CURLOPT_RANGE); + REGISTER_CURL_CONSTANT("CURLOPT_TIMEOUT", CURLOPT_TIMEOUT); + REGISTER_CURL_CONSTANT("CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS); + REGISTER_CURL_CONSTANT("CURLOPT_REFERER", CURLOPT_REFERER); + REGISTER_CURL_CONSTANT("CURLOPT_USERAGENT", CURLOPT_USERAGENT); + REGISTER_CURL_CONSTANT("CURLOPT_FTPPORT", CURLOPT_FTPPORT); + REGISTER_CURL_CONSTANT("CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT); + REGISTER_CURL_CONSTANT("CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME); + REGISTER_CURL_CONSTANT("CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM); + REGISTER_CURL_CONSTANT("CURLOPT_COOKIE", CURLOPT_COOKIE); + REGISTER_CURL_CONSTANT("CURLOPT_SSLCERT", CURLOPT_SSLCERT); + REGISTER_CURL_CONSTANT("CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD); + REGISTER_CURL_CONSTANT("CURLOPT_WRITEHEADER", CURLOPT_WRITEHEADER); + REGISTER_CURL_CONSTANT("CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE); + REGISTER_CURL_CONSTANT("CURLOPT_SSLVERSION", CURLOPT_SSLVERSION); + REGISTER_CURL_CONSTANT("CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION); + REGISTER_CURL_CONSTANT("CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE); + REGISTER_CURL_CONSTANT("CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST); + REGISTER_CURL_CONSTANT("CURLOPT_STDERR", CURLOPT_STDERR); + REGISTER_CURL_CONSTANT("CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT); + REGISTER_CURL_CONSTANT("CURLOPT_RETURNTRANSFER", CURLOPT_RETURNTRANSFER); + REGISTER_CURL_CONSTANT("CURLOPT_QUOTE", CURLOPT_QUOTE); + REGISTER_CURL_CONSTANT("CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE); + REGISTER_CURL_CONSTANT("CURLOPT_INTERFACE", CURLOPT_INTERFACE); + REGISTER_CURL_CONSTANT("CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL); + REGISTER_CURL_CONSTANT("CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL); + REGISTER_CURL_CONSTANT("CURLOPT_FILETIME", CURLOPT_FILETIME); + REGISTER_CURL_CONSTANT("CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION); + REGISTER_CURL_CONSTANT("CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS); + REGISTER_CURL_CONSTANT("CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS); + REGISTER_CURL_CONSTANT("CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY); + REGISTER_CURL_CONSTANT("CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT); + REGISTER_CURL_CONSTANT("CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE); + REGISTER_CURL_CONSTANT("CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE); + REGISTER_CURL_CONSTANT("CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET); + REGISTER_CURL_CONSTANT("CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT); + REGISTER_CURL_CONSTANT("CURLOPT_SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER); + REGISTER_CURL_CONSTANT("CURLOPT_CAINFO", CURLOPT_CAINFO); + + /* Constants effecting the way CURLOPT_CLOSEPOLICY works */ + REGISTER_CURL_CONSTANT("CURLCLOSEPOLICY_LEAST_RECENTLY_USED", CURLCLOSEPOLICY_LEAST_RECENTLY_USED); + REGISTER_CURL_CONSTANT("CURLCLOSEPOLICY_OLDEST", CURLCLOSEPOLICY_OLDEST); - -#if LIBCURL_VERSION_NUM >= 0x070401 /* Info constants */ - REGISTER_LONG_CONSTANT("CURLINFO_EFFECTIVE_URL", CURLINFO_EFFECTIVE_URL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_HTTP_CODE", CURLINFO_HTTP_CODE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_HEADER_SIZE", CURLINFO_HEADER_SIZE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_REQUEST_SIZE", CURLINFO_REQUEST_SIZE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_TOTAL_TIME", CURLINFO_TOTAL_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_NAMELOOKUP_TIME", CURLINFO_NAMELOOKUP_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_CONNECT_TIME", CURLINFO_CONNECT_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_PRETRANSFER_TIME", CURLINFO_PRETRANSFER_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_SIZE_UPLOAD", CURLINFO_SIZE_UPLOAD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_SIZE_DOWNLOAD", CURLINFO_SIZE_DOWNLOAD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_SPEED_DOWNLOAD", CURLINFO_SPEED_DOWNLOAD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLINFO_SPEED_UPLOAD", CURLINFO_SPEED_UPLOAD, CONST_CS | CONST_PERSISTENT); - -#endif + REGISTER_CURL_CONSTANT("CURLINFO_EFFECTIVE_URL", CURLINFO_EFFECTIVE_URL); + REGISTER_CURL_CONSTANT("CURLINFO_HTTP_CODE", CURLINFO_HTTP_CODE); + REGISTER_CURL_CONSTANT("CURLINFO_HEADER_SIZE", CURLINFO_HEADER_SIZE); + REGISTER_CURL_CONSTANT("CURLINFO_REQUEST_SIZE", CURLINFO_REQUEST_SIZE); + REGISTER_CURL_CONSTANT("CURLINFO_TOTAL_TIME", CURLINFO_TOTAL_TIME); + REGISTER_CURL_CONSTANT("CURLINFO_NAMELOOKUP_TIME", CURLINFO_NAMELOOKUP_TIME); + REGISTER_CURL_CONSTANT("CURLINFO_CONNECT_TIME", CURLINFO_CONNECT_TIME); + REGISTER_CURL_CONSTANT("CURLINFO_PRETRANSFER_TIME", CURLINFO_PRETRANSFER_TIME); + REGISTER_CURL_CONSTANT("CURLINFO_SIZE_UPLOAD", CURLINFO_SIZE_UPLOAD); + REGISTER_CURL_CONSTANT("CURLINFO_SIZE_DOWNLOAD", CURLINFO_SIZE_DOWNLOAD); + REGISTER_CURL_CONSTANT("CURLINFO_SPEED_DOWNLOAD", CURLINFO_SPEED_DOWNLOAD); + REGISTER_CURL_CONSTANT("CURLINFO_SPEED_UPLOAD", CURLINFO_SPEED_UPLOAD); + REGISTER_CURL_CONSTANT("CURLINFO_FILETIME", CURLINFO_FILETIME); /* Error Constants */ - REGISTER_LONG_CONSTANT("CURLE_OK", CURLE_OK, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FAILED_INIT", CURLE_FAILED_INIT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_WRITE_ERROR", CURLE_WRITE_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_READ_ERROR", CURLE_READ_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("CURL_LAST", CURL_LAST, CONST_CS | CONST_PERSISTENT); - + REGISTER_CURL_CONSTANT("CURLE_OK", CURLE_OK); + REGISTER_CURL_CONSTANT("CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL); + REGISTER_CURL_CONSTANT("CURLE_FAILED_INIT", CURLE_FAILED_INIT); + REGISTER_CURL_CONSTANT("CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT); + REGISTER_CURL_CONSTANT("CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER); + REGISTER_CURL_CONSTANT("CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY); + REGISTER_CURL_CONSTANT("CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST); + REGISTER_CURL_CONSTANT("CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT); + REGISTER_CURL_CONSTANT("CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY); + REGISTER_CURL_CONSTANT("CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED); + REGISTER_CURL_CONSTANT("CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT); + REGISTER_CURL_CONSTANT("CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY); + REGISTER_CURL_CONSTANT("CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY); + REGISTER_CURL_CONSTANT("CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY); + REGISTER_CURL_CONSTANT("CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT); + REGISTER_CURL_CONSTANT("CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST); + REGISTER_CURL_CONSTANT("CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY); + REGISTER_CURL_CONSTANT("CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE); + REGISTER_CURL_CONSTANT("CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR); + REGISTER_CURL_CONSTANT("CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR); + REGISTER_CURL_CONSTANT("CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND); + REGISTER_CURL_CONSTANT("CURLE_WRITE_ERROR", CURLE_WRITE_ERROR); + REGISTER_CURL_CONSTANT("CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE); + REGISTER_CURL_CONSTANT("CURLE_READ_ERROR", CURLE_READ_ERROR); + REGISTER_CURL_CONSTANT("CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY); + REGISTER_CURL_CONSTANT("CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII); + REGISTER_CURL_CONSTANT("CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST); + REGISTER_CURL_CONSTANT("CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE); + REGISTER_CURL_CONSTANT("CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR); + REGISTER_CURL_CONSTANT("CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR); + REGISTER_CURL_CONSTANT("CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR); + REGISTER_CURL_CONSTANT("CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME); + REGISTER_CURL_CONSTANT("CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE); + REGISTER_CURL_CONSTANT("CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND); + REGISTER_CURL_CONSTANT("CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED); + REGISTER_CURL_CONSTANT("CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND); + REGISTER_CURL_CONSTANT("CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND); + REGISTER_CURL_CONSTANT("CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK); + REGISTER_CURL_CONSTANT("CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT); + REGISTER_CURL_CONSTANT("CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER); + REGISTER_CURL_CONSTANT("CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED); + REGISTER_CURL_CONSTANT("CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED); + REGISTER_CURL_CONSTANT("CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS); + REGISTER_CURL_CONSTANT("CURLE_UNKOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION); + REGISTER_CURL_CONSTANT("CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX); + REGISTER_CURL_CONSTANT("CURLE_ALREADY_COMPLETE", CURLE_ALREADY_COMPLETE); + if (win32_init() != CURLE_OK) { return FAILURE; } @@ -265,10 +270,204 @@ PHP_MSHUTDOWN_FUNCTION(curl) return SUCCESS; } -static void curl_free_string(void **string) { +#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 + +static size_t curl_write(void *ctx, char *data, size_t size, size_t nmemb, FILE *fp) +{ + php_curl *ch = (php_curl *) ctx; + php_curl_write *t = ch->write; + size_t length = size * nmemb; + + switch (t->method) { + case PHP_CURL_FILE: + return fwrite(data, size, nmemb, fp); + case PHP_CURL_RETURN: + case PHP_CURL_STDOUT: + smart_str_appendl(&t->buf, data, (int) length); + break; + case PHP_CURL_USER: { + zval *argv[2]; + zval *retval; + int error; + ELS_FETCH(); + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(retval); + + ZVAL_RESOURCE(argv[0], ch->id); + zend_list_addref(ch->id); + ZVAL_STRINGL(argv[1], data, (int) length, 1); + + error = call_user_function(EG(function_table), + NULL, + t->func, + retval, 2, argv); + if (error == FAILURE) { + php_error(E_WARNING, "Cannot call the CURLOPT_WRITEFUNCTION"); + return -1; + } + + length = Z_LVAL_P(retval); + + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&retval); + + break; + } + } + + return length; +} + +static size_t curl_read(void *ctx, char *data, size_t size, size_t nmemb, FILE *fp) +{ + php_curl *ch = (php_curl *) ctx; + php_curl_read *t = ch->read; + int length = -1; + + switch (t->method) { + case PHP_CURL_DIRECT: + length = fread(data, size, nmemb, fp); + case PHP_CURL_USER: { + zval *argv[3]; + zval *retval; + int length; + int error; + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(argv[2]); + MAKE_STD_ZVAL(retval); + + ZVAL_RESOURCE(argv[0], ch->id); + zend_list_addref(ch->id); + ZVAL_RESOURCE(argv[1], t->fd); + zend_list_addref(t->fd); + ZVAL_LONG(argv[2], size * nmemb); + + error = call_user_function(EG(function_table), + NULL, + t->func, + retval, 3, argv); + if (error == FAILURE) { + php_error(E_WARNING, "Cannot call the CURLOPT_READFUNCTION"); + break; + } + + data = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + length = Z_STRLEN_P(retval); + + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&argv[2]); + zval_ptr_dtor(&retval); + + break; + } + } + + return length; +} + +static size_t _php_curl_write_header(void *ctx, char *data, size_t size, size_t nmemb, FILE *fp) +{ + php_curl *ch = (php_curl *) ctx; + zval *func = ch->handlers->write_header; + zval *argv[2]; + zval *retval; + int error; + int length; + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(retval); + + ZVAL_RESOURCE(argv[0], ch->id); + zend_list_addref(ch->id); + ZVAL_STRINGL(argv[0], data, size * nmemb, 1); + + error = call_user_function(EG(function_table), + NULL, + func, + retval, 2, argv); + if (error == FAILURE) { + php_error(E_WARNING, "Couldn't call the CURLOPT_HEADERFUNCTION"); + return -1; + } + + length = Z_LVAL_P(retval); + + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&retval); + + return length; +} + +static size_t _php_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; + int error; + + 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); + if (error == FAILURE) { + php_error(E_WARNING, "Couldn't call the CURLOPT_PASSWDFUNCTION"); + return -1; + } + + if (Z_STRLEN_P(retval) > buflen) { + php_error(E_WARNING, "Returned password is too long for libcurl to handle"); + return -1; + } + + strncpy(buf, Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&argv[2]); + zval_ptr_dtor(&retval); + + return 0; +} + + + +static void curl_free_string(void **string) +{ efree(*string); } +static void curl_free_post(void **post) +{ + curl_formfree((struct HttpPost *) *post); +} + +static void curl_free_slist(void **slist) +{ + curl_slist_free_all((struct curl_slist *) *slist); +} + /* {{{ proto string curl_version(void) Return the CURL version string. */ PHP_FUNCTION(curl_version) @@ -281,43 +480,57 @@ PHP_FUNCTION(curl_version) Initialize a CURL session */ PHP_FUNCTION(curl_init) { - zval **url; - php_curl *curl_handle = NULL; - int argc = ZEND_NUM_ARGS(); - + zval **url; + php_curl *ch; + int argc = ZEND_NUM_ARGS(); + if (argc < 0 || argc > 1 || zend_get_parameters_ex(argc, &url) == FAILURE) { WRONG_PARAM_COUNT; } - - curl_handle = (php_curl *)emalloc(sizeof(php_curl)); - memset(curl_handle, 0, sizeof(php_curl)); - - zend_llist_init(&curl_handle->to_free, sizeof(char *), (void(*)(void *))curl_free_string, 0); - curl_handle->cp = curl_easy_init(); - if (!curl_handle->cp) { - php_error(E_ERROR, "Cannot initialize CURL Handle"); + ch = emalloc(sizeof(php_curl)); + ch->write = emalloc(sizeof(php_curl_write)); + ch->read = emalloc(sizeof(php_curl_read)); + ch->handlers = emalloc(sizeof(php_curl_handlers)); + memset(ch->write, 0, sizeof(php_curl_write)); + memset(ch->read, 0, sizeof(php_curl_read)); + memset(ch->handlers, 0, sizeof(php_curl_handlers)); + + zend_llist_init(&ch->to_free.str, sizeof(char *), + (void(*)(void *)) curl_free_string, 0); + zend_llist_init(&ch->to_free.slist, sizeof(struct curl_slist), + (void(*)(void *)) curl_free_slist, 0); + zend_llist_init(&ch->to_free.post, sizeof(struct HttpPost), + (void(*)(void *)) curl_free_post, 0); + + ch->cp = curl_easy_init(); + if (! ch->cp) { + php_error(E_WARNING, "Cannot initialize a new cURL handle"); RETURN_FALSE; } - + + ch->write->method = PHP_CURL_STDOUT; + ch->read->method = PHP_CURL_DIRECT; + + 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_WRITEFUNCTIONDATA, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read); + curl_easy_setopt(ch->cp, CURLOPT_READFUNCTIONDATA, (void *) ch); if (argc > 0) { - char *urlstr; + char *urlcopy; convert_to_string_ex(url); - urlstr = estrndup(Z_STRVAL_PP(url), Z_STRLEN_PP(url)); - curl_easy_setopt(curl_handle->cp, CURLOPT_URL, urlstr); - zend_llist_add_element(&curl_handle->to_free, &urlstr); + urlcopy = estrndup(Z_STRVAL_PP(url), Z_STRLEN_PP(url)); + curl_easy_setopt(ch->cp, CURLOPT_URL, urlcopy); + zend_llist_add_element(&ch->to_free.str, &urlcopy); } - curl_easy_setopt(curl_handle->cp, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(curl_handle->cp, CURLOPT_VERBOSE, 0); - curl_easy_setopt(curl_handle->cp, CURLOPT_ERRORBUFFER, curl_handle->error); - - curl_handle->output_file = 0; - curl_handle->php_stdout = 1; - - ZEND_REGISTER_RESOURCE(return_value, curl_handle, le_curl); + ZEND_REGISTER_RESOURCE(return_value, ch, le_curl); + ch->id = Z_LVAL_P(return_value); } /* }}} */ @@ -325,227 +538,223 @@ PHP_FUNCTION(curl_init) Set an option for a CURL transfer */ PHP_FUNCTION(curl_setopt) { - zval **curl_id, - **curl_option, - **curl_value; - php_curl *curl_handle; - CURLcode ret; - int option; + zval **zid, + **zoption, + **zvalue; + php_curl *ch; + CURLcode error; + int option; if (ZEND_NUM_ARGS() != 3 || - zend_get_parameters_ex(3, &curl_id, &curl_option, &curl_value) == FAILURE) { + zend_get_parameters_ex(3, &zid, &zoption, &zvalue) == FAILURE) { WRONG_PARAM_COUNT; } + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); + convert_to_long_ex(zoption); - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); + option = Z_LVAL_PP(zoption); + switch (option) { + 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_FOLLOWLOCATION: + case CURLOPT_PUT: + case CURLOPT_MUTE: + case CURLOPT_TIMEOUT: + 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: + case CURLOPT_SSL_VERIFYPEER: + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; + 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_SSLCERT: + case CURLOPT_SSLCERTPASSWD: + case CURLOPT_COOKIEFILE: + case CURLOPT_REFERER: + case CURLOPT_INTERFACE: + case CURLOPT_KRB4LEVEL: + case CURLOPT_RANDOM_FILE: + case CURLOPT_EGDSOCKET: + case CURLOPT_CAINFO: { + char *copystr = NULL; - convert_to_long_ex(curl_option); - option = Z_LVAL_PP(curl_option); + convert_to_string_ex(zvalue); + 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); + + break; + } + case CURLOPT_FILE: + case CURLOPT_INFILE: + case CURLOPT_WRITEHEADER: + case CURLOPT_STDERR: { + FILE *fp; + ZEND_FETCH_RESOURCE(fp, FILE *, zvalue, -1, "File-Handle", php_file_le_fopen()); + + error = curl_easy_setopt(ch->cp, option, fp); + if (option == CURLOPT_FILE) { + ch->write->method = PHP_CURL_FILE; + } + + if (option == CURLOPT_INFILE) { + ch->read->fd = Z_LVAL_PP(zvalue); + } + + break; + } + case CURLOPT_RETURNTRANSFER: + convert_to_long_ex(zvalue); + + if (Z_LVAL_PP(zvalue)) { + ch->write->method = PHP_CURL_RETURN; + } + break; + case CURLOPT_WRITEFUNCTION: + zval_add_ref(zvalue); + ch->write->func = *zvalue; + ch->write->method = PHP_CURL_USER; + break; + case CURLOPT_READFUNCTION: + zval_add_ref(zvalue); + ch->read->func = *zvalue; + ch->read->method = PHP_CURL_USER; + break; + case CURLOPT_HEADERFUNCTION: + zval_add_ref(zvalue); + ch->handlers->write_header = *zvalue; + error = curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, _php_curl_write_header); + error = curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTIONDATA, (void *) ch); + break; + case CURLOPT_PASSWDFUNCTION: + zval_add_ref(zvalue); + ch->handlers->passwd = *zvalue; + error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, _php_curl_passwd); + error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch); + break; + 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; - switch (option) { - 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_FOLLOWLOCATION: - case CURLOPT_PUT: case CURLOPT_MUTE: case CURLOPT_TIMEOUT: - 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: -#if LIBCURL_VERSION_NUM >= 0x070300 - case CURLOPT_HTTPPROXYTUNNEL: -#endif - - convert_to_long_ex(curl_value); - ret = curl_easy_setopt(curl_handle->cp, option, Z_LVAL_PP(curl_value)); - break; - - 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_SSLCERT: case CURLOPT_SSLCERTPASSWD: case CURLOPT_COOKIEFILE: - case CURLOPT_REFERER: -#if LIBCURL_VERSION_NUM >= 0x070300 - case CURLOPT_INTERFACE: case CURLOPT_KRB4LEVEL: -#endif - - { - char *copystr = NULL; - - convert_to_string_ex(curl_value); - copystr = estrndup(Z_STRVAL_PP(curl_value), Z_STRLEN_PP(curl_value)); - - ret = curl_easy_setopt(curl_handle->cp, option, copystr); - zend_llist_add_element(&curl_handle->to_free, ©str); - } - break; - - case CURLOPT_FILE: - case CURLOPT_INFILE: - case CURLOPT_WRITEHEADER: - case CURLOPT_STDERR: - - { - FILE *fp; - - ZEND_FETCH_RESOURCE(fp, FILE *, curl_value, -1, "File-Handle", php_file_le_fopen()); - ret = curl_easy_setopt(curl_handle->cp, option, fp); - - if (option & CURLOPT_FILE) { - curl_handle->output_file = Z_LVAL_PP(curl_value); - curl_handle->php_stdout = 0; - } + postfields = HASH_OF(*zvalue); + if (! postfields) { + php_error(E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS"); + RETURN_FALSE; } - break; - - case CURLOPT_RETURNTRANSFER: - - convert_to_long_ex(curl_value); - - curl_handle->return_transfer = Z_LVAL_PP(curl_value); - curl_handle->php_stdout = !Z_LVAL_PP(curl_value); - break; - - case CURLOPT_POSTFIELDS: - - if (Z_TYPE_PP(curl_value) == IS_ARRAY || - Z_TYPE_PP(curl_value) == IS_OBJECT) { - - zval **current; - HashTable *u_post = HASH_OF(*curl_value); - struct HttpPost *first = NULL, - *last = NULL; - - for (zend_hash_internal_pointer_reset(u_post); - zend_hash_get_current_data(u_post, (void **)¤t) == SUCCESS; - zend_hash_move_forward(u_post)) { - - char *string_key = NULL, - *str = NULL, - *val_str = NULL; - ulong num_key; - - SEPARATE_ZVAL(current); - convert_to_string_ex(current); - - if (zend_hash_get_current_key(u_post, &string_key, &num_key, 0) == HASH_KEY_IS_LONG) { - string_key = emalloc(20); - sprintf(string_key, "%d", num_key); - } - - val_str = estrndup(Z_STRVAL_PP(current), Z_STRLEN_PP(current)); - - str = emalloc(strlen(string_key) + strlen(val_str) + 1 + 2); - sprintf(str, "%s=%s", string_key, val_str); + for (zend_hash_internal_pointer_reset(postfields); + zend_hash_get_current_data(postfields, (void **) ¤t) == SUCCESS; + zend_hash_move_forward(postfields)) { + char *string_key = NULL; + char *postval = NULL; + ulong num_key; - ret = curl_formparse(str, &first, &last); + SEPARATE_ZVAL(current); + convert_to_string_ex(current); - efree(string_key); - efree(val_str); - } - - if (ret != CURLE_OK) { - SAVE_CURL_ERROR(curl_handle, ret); - RETURN_FALSE; - } - - ret = curl_easy_setopt(curl_handle->cp, CURLOPT_HTTPPOST, first); - } else { - - char *post_str = NULL; + zend_hash_get_current_key(postfields, &string_key, &num_key, 0); - convert_to_string_ex(curl_value); - post_str = estrndup(Z_STRVAL_PP(curl_value), Z_STRLEN_PP(curl_value)); + postval = emalloc(strlen(string_key) + Z_STRLEN_PP(current) + 1); + sprintf(postval, "%s=%s", string_key, Z_STRVAL_PP(current)); - ret = curl_easy_setopt(curl_handle->cp, CURLOPT_POSTFIELDS, post_str); -#if LIBCURL_VERSION_NUM >= 0x070300 - ret = curl_easy_setopt(curl_handle->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(curl_value)); -#endif - if (ret != CURLE_OK) { - SAVE_CURL_ERROR(curl_handle, ret); - RETURN_FALSE; - } - - ret = curl_easy_setopt(curl_handle->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(curl_value)); - break; - + error = curl_formparse(postval, &first, &last); } - break; - - case CURLOPT_HTTPHEADER: - - { - zval **current; - HashTable *headers = HASH_OF(*curl_value); - struct curl_slist *header = NULL; - - if (!headers) { - RETURN_FALSE; - } - - for (zend_hash_internal_pointer_reset(headers); - zend_hash_get_current_data(headers, (void **)¤t) == SUCCESS; - zend_hash_move_forward(headers)) { - char *indiv_header = NULL; - - SEPARATE_ZVAL(current); - convert_to_string_ex(current); - - indiv_header = estrndup(Z_STRVAL_PP(current), Z_STRLEN_PP(current)); - header = curl_slist_append(header, indiv_header); - if (!header) { - php_error(E_WARNING, "Couldn't build header from %s()", get_active_function_name()); - efree(indiv_header); - RETURN_FALSE; - } - - } - - ret = curl_easy_setopt(curl_handle->cp, CURLOPT_HTTPHEADER, header); + + if (error != CURLE_OK) { + SAVE_CURL_ERROR(ch, error); + RETURN_FALSE; } - break; - - case CURLOPT_QUOTE: - case CURLOPT_POSTQUOTE: - - { - zval **current; - HashTable *php_commands = HASH_OF(*curl_value); - struct curl_slist *commands = NULL; - - if (!php_commands) { - RETURN_FALSE; - } - - for (zend_hash_internal_pointer_reset(php_commands); - zend_hash_get_current_data(php_commands, (void **)¤t) == SUCCESS; - zend_hash_move_forward(php_commands)) { - char *indiv_command = NULL; - - SEPARATE_ZVAL(current); - convert_to_string_ex(current); - - if (Z_STRLEN_PP(current) < 1) { - continue; - } - - indiv_command = estrndup(Z_STRVAL_PP(current), Z_STRLEN_PP(current)); - commands = curl_slist_append(commands, indiv_command); - if (!commands) { - php_error(E_WARNING, "Couldn't build command list from %s()", get_active_function_name()); - efree(indiv_command); - RETURN_FALSE; - } - - } - - ret = curl_easy_setopt(curl_handle->cp, option, commands); + + zend_llist_add_element(&ch->to_free.post, &first); + error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, &first); + } + 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)); + } + + break; + case CURLOPT_HTTPHEADER: + case CURLOPT_QUOTE: + case CURLOPT_POSTQUOTE: { + zval **current; + HashTable *hash; + struct curl_slist *slist = NULL; + + hash = HASH_OF(*zvalue); + if (! hash) { + php_error(E_WARNING, + "You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE and CURLOPT_POSTQUOTE arguments"); + RETURN_FALSE; + } + + for (zend_hash_internal_pointer_reset(hash); + zend_hash_get_current_data(hash, (void **) ¤t) == SUCCESS; + zend_hash_move_forward(hash)) { + char *indiv = NULL; + + SEPARATE_ZVAL(current); + convert_to_string_ex(current); + + indiv = estrndup(Z_STRVAL_PP(current), Z_STRLEN_PP(current)); + slist = curl_slist_append(slist, indiv); + if (! slist) { + efree(indiv); + php_error(E_WARNING, "Couldn't build curl_slist from curl_setopt()"); + RETURN_FALSE; } - break; + zend_llist_add_element(&ch->to_free.str, &indiv); + } + zend_llist_add_element(&ch->to_free.slist, &slist); + + error = curl_easy_setopt(ch->cp, option, slist); + + break; + } } - if (ret != CURLE_OK) { - SAVE_CURL_ERROR(curl_handle, ret); + if (error != CURLE_OK) { + SAVE_CURL_ERROR(ch, error); RETURN_FALSE; } else { RETURN_TRUE; @@ -557,209 +766,142 @@ PHP_FUNCTION(curl_setopt) Perform a CURL session */ PHP_FUNCTION(curl_exec) { - zval **curl_id; - php_curl *curl_handle; - CURLcode ret; - FILE *fp; - char buf[4096]; - int b, - is_temp_file; - unsigned long pos = 0; - + zval **zid; + php_curl *ch; + CURLcode error; + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &curl_id) == FAILURE) { + zend_get_parameters_ex(1, &zid) == FAILURE) { WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); - - if ((curl_handle->return_transfer && - !curl_handle->output_file) || curl_handle->php_stdout) { - - if ((fp = tmpfile()) == NULL) { - php_error(E_WARNING, "Cannot initialize temporary file to save output from %s()", get_active_function_name()); - RETURN_FALSE; - } - curl_handle->tmp_fp = fp; - - curl_easy_setopt(curl_handle->cp, CURLOPT_FILE, fp); - - is_temp_file = 1; - - } else if (curl_handle->return_transfer && - curl_handle->output_file) { - - ZEND_FETCH_RESOURCE(fp, FILE *, (zval **) NULL, curl_handle->output_file, "File-Handle", php_file_le_fopen()); + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); + error = curl_easy_perform(ch->cp); + if (error != CURLE_OK) { + SAVE_CURL_ERROR(ch, error); + RETURN_FALSE; } - - ret = curl_easy_perform(curl_handle->cp); - - if ((!curl_handle->return_transfer && !curl_handle->php_stdout) || - (ret != CURLE_OK)) { - - if (ret != CURLE_OK) { - SAVE_CURL_ERROR(curl_handle, ret); - RETVAL_FALSE; - } else { - RETVAL_TRUE; - } - - if (fp && is_temp_file) - fclose(fp); - return; + if (ch->write->method == PHP_CURL_RETURN) { + smart_str_0(&ch->write->buf); + RETURN_STRINGL(ch->write->buf.c, ch->write->buf.len, 1); + smart_str_free(&ch->write->buf); } - - fseek(fp, 0, SEEK_SET); - - if (curl_handle->php_stdout) { - - while ((b = fread(buf, 1, sizeof(buf), fp)) > 0) { - php_write(buf, b); - } - - if (is_temp_file) - fclose(fp); - - } else { - - char *ret_data; - struct stat stat_sb; - - if (fstat(fileno(fp), &stat_sb)) { - if (is_temp_file) { - fclose(fp); - } - RETURN_FALSE; - } - - ret_data = (char *) emalloc(stat_sb.st_size + 1); - - while ((b = fread(buf, 1, sizeof(buf), fp)) > 0) { - memcpy(ret_data + pos, buf, b); - pos += b; - } - ret_data[stat_sb.st_size] = '\0'; - - if (is_temp_file) - fclose(fp); - - RETURN_STRINGL(ret_data, stat_sb.st_size + 1, 0); - + else if (ch->write->method == PHP_CURL_STDOUT) { + smart_str_0(&ch->write->buf); + PUTS(ch->write->buf.c); + smart_str_free(&ch->write->buf); } + RETURN_TRUE; } /* }}} */ -#if LIBCURL_VERSION_NUM >= 0x070401 /* {{{ proto string curl_getinfo(int ch, int opt) Get information regarding a specific transfer */ PHP_FUNCTION(curl_getinfo) { - zval **curl_id, **curl_opt; - php_curl *curl_handle; - int opt, - argc = ZEND_NUM_ARGS(); - + zval **zid, + **zoption; + php_curl *ch; + int option, + argc = ZEND_NUM_ARGS(); + if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &curl_id, &curl_opt) == FAILURE) { + zend_get_parameters_ex(argc, &zid, &zoption) == FAILURE) { WRONG_PARAM_COUNT; } - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); if (argc < 2) { - char *url; - long l_code; - double d_code; + char *url; + long l_code; + double d_code; array_init(return_value); - curl_easy_getinfo(curl_handle->cp, CURLINFO_EFFECTIVE_URL, &url); + curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_URL, &url); add_assoc_string(return_value, "url", url, 1); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_HTTP_CODE, &l_code); + curl_easy_getinfo(ch->cp, CURLINFO_HTTP_CODE, &l_code); add_assoc_long(return_value, "http_code", l_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_HEADER_SIZE, &l_code); + curl_easy_getinfo(ch->cp, CURLINFO_HEADER_SIZE, &l_code); add_assoc_long(return_value, "header_size", l_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_REQUEST_SIZE, &l_code); + curl_easy_getinfo(ch->cp, CURLINFO_REQUEST_SIZE, &l_code); add_assoc_long(return_value, "request_size", l_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_TOTAL_TIME, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_FILETIME, &l_code); + add_assoc_long(return_value, "filetime", l_code); + curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME, &d_code); add_assoc_double(return_value, "total_time", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_NAMELOOKUP_TIME, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME, &d_code); add_assoc_double(return_value, "namelookup_time", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_CONNECT_TIME, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME, &d_code); add_assoc_double(return_value, "connect_time", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_PRETRANSFER_TIME, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME, &d_code); add_assoc_double(return_value, "pretransfer_time", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_SIZE_UPLOAD, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD, &d_code); add_assoc_double(return_value, "size_upload", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_SIZE_DOWNLOAD, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code); add_assoc_double(return_value, "size_download", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_SPEED_DOWNLOAD, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code); add_assoc_double(return_value, "speed_download", d_code); - - curl_easy_getinfo(curl_handle->cp, CURLINFO_SPEED_UPLOAD, &d_code); + curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD, &d_code); add_assoc_double(return_value, "speed_upload", d_code); } else { - opt = Z_LVAL_PP(curl_opt); - switch (opt) { - case CURLINFO_EFFECTIVE_URL: - { - char *url; - - curl_easy_getinfo(curl_handle->cp, opt, &url); - - RETURN_STRING(url, 1); - } - break; - case CURLINFO_HTTP_CODE: case CURLINFO_HEADER_SIZE: case CURLINFO_REQUEST_SIZE: - { - long code; + option = Z_LVAL_PP(zoption); + switch (option) { + case CURLINFO_EFFECTIVE_URL: { + char *url; + + curl_easy_getinfo(ch->cp, option, &url); + RETURN_STRING(url, 1); + + break; + } + case CURLINFO_HTTP_CODE: + case CURLINFO_HEADER_SIZE: + case CURLINFO_REQUEST_SIZE: + case CURLINFO_FILETIME: { + long code; - curl_easy_getinfo(curl_handle->cp, opt, &code); - RETURN_LONG(code); - } - break; - 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: - { - double code; + curl_easy_getinfo(ch->cp, option, &code); + RETURN_LONG(code); + + break; + } + 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: { + double code; - curl_easy_getinfo(curl_handle->cp, opt, &code); - RETURN_DOUBLE(code); - } - break; + curl_easy_getinfo(ch->cp, option, &code); + RETURN_DOUBLE(code); + + break; + } } } } /* }}} */ -#endif /* {{{ proto string curl_error(int ch) Return a string contain the last error for the current session */ PHP_FUNCTION(curl_error) { - zval **curl_id; - php_curl *curl_handle; + zval **zid; + php_curl *ch; if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &curl_id) == FAILURE) { + zend_get_parameters_ex(1, &zid) == FAILURE) { WRONG_PARAM_COUNT; } + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); - RETURN_STRING(curl_handle->error, 1); + RETURN_STRING(ch->err.str, 1); } /* }}} */ @@ -767,16 +909,16 @@ PHP_FUNCTION(curl_error) Return an integer containing the last error number */ PHP_FUNCTION(curl_errno) { - zval **curl_id; - php_curl *curl_handle; - + zval **zid; + php_curl *ch; + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &curl_id) == FAILURE) { + zend_get_parameters_ex(1, &zid) == FAILURE) { WRONG_PARAM_COUNT; } - - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); - RETURN_LONG(curl_handle->cerrno); + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); + + RETURN_LONG(ch->err.no); } /* }}} */ @@ -784,17 +926,16 @@ PHP_FUNCTION(curl_errno) Close a CURL session */ PHP_FUNCTION(curl_close) { - zval **curl_id; - php_curl *curl_handle; - + zval **zid; + php_curl *ch; + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &curl_id) == FAILURE) { + zend_get_parameters_ex(1, &zid) == FAILURE) { WRONG_PARAM_COUNT; } + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); - ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl); - - zend_list_delete(Z_LVAL_PP(curl_id)); + zend_list_delete(Z_LVAL_PP(zid)); } /* }}} */ @@ -802,12 +943,23 @@ PHP_FUNCTION(curl_close) List destructor for curl handles */ static void _php_curl_close(zend_rsrc_list_entry *rsrc) { - php_curl *curl_handle = (php_curl *)rsrc->ptr; - curl_easy_cleanup(curl_handle->cp); - if (curl_handle->tmp_fp) fclose(curl_handle->tmp_fp); - zend_llist_clean(&curl_handle->to_free); - efree(curl_handle); -} + php_curl *ch = (php_curl *) rsrc->ptr; + + curl_easy_cleanup(ch->cp); + zend_llist_clean(&ch->to_free.str); + zend_llist_clean(&ch->to_free.slist); + zend_llist_clean(&ch->to_free.post); + + if (ch->write->func) zval_ptr_dtor(&ch->write->func); + if (ch->read->func) zval_ptr_dtor(&ch->read->func); + if (ch->handlers->write_header) zval_ptr_dtor(&ch->handlers->write_header); + if (ch->handlers->passwd) zval_ptr_dtor(&ch->handlers->passwd); + + efree(ch->write); + efree(ch->read); + efree(ch->handlers); + efree(ch); +} /* }}} */ #endif diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 58ee10aa2b..326318e75a 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -21,6 +21,9 @@ #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 @@ -30,6 +33,7 @@ #include <curl/curl.h> + extern zend_module_entry curl_module_entry; #define curl_module_ptr &curl_module_entry @@ -42,22 +46,47 @@ PHP_FUNCTION(curl_version); PHP_FUNCTION(curl_init); PHP_FUNCTION(curl_setopt); PHP_FUNCTION(curl_exec); -#if LIBCURL_VERSION_NUM >= 0x070401 PHP_FUNCTION(curl_getinfo); -#endif PHP_FUNCTION(curl_error); PHP_FUNCTION(curl_errno); PHP_FUNCTION(curl_close); typedef struct { - int return_transfer; - int output_file; - int php_stdout; - int cerrno; - char error[CURL_ERROR_SIZE+1]; - FILE *tmp_fp; - CURL *cp; - zend_llist to_free; + zval *func; + smart_str buf; + int method; +} php_curl_write; + +typedef struct { + zval *func; + long fd; + int method; +} php_curl_read; + +typedef struct { + zval *write_header; + zval *passwd; +} php_curl_handlers; + +struct _php_curl_error { + char str[CURL_ERROR_SIZE + 1]; + int no; +}; + +struct _php_curl_free { + zend_llist str; + zend_llist post; + zend_llist slist; +}; + +typedef struct { + CURL *cp; + php_curl_write *write; + php_curl_read *read; + php_curl_handlers *handlers; + struct _php_curl_error err; + struct _php_curl_free to_free; + long id; } php_curl; |