#ifdef HTTP_HAVE_CURL
+#if defined(ZTS) && defined(HTTP_HAVE_SSL)
+# if !defined(HAVE_OPENSSL_CRYPTO_H)
+# error "libcurl was compiled with OpenSSL support, but we have no openssl/crypto.h"
+# else
+# define HTTP_NEED_SSL
+# include <openssl/crypto.h>
+# endif
+#endif
+
#include "php_http.h"
#include "php_http_std_defs.h"
#include "php_http_api.h"
ZEND_EXTERN_MODULE_GLOBALS(http);
+#ifdef HTTP_NEED_SSL
+static inline void http_ssl_init(void);
+static inline void http_ssl_cleanup(void);
+#endif
+
+STATUS _http_request_global_init(INIT_FUNC_ARGS)
+{
+ if (CURLE_OK != curl_global_init(CURL_GLOBAL_ALL)) {
+ return FAILURE;
+ }
+
+#ifdef HTTP_NEED_SSL
+ {
+ curl_version_info_data *cvid = curl_version_info(CURLVERSION_NOW);
+ if (cvid && (cvid->features & CURL_VERSION_SSL)) {
+ http_ssl_init();
+ }
+ }
+#endif
+
+ return SUCCESS;
+}
+
+void _http_request_global_cleanup(TSRMLS_D)
+{
+ curl_global_cleanup();
+#ifdef HTTP_NEED_SSL
+ http_ssl_cleanup();
+#endif
+}
+
#ifndef HAVE_CURL_EASY_STRERROR
# define curl_easy_strerror(code) HTTP_G(request).error
#endif
static int http_curl_raw_callback(CURL *, curl_infotype, char *, size_t, void *);
static int http_curl_dummy_callback(char *data, size_t n, size_t l, void *s) { return n*l; }
-#define HTTP_CURL_CALLBACK_DATA(from, type, var) \
- http_curl_callback_ctx *__CTX = (http_curl_callback_ctx *) (from); \
- TSRMLS_FETCH_FROM_CTX(__CTX->tsrm_ctx); \
- type (var) = (type) (__CTX->data)
-
-#define http_curl_callback_data(data) _http_curl_callback_data((data) TSRMLS_CC)
-static http_curl_callback_ctx *_http_curl_callback_data(void *data TSRMLS_DC);
-
+/* {{{ http_request_callback_ctx http_request_callback_data(void *) */
+http_request_callback_ctx *_http_request_callback_data_ex(void *data, zend_bool cpy TSRMLS_DC)
+{
+ http_request_callback_ctx *ctx = emalloc(sizeof(http_request_callback_ctx));
+
+ TSRMLS_SET_CTX(ctx->tsrm_ctx);
+ ctx->data = data;
+
+ if (cpy) {
+ return http_request_data_copy(COPY_CONTEXT, ctx);
+ } else {
+ return ctx;
+ }
+}
+/* }}} */
/* {{{ void *http_request_data_copy(int, void *) */
void *_http_request_data_copy(int type, void *data TSRMLS_DC)
}
/* }}} */
-/* {{{ _http_request_data_free_context(http_curl_callback_ctx **) */
+/* {{{ _http_request_data_free_context(http_request_callback_ctx **) */
void _http_request_data_free_context(void *context)
{
- efree(*((http_curl_callback_ctx **) context));
+ efree(*((http_request_callback_ctx **) context));
}
/* }}} */
-/* {{{ _http_request_data_free_conv(http_curl_conv **) */
+/* {{{ _http_request_data_free_conv(http_request_conv **) */
void _http_request_data_free_conv(void *conv)
{
- efree(*((http_curl_conv **) conv));
+ efree(*((http_request_conv **) conv));
}
/* }}} */
if (zoption = http_curl_getopt(options, "onprogress", 0)) {
HTTP_CURL_OPT(NOPROGRESS, 0);
HTTP_CURL_OPT(PROGRESSFUNCTION, http_curl_progress_callback);
- HTTP_CURL_OPT(PROGRESSDATA, http_curl_callback_data(zoption));
+ HTTP_CURL_OPT(PROGRESSDATA, http_request_callback_data(zoption));
} else {
HTTP_CURL_OPT(NOPROGRESS, 1);
}
break;
case HTTP_REQUEST_BODY_UPLOADFILE:
- curl_easy_setopt(ch, CURLOPT_READDATA, http_curl_callback_data(body));
+ curl_easy_setopt(ch, CURLOPT_READDATA, http_request_callback_data(body));
curl_easy_setopt(ch, CURLOPT_INFILESIZE, body->size);
break;
/* {{{ void http_request_conv(CURL *, phpstr *, phpstr *) */
void _http_request_conv(CURL *ch, phpstr* response, phpstr *request TSRMLS_DC)
{
- http_curl_conv *conv = emalloc(sizeof(http_curl_conv));
+ http_request_conv *conv = emalloc(sizeof(http_request_conv));
conv->response = response;
conv->request = request;
conv->last_info = -1;
- HTTP_CURL_OPT(DEBUGDATA, http_curl_callback_data(http_request_data_copy(COPY_CONV, conv)));
+ HTTP_CURL_OPT(DEBUGDATA, http_request_callback_data(http_request_data_copy(COPY_CONV, conv)));
}
/* }}} */
/* {{{ static size_t http_curl_read_callback(void *, size_t, size_t, void *) */
static size_t http_curl_read_callback(void *data, size_t len, size_t n, void *s)
{
- HTTP_CURL_CALLBACK_DATA(s, http_request_body *, body);
+ HTTP_REQUEST_CALLBACK_DATA(s, http_request_body *, body);
if (body->type != HTTP_REQUEST_BODY_UPLOADFILE) {
return 0;
}
/* }}} */
-/* {{{ http_curl_callback_ctx http_curl_callback_data(void *) */
-static http_curl_callback_ctx *_http_curl_callback_data(void *data TSRMLS_DC)
-{
- http_curl_callback_ctx *ctx = emalloc(sizeof(http_curl_callback_ctx));
- TSRMLS_SET_CTX(ctx->tsrm_ctx);
- ctx->data = data;
- return http_request_data_copy(COPY_CONTEXT, ctx);
-}
-/* }}} */
-
/* {{{ static int http_curl_progress_callback(void *, double, double, double, double) */
static int http_curl_progress_callback(void *data, double dltotal, double dlnow, double ultotal, double ulnow)
{
zval *params_pass[4], params_local[4], retval;
- HTTP_CURL_CALLBACK_DATA(data, zval *, func);
+ HTTP_REQUEST_CALLBACK_DATA(data, zval *, func);
params_pass[0] = ¶ms_local[0];
params_pass[1] = ¶ms_local[1];
/* {{{ static int http_curl_raw_callback(CURL *, curl_infotype, char *, size_t, void *) */
static int http_curl_raw_callback(CURL *ch, curl_infotype type, char *data, size_t length, void *ctx)
{
- HTTP_CURL_CALLBACK_DATA(ctx, http_curl_conv *, conv);
+ HTTP_REQUEST_CALLBACK_DATA(ctx, http_request_conv *, conv);
+
+#if 0
+ fprintf(stderr, "DEBUG: %s\n", data);
+#endif
switch (type)
{
}
/* }}} */
-#endif
+#ifdef HTTP_NEED_SSL
+
+static MUTEX_T *http_ssl_mutex = NULL;
+
+static void http_ssl_lock(int mode, int n, const char * file, int line)
+{
+ if (mode & CRYPTO_LOCK) {
+ tsrm_mutex_lock(http_ssl_mutex[n]);
+ } else {
+ tsrm_mutex_unlock(http_ssl_mutex[n]);
+ }
+}
+
+static unsigned long http_ssl_id(void)
+{
+ return (unsigned long) tsrm_thread_id();
+}
+
+static inline void http_ssl_init(void)
+{
+ int i, c = CRYPTO_num_locks();
+ http_ssl_mutex = malloc(c * sizeof(MUTEX_T));
+
+ for (i = 0; i < c; ++i) {
+ http_ssl_mutex[i] = tsrm_mutex_alloc();
+ }
+
+ CRYPTO_set_id_callback(http_ssl_id);
+ CRYPTO_set_locking_callback(http_ssl_lock);
+}
+
+static inline void http_ssl_cleanup(void)
+{
+ if (http_ssl_mutex) {
+ int i, c = CRYPTO_num_locks();
+
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+
+ for (i = 0; i < c; ++i) {
+ tsrm_mutex_free(http_ssl_mutex[i]);
+ }
+
+ free(http_ssl_mutex);
+ http_ssl_mutex = NULL;
+ }
+}
+#endif /* HTTP_NEED_SSL */
+
+#endif /* HTTP_HAVE_CURL */
/*
* Local variables: