diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 index e549330c50c..e3d1d51cccd 100644 --- a/ext/curl/config.m4 +++ b/ext/curl/config.m4 @@ -5,10 +5,6 @@ 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 @@ -145,10 +141,6 @@ int main(int argc, char *argv[]) $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 share.c streams.c curl_file.c, $ext_shared) + PHP_NEW_EXTENSION(curl, interface.c multi.c share.c curl_file.c, $ext_shared) PHP_SUBST(CURL_SHARED_LIBADD) fi diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 index 5acda7ec9e9..a481e294863 100644 --- a/ext/curl/config.w32 +++ b/ext/curl/config.w32 @@ -20,7 +20,6 @@ if (PHP_CURL != "no") { AC_DEFINE('HAVE_CURL_MULTI_STRERROR', 1, 'Have curl_multi_strerror 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/interface.c b/ext/curl/interface.c index a2256ef30dc..2d541403173 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1221,25 +1221,6 @@ PHP_MINIT_FUNCTION(curl) return FAILURE; } -#ifdef PHP_CURL_URL_WRAPPERS - REGISTER_LONG_CONSTANT("CURL_WRAPPERS_ENABLED", 1, CONST_CS | CONST_PERSISTENT); - { - 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 - REGISTER_LONG_CONSTANT("CURL_WRAPPERS_ENABLED", 0, CONST_CS | CONST_PERSISTENT); -#endif - curlfile_register_class(TSRMLS_C); return SUCCESS; @@ -1250,20 +1231,6 @@ PHP_MINIT_FUNCTION(curl) */ PHP_MSHUTDOWN_FUNCTION(curl) { -#ifdef PHP_CURL_URL_WRAPPERS - { - 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); - } - (void) *p++; - } - } -#endif curl_global_cleanup(); #ifdef PHP_CURL_NEED_OPENSSL_TSL if (php_curl_openssl_tsl) { diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index c4222c05883..9e98fe57cdc 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -200,38 +200,6 @@ 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; - void curlfile_register_class(TSRMLS_D); PHP_CURL_API extern zend_class_entry *curl_CURLFile_class; diff --git a/ext/curl/streams.c b/ext/curl/streams.c deleted file mode 100644 index 2683ae08808..00000000000 --- a/ext/curl/streams.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | 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 | - +----------------------------------------------------------------------+ -*/ - -/* $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 -#include - -#ifdef PHP_WIN32 -#include -#include -#endif - -#include -#include - -#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/standard/basic_functions.c b/ext/standard/basic_functions.c index 3a84d16d687..9c91404eff0 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -3680,10 +3680,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper TSRMLS_CC); #endif php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper TSRMLS_CC); -#ifndef PHP_CURL_URL_WRAPPERS php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC); php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC); -#endif #if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) # if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS @@ -3713,10 +3711,8 @@ PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */ #endif php_unregister_url_stream_wrapper("php" TSRMLS_CC); -#ifndef PHP_CURL_URL_WRAPPERS php_unregister_url_stream_wrapper("http" TSRMLS_CC); php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); -#endif BASIC_MSHUTDOWN_SUBMODULE(browscap) BASIC_MSHUTDOWN_SUBMODULE(array)