PHP_MINIT_FUNCTION(http_request)
{
#ifdef HTTP_NEED_OPENSSL_TSL
- int i, c = CRYPTO_num_locks();
-
- http_openssl_tsl = malloc(c * sizeof(MUTEX_T));
-
- for (i = 0; i < c; ++i) {
- http_openssl_tsl[i] = tsrm_mutex_alloc();
+ /* mod_ssl, libpq or ext/curl might already have set thread lock callbacks */
+ if (!CRYPTO_get_id_callback()) {
+ int i, c = CRYPTO_num_locks();
+
+ http_openssl_tsl = malloc(c * sizeof(MUTEX_T));
+
+ for (i = 0; i < c; ++i) {
+ http_openssl_tsl[i] = tsrm_mutex_alloc();
+ }
+
+ CRYPTO_set_id_callback(http_openssl_thread_id);
+ CRYPTO_set_locking_callback(http_openssl_thread_lock);
}
-
- CRYPTO_set_id_callback(http_openssl_thread_id);
- CRYPTO_set_locking_callback(http_openssl_thread_lock);
#endif
#ifdef HTTP_NEED_GNUTLS_TSL
gcry_control(GCRYCTL_SET_THREAD_CBS, &http_gnutls_tsl);
HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC);
HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST);
HTTP_LONG_CONSTANT("HTTP_AUTH_NTLM", CURLAUTH_NTLM);
+ HTTP_LONG_CONSTANT("HTTP_AUTH_GSSNEG", CURLAUTH_GSSNEGOTIATE);
HTTP_LONG_CONSTANT("HTTP_AUTH_ANY", CURLAUTH_ANY);
- HTTP_LONG_CONSTANT("HTTP_VERSION_NONE", CURL_HTTP_VERSION_NONE);
+ HTTP_LONG_CONSTANT("HTTP_VERSION_NONE", CURL_HTTP_VERSION_NONE); /* to be removed */
HTTP_LONG_CONSTANT("HTTP_VERSION_1_0", CURL_HTTP_VERSION_1_0);
HTTP_LONG_CONSTANT("HTTP_VERSION_1_1", CURL_HTTP_VERSION_1_1);
+ HTTP_LONG_CONSTANT("HTTP_VERSION_ANY", CURL_HTTP_VERSION_NONE);
+
+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_TLSv1", CURL_SSLVERSION_TLSv1);
+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_SSLv2", CURL_SSLVERSION_SSLv2);
+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_SSLv3", CURL_SSLVERSION_SSLv3);
+ HTTP_LONG_CONSTANT("HTTP_SSL_VERSION_ANY", CURL_SSLVERSION_DEFAULT);
HTTP_LONG_CONSTANT("HTTP_IPRESOLVE_V4", CURL_IPRESOLVE_V4);
HTTP_LONG_CONSTANT("HTTP_IPRESOLVE_V6", CURL_IPRESOLVE_V6);
/* {{{ MSHUTDOWN */
PHP_MSHUTDOWN_FUNCTION(http_request)
{
-#ifdef HTTP_NEED_OPENSSL_TSL
- CRYPTO_set_id_callback(http_openssl_thread_id);
- CRYPTO_set_locking_callback(http_openssl_thread_lock);
-#endif
curl_global_cleanup();
#ifdef HTTP_NEED_OPENSSL_TSL
if (http_openssl_tsl) {
TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
- if (initialized) {
- curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "");
+ if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "")) {
return SUCCESS;
}
http_error(HE_WARNING, HTTP_E_REQUEST, "Could not enable cookies for this session");
HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
if (session_only) {
#if HTTP_CURL_VERSION(7,15,4)
- if (initialized) {
- curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS");
+ if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS")) {
return SUCCESS;
}
#endif
http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)");
} else {
#if HTTP_CURL_VERSION(7,14,1)
- if (initialized) {
- curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL");
+ if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL")) {
return SUCCESS;
}
#endif
HTTP_CURL_OPT(CURLOPT_SSL_VERIFYPEER, 0L);
HTTP_CURL_OPT(CURLOPT_SSL_VERIFYHOST, 0L);
HTTP_CURL_OPT(CURLOPT_SSL_CIPHER_LIST, NULL);
+#ifdef HTTP_CURL_CAINFO
+ HTTP_CURL_OPT(CURLOPT_CAINFO, HTTP_CURL_CAINFO);
+#else
HTTP_CURL_OPT(CURLOPT_CAINFO, NULL);
+#endif
HTTP_CURL_OPT(CURLOPT_CAPATH, NULL);
HTTP_CURL_OPT(CURLOPT_RANDOM_FILE, NULL);
HTTP_CURL_OPT(CURLOPT_EGDSOCKET, NULL);
request->_cache.headers = NULL;
}
if ((zoption = http_request_option(request, options, "headers", IS_ARRAY))) {
- char *header_key = NULL;
- ulong header_idx;
+ HashKey header_key = initHashKey(0);
+ zval **header_val;
HashPosition pos;
- FOREACH_KEY(pos, zoption, header_key, header_idx) {
- if (header_key) {
- zval **header_val;
- if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_P(zoption), (void *) &header_val, &pos)) {
- char header[1024] = {0};
-
- ZVAL_ADDREF(*header_val);
- convert_to_string_ex(header_val);
- if (!strcasecmp(header_key, "range")) {
- range_req = 1;
- }
- snprintf(header, lenof(header), "%s: %s", header_key, Z_STRVAL_PP(header_val));
- request->_cache.headers = curl_slist_append(request->_cache.headers, header);
- zval_ptr_dtor(header_val);
+ FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
+ if (header_key.type == HASH_KEY_IS_STRING) {
+ char header[1024];
+
+ ZVAL_ADDREF(*header_val);
+ convert_to_string_ex(header_val);
+ if (!strcasecmp(header_key.str, "range")) {
+ range_req = 1;
}
-
- /* reset */
- header_key = NULL;
+ snprintf(header, sizeof(header), "%s: %s", header_key.str, Z_STRVAL_PP(header_val));
+ request->_cache.headers = curl_slist_append(request->_cache.headers, header);
+ zval_ptr_dtor(header_val);
}
}
}
/* etag */
if ((zoption = http_request_option(request, options, "etag", IS_STRING)) && Z_STRLEN_P(zoption)) {
- char match_header[1024] = {0}, *quoted_etag = NULL;
+ char match_header[1024], *quoted_etag = NULL;
if ((Z_STRVAL_P(zoption)[0] != '"') || (Z_STRVAL_P(zoption)[Z_STRLEN_P(zoption)-1] != '"')) {
spprintf("ed_etag, 0, "\"%s\"", Z_STRVAL_P(zoption));
}
- snprintf(match_header, lenof(match_header), "%s: %s", range_req?"If-Match":"If-None-Match", quoted_etag?quoted_etag:Z_STRVAL_P(zoption));
+ snprintf(match_header, sizeof(match_header), "%s: %s", range_req?"If-Match":"If-None-Match", quoted_etag?quoted_etag:Z_STRVAL_P(zoption));
request->_cache.headers = curl_slist_append(request->_cache.headers, match_header);
STR_FREE(quoted_etag);
}
}
} else {
HashPosition pos;
- char *cookie_key = NULL;
- ulong cookie_idx;
+ HashKey cookie_key = initHashKey(0);
+ zval **cookie_val;
- FOREACH_KEY(pos, zoption, cookie_key, cookie_idx) {
- if (cookie_key) {
- zval **cookie_val;
- if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_P(zoption), (void *) &cookie_val, &pos)) {
- zval *val = zval_copy(IS_STRING, *cookie_val);
- phpstr_appendf(&request->_cache.cookies, "%s=%s; ", cookie_key, Z_STRVAL_P(val));
- zval_free(&val);
- }
-
- /* reset */
- cookie_key = NULL;
+ FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) {
+ if (cookie_key.type == HASH_KEY_IS_STRING) {
+ zval *val = zval_copy(IS_STRING, *cookie_val);
+ phpstr_appendf(&request->_cache.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
+ zval_free(&val);
}
}
/* ssl */
if ((zoption = http_request_option(request, options, "ssl", IS_ARRAY))) {
- ulong idx;
- char *key = NULL;
+ HashKey key = initHashKey(0);
zval **param;
HashPosition pos;
- FOREACH_KEYVAL(pos, zoption, key, idx, param) {
- if (key) {
+ FOREACH_KEYVAL(pos, zoption, key, param) {
+ if (key.type == HASH_KEY_IS_STRING) {
HTTP_CURL_OPT_STRING(CURLOPT_SSLCERT, 0, 1);
HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTTYPE, 0, 0);
HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTPASSWD, 0, 0);
HTTP_CURL_OPT_STRING(CURLOPT_CAPATH, -3, 1);
HTTP_CURL_OPT_STRING(CURLOPT_RANDOM_FILE, -3, 1);
HTTP_CURL_OPT_STRING(CURLOPT_EGDSOCKET, -3, 1);
-
- /* reset key */
- key = NULL;
}
}
}
{
http_request *request = (http_request *) ctx;
+#define EMPTY_HEADER(d, l) ((l == 1 && d[0] == '\n') || (l == 2 && d[0] == '\r' && d[1] == '\n'))
switch (type) {
case CURLINFO_DATA_IN:
if (request->conv.last_type == CURLINFO_HEADER_IN) {
phpstr_appends(&request->conv.response, HTTP_CRLF);
}
- case CURLINFO_HEADER_IN:
phpstr_append(&request->conv.response, data, length);
break;
- case CURLINFO_DATA_OUT:
- if (request->conv.last_type == CURLINFO_HEADER_OUT) {
- phpstr_appends(&request->conv.request, HTTP_CRLF);
+ case CURLINFO_HEADER_IN:
+ if (!EMPTY_HEADER(data, length)) {
+ phpstr_append(&request->conv.response, data, length);
}
+ break;
+ case CURLINFO_DATA_OUT:
case CURLINFO_HEADER_OUT:
phpstr_append(&request->conv.request, data, length);
break;
if (data[length-1] != 0xa) {
fprintf(stderr, "\n");
}
-#endif
-#if 0
- fprintf(stderr, "%.*s%s", length, data, data[length-1]=='\n'?"":"\n");
#endif
break;
}
+#if 0
+ fprintf(stderr, "DEBUG: %3d (%5zu) %.*s%s", type, length, length, data, data[length-1]=='\n'?"":"\n");
+#endif
+
if (type) {
request->conv.last_type = type;
}