X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_request_api.c;h=b16957c6491f5a01c54d387e612c8383a4860b6d;hp=d9b1a2198a06067823881907a09bbad592407856;hb=03848def2b38db9a52ab905405d9ea9ffd130e85;hpb=5dca59e3a269c903b395d97abe831c0fc138b5b6 diff --git a/http_request_api.c b/http_request_api.c index d9b1a21..b16957c 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -22,15 +22,6 @@ #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 -# endif -#endif - #include "php_http.h" #include "php_http_std_defs.h" #include "php_http_api.h" @@ -49,23 +40,62 @@ #include +/* + * cruft for thread safe SSL crypto locks + */ +#if defined(ZTS) && defined(HTTP_HAVE_SSL) +# ifdef PHP_WIN32 +# define HTTP_NEED_SSL_TSL +# define HTTP_NEED_OPENSSL_TSL +# include +# else /* !PHP_WIN32 */ +# define HTTP_NEED_SSL_TSL +# if defined(HTTP_HAVE_OPENSSL) +# if defined(HAVE_OPENSSL_CRYPTO_H) +# define HTTP_NEED_OPENSSL_TSL +# include +# else +# warning \ + "libcurl was compiled with OpenSSL support, but configure could not find " \ + "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# elif defined(HTTP_HAVE_GNUTLS) +# if defined(HAVE_GCRYPT_H) +# define HTTP_NEED_GNUTLS_TSL +# include +# else +# warning \ + "libcurl was compiled with GnuTLS support, but configure could not find " \ + "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif +# else +# warning \ + "libcurl was compiled with SSL support, but configure could not determine which" \ + "library was used; thus no SSL crypto locking callbacks will be set, which may " \ + "cause random crashes on SSL requests" +# endif /* HTTP_HAVE_OPENSSL || HTTP_HAVE_GNUTLS */ +# endif /* PHP_WIN32 */ +#endif /* ZTS && HTTP_HAVE_SSL */ + ZEND_EXTERN_MODULE_GLOBALS(http); -#ifdef HTTP_NEED_SSL -static inline zend_bool http_ssl_init(void); +#ifdef HTTP_NEED_SSL_TSL +static inline void http_ssl_init(void); static inline void http_ssl_cleanup(void); #endif -STATUS _http_request_global_init(INIT_FUNC_ARGS) +PHP_MINIT_FUNCTION(http_request) { +#ifdef HTTP_NEED_SSL_TSL + http_ssl_init(); +#endif + if (CURLE_OK != curl_global_init(CURL_GLOBAL_ALL)) { return FAILURE; } -#ifdef HTTP_NEED_SSL - http_ssl_init(); -#endif - #if LIBCURL_VERSION_NUM >= 0x070a05 HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC); HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST); @@ -76,12 +106,13 @@ STATUS _http_request_global_init(INIT_FUNC_ARGS) return SUCCESS; } -void _http_request_global_cleanup(TSRMLS_D) +PHP_MSHUTDOWN_FUNCTION(http_request) { curl_global_cleanup(); -#ifdef HTTP_NEED_SSL +#ifdef HTTP_NEED_SSL_TSL http_ssl_cleanup(); #endif + return SUCCESS; } #ifndef HAVE_CURL_EASY_STRERROR @@ -433,9 +464,13 @@ PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, char } #endif - /* compress, empty string enables deflate and gzip */ + /* compress, empty string enables all supported if libcurl was build with zlib support */ if ((zoption = http_curl_getopt(options, "compress", IS_BOOL)) && Z_LVAL_P(zoption)) { +#if defined(HTTP_HAVE_ZLIB) || defined(HAVE_ZLIB) + HTTP_CURL_OPT(ENCODING, "gzip;q=1.0, deflate;q=0.5, *;q=0"); +#else HTTP_CURL_OPT(ENCODING, ""); +#endif } /* redirects, defaults to 0 */ @@ -537,8 +572,16 @@ PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, char /* lastmodified */ if (zoption = http_curl_getopt(options, "lastmodified", IS_LONG)) { - HTTP_CURL_OPT(TIMECONDITION, range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE); - HTTP_CURL_OPT(TIMEVALUE, Z_LVAL_P(zoption)); + if (Z_LVAL_P(zoption)) { + if (Z_LVAL_P(zoption) > 0) { + HTTP_CURL_OPT(TIMEVALUE, Z_LVAL_P(zoption)); + } else { + HTTP_CURL_OPT(TIMEVALUE, time(NULL) + Z_LVAL_P(zoption)); + } + HTTP_CURL_OPT(TIMECONDITION, range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE); + } else { + HTTP_CURL_OPT(TIMECONDITION, CURL_TIMECOND_NONE); + } } /* timeout, defaults to 0 */ @@ -739,14 +782,9 @@ PHP_HTTP_API void _http_request_info(CURL *ch, HashTable *info TSRMLS_DC) PHP_HTTP_API STATUS _http_request_ex(CURL *ch, http_request_method meth, char *url, http_request_body *body, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) { STATUS status; - zend_bool clean_curl; + zend_bool clean_curl = !ch; - if ((clean_curl = (!ch))) { - if (!(ch = curl_easy_init())) { - http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initialize curl."); - return FAILURE; - } - } + HTTP_CHECK_CURL_INIT(ch, curl_easy_init(), return FAILURE); status = ((SUCCESS == http_request_init(ch, meth, url, body, options)) && (SUCCESS == http_request_exec(ch, info, response, NULL))) ? SUCCESS : FAILURE; @@ -859,7 +897,7 @@ static inline zval *_http_curl_getopt_ex(HashTable *options, char *key, size_t k } /* }}} */ -#ifdef HTTP_NEED_SSL +#ifdef HTTP_NEED_OPENSSL_TSL static MUTEX_T *http_ssl_mutex = NULL; @@ -877,26 +915,18 @@ static unsigned long http_ssl_id(void) return (unsigned long) tsrm_thread_id(); } -static inline zend_bool http_ssl_init(void) +static inline void http_ssl_init(void) { - curl_version_info_data *cvid = curl_version_info(CURLVERSION_NOW); + int i, c = CRYPTO_num_locks(); - if (cvid && (cvid->features & CURL_VERSION_SSL)) { - 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); - - return 1; + http_ssl_mutex = malloc(c * sizeof(MUTEX_T)); + + for (i = 0; i < c; ++i) { + http_ssl_mutex[i] = tsrm_mutex_alloc(); } - return 0; + CRYPTO_set_id_callback(http_ssl_id); + CRYPTO_set_locking_callback(http_ssl_lock); } static inline void http_ssl_cleanup(void) @@ -915,7 +945,55 @@ static inline void http_ssl_cleanup(void) http_ssl_mutex = NULL; } } -#endif /* HTTP_NEED_SSL */ +#endif /* HTTP_NEED_OPENSSL_TSL */ + +#ifdef HTTP_NEED_GNUTLS_TSL + +static int http_ssl_mutex_create(void **m) +{ + if (*((MUTEX_T **) m) = tsrm_mutex_alloc()) { + return SUCCESS; + } else { + return FAILURE; + } +} + +static int http_ssl_mutex_destroy(void **m) +{ + tsrm_mutex_free(*((MUTEX_T **) m)); + return SUCCESS; +} + +static int http_ssl_mutex_lock(void **m) +{ + return tsrm_mutex_lock(*((MUTEX_T **) m)); +} + +static int http_ssl_mutex_unlock(void **m) +{ + return tsrm_mutex_unlock(*((MUTEX_T **) m)); +} + +static struct gcry_thread_cbs http_ssl_callbacks = { + GCRY_THREAD_OPTIONS_USER, + NULL, + http_ssl_mutex_create, + http_ssl_mutex_destroy, + http_ssl_mutex_lock, + http_ssl_mutex_unlock +}; + +static inline void http_ssl_init(void) +{ + gcry_control(GCRYCTL_SET_THREAD_CBS, &http_ssl_callbacks); +} + +static inline void http_ssl_cleanup(void) +{ + return; +} + +#endif /* HTTP_NEED_GNUTLS_TSL */ static inline void _http_curl_defaults(CURL *ch) { @@ -944,6 +1022,7 @@ static inline void _http_curl_defaults(CURL *ch) HTTP_CURL_OPT(COOKIEJAR, NULL); HTTP_CURL_OPT(RESUME_FROM, 0); HTTP_CURL_OPT(MAXFILESIZE, 0); + HTTP_CURL_OPT(TIMECONDITION, 0); HTTP_CURL_OPT(TIMEVALUE, 0); HTTP_CURL_OPT(TIMEOUT, 0); HTTP_CURL_OPT(CONNECTTIMEOUT, 3);