mirror of
https://github.com/php/php-src.git
synced 2025-01-08 20:17:28 +08:00
a59a85b598
Return the proper amount.
808 lines
28 KiB
C
808 lines
28 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP version 4.0 |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 1997-2001 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 2.02 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available at through the world-wide-web at |
|
|
| http://www.php.net/license/2_02.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$ */
|
|
|
|
|
|
#include "php.h"
|
|
|
|
#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 void _php_curl_close(zend_rsrc_list_entry *rsrc);
|
|
#define SAVE_CURL_ERROR(__handle, __err) \
|
|
__handle->cerrno = (int)__err;
|
|
|
|
#ifdef PHP_WIN32
|
|
/* {{{ win32_cleanup()
|
|
Clean-up allocated socket data on win32 systems */
|
|
static void win32_cleanup()
|
|
{
|
|
WSACleanup();
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ win32_init()
|
|
Initialize WSA stuff on Win32 systems */
|
|
static CURLcode win32_init()
|
|
{
|
|
WSADATA wsa_data;
|
|
WORD requested_version = MAKEWORD(1, 1);
|
|
int error;
|
|
|
|
error = WSAStartup(requested_version, wsa_data);
|
|
if (error != 0) {
|
|
return CURLE_FAILED_INIT;
|
|
}
|
|
|
|
if (LOBYTE(wsa_data.wVersion) != 1 || HIBYTE(wsa_data.wVersion) != 1) {
|
|
WSACleanup();
|
|
return CURLE_FAILED_INIT;
|
|
}
|
|
|
|
return CURLE_OK;
|
|
}
|
|
/* }}} */
|
|
#else
|
|
static CURLcode win32_init(void) { return CURLE_OK; }
|
|
#define win32_cleanup()
|
|
#endif
|
|
|
|
|
|
function_entry curl_functions[] = {
|
|
PHP_FE(curl_init, NULL)
|
|
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)
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
zend_module_entry curl_module_entry = {
|
|
"curl",
|
|
curl_functions,
|
|
PHP_MINIT(curl),
|
|
PHP_MSHUTDOWN(curl),
|
|
NULL,
|
|
NULL,
|
|
PHP_MINFO(curl),
|
|
STANDARD_MODULE_PROPERTIES
|
|
};
|
|
|
|
#ifdef COMPILE_DL_CURL
|
|
ZEND_GET_MODULE (curl)
|
|
#endif
|
|
|
|
PHP_MINFO_FUNCTION(curl)
|
|
{
|
|
php_info_print_table_start();
|
|
php_info_print_table_row(2, "CURL support", "enabled");
|
|
php_info_print_table_row(2, "CURL Information", curl_version());
|
|
php_info_print_table_end();
|
|
}
|
|
|
|
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
|
|
|
|
|
|
#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
|
|
|
|
/* 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);
|
|
|
|
if (win32_init() != CURLE_OK) {
|
|
return FAILURE;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_MSHUTDOWN_FUNCTION(curl)
|
|
{
|
|
win32_cleanup();
|
|
return SUCCESS;
|
|
}
|
|
|
|
static void curl_free_string(void **string) {
|
|
efree(*string);
|
|
}
|
|
|
|
/* {{{ proto string curl_version(void)
|
|
Return the CURL version string. */
|
|
PHP_FUNCTION(curl_version)
|
|
{
|
|
RETURN_STRING(curl_version(), 1);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto int curl_init([string url])
|
|
Initialize a CURL session */
|
|
PHP_FUNCTION(curl_init)
|
|
{
|
|
zval **url;
|
|
php_curl *curl_handle = NULL;
|
|
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");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (argc > 0) {
|
|
char *urlstr;
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto bool curl_setopt(int ch, string option, mixed value)
|
|
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;
|
|
|
|
if (ZEND_NUM_ARGS() != 3 ||
|
|
zend_get_parameters_ex(3, &curl_id, &curl_option, &curl_value) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl);
|
|
|
|
convert_to_long_ex(curl_option);
|
|
option = Z_LVAL_PP(curl_option);
|
|
|
|
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;
|
|
}
|
|
}
|
|
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);
|
|
|
|
ret = curl_formparse(str, &first, &last);
|
|
|
|
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;
|
|
|
|
convert_to_string_ex(curl_value);
|
|
post_str = estrndup(Z_STRVAL_PP(curl_value), Z_STRLEN_PP(curl_value));
|
|
|
|
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;
|
|
|
|
}
|
|
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);
|
|
}
|
|
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);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (ret != CURLE_OK) {
|
|
SAVE_CURL_ERROR(curl_handle, ret);
|
|
RETURN_FALSE;
|
|
} else {
|
|
RETURN_TRUE;
|
|
}
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto bool curl_exec(int ch)
|
|
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;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 ||
|
|
zend_get_parameters_ex(1, &curl_id) == 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_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());
|
|
|
|
}
|
|
|
|
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);
|
|
RETURN_FALSE;
|
|
} else {
|
|
RETURN_TRUE;
|
|
}
|
|
|
|
if (fp && is_temp_file)
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
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)) {
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
/* }}} */
|
|
|
|
#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();
|
|
|
|
if (argc < 1 || argc > 2 ||
|
|
zend_get_parameters_ex(argc, &curl_id, &curl_opt) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl);
|
|
|
|
if (argc < 2) {
|
|
char *url;
|
|
long l_code;
|
|
double d_code;
|
|
|
|
array_init(return_value);
|
|
|
|
curl_easy_getinfo(curl_handle->cp, CURLINFO_EFFECTIVE_URL, &url);
|
|
add_assoc_string(return_value, "url", url, 1);
|
|
|
|
curl_easy_getinfo(curl_handle->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);
|
|
add_assoc_long(return_value, "header_size", l_code);
|
|
|
|
curl_easy_getinfo(curl_handle->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);
|
|
add_assoc_double(return_value, "total_time", d_code);
|
|
|
|
curl_easy_getinfo(curl_handle->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);
|
|
add_assoc_double(return_value, "connect_time", d_code);
|
|
|
|
curl_easy_getinfo(curl_handle->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);
|
|
add_assoc_double(return_value, "size_upload", d_code);
|
|
|
|
curl_easy_getinfo(curl_handle->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);
|
|
add_assoc_double(return_value, "speed_download", d_code);
|
|
|
|
curl_easy_getinfo(curl_handle->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;
|
|
|
|
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(curl_handle->cp, opt, &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;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 ||
|
|
zend_get_parameters_ex(1, &curl_id) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl);
|
|
RETURN_STRING(curl_handle->error, 1);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto int curl_errno(int ch)
|
|
Return an integer containing the last error number */
|
|
PHP_FUNCTION(curl_errno)
|
|
{
|
|
zval **curl_id;
|
|
php_curl *curl_handle;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 ||
|
|
zend_get_parameters_ex(1, &curl_id) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl);
|
|
RETURN_LONG(curl_handle->cerrno);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto void curl_close(int ch)
|
|
Close a CURL session */
|
|
PHP_FUNCTION(curl_close)
|
|
{
|
|
zval **curl_id;
|
|
php_curl *curl_handle;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 ||
|
|
zend_get_parameters_ex(1, &curl_id) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(curl_handle, php_curl *, curl_id, -1, "CURL Handle", le_curl);
|
|
|
|
zend_list_delete(Z_LVAL_PP(curl_id));
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ _php_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);
|
|
zend_llist_clean(&curl_handle->to_free);
|
|
efree(curl_handle);
|
|
}
|
|
/* }}} */
|
|
|
|
#endif
|