#define HTTP_CURL_OPT(OPTION, p) HTTP_CURL_OPT_EX(request->ch, OPTION, (p))
#define HTTP_CURL_OPT_EX(ch, OPTION, p) curl_easy_setopt((ch), OPTION, (p))
-#define HTTP_CURL_OPT_STRING(keyname, obdc) HTTP_CURL_OPT_STRING_EX(keyname, keyname, obdc)
+
+#define HTTP_CURL_OPT_STRING(OPTION, ldiff, obdc) \
+ { \
+ char *K = #OPTION; \
+ HTTP_CURL_OPT_STRING_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION, obdc); \
+ }
#define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \
- if (!strcasecmp(key, #keyname)) { \
- zval *copy = http_request_option_cache(request, #keyname, zval_copy(IS_STRING, *param)); \
+ if (!strcasecmp(key, keyname)) { \
+ zval *copy = http_request_option_cache(request, keyname, zval_copy(IS_STRING, *param)); \
if (obdc) { \
HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(copy), return FAILURE); \
} \
key = NULL; \
continue; \
}
-#define HTTP_CURL_OPT_LONG(keyname) HTTP_CURL_OPT_LONG_EX(keyname, keyname)
+#define HTTP_CURL_OPT_LONG(OPTION, ldiff) \
+ { \
+ char *K = #OPTION; \
+ HTTP_CURL_OPT_LONG_EX(K+lenof("CURLOPT_KEY")+ldiff, OPTION); \
+ }
#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \
- if (!strcasecmp(key, #keyname)) { \
- zval *copy = http_request_option_cache(request, #keyname, zval_copy(IS_LONG, *param)); \
+ if (!strcasecmp(key, keyname)) { \
+ zval *copy = http_request_option_cache(request, keyname, zval_copy(IS_LONG, *param)); \
HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \
key = NULL; \
continue; \
if (request->ch) {
http_request_defaults(request);
}
+ request->_error[0] = '\0';
}
/* }}} */
}
}
+ /* resume */
+ if ((zoption = http_request_option(request, options, "resume", IS_LONG)) && (Z_LVAL_P(zoption) != 0)) {
+ range_req = 1;
+ HTTP_CURL_OPT(CURLOPT_RESUME_FROM, Z_LVAL_P(zoption));
+ }
+
/* additional headers, array('name' => 'value') */
if (request->_cache.headers) {
curl_slist_free_all(request->_cache.headers);
ZVAL_ADDREF(*header_val);
convert_to_string_ex(header_val);
- snprintf(header, 1023, "%s: %s", header_key, Z_STRVAL_PP(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);
}
}
}
}
+ /* etag */
+ if ((zoption = http_request_option(request, options, "etag", IS_STRING)) && Z_STRLEN_P(zoption)) {
+ char match_header[1024] = {0}, *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));
+ request->_cache.headers = curl_slist_append(request->_cache.headers, match_header);
+ STR_FREE(quoted_etag);
+ }
+ /* compression */
if ((zoption = http_request_option(request, options, "compress", IS_BOOL)) && Z_LVAL_P(zoption)) {
request->_cache.headers = curl_slist_append(request->_cache.headers, "Accept-Encoding: gzip;q=1.0,deflate;q=0.5");
}
HTTP_CURL_OPT(CURLOPT_HTTPHEADER, request->_cache.headers);
+ /* lastmodified */
+ if ((zoption = http_request_option(request, options, "lastmodified", IS_LONG))) {
+ if (Z_LVAL_P(zoption)) {
+ if (Z_LVAL_P(zoption) > 0) {
+ HTTP_CURL_OPT(CURLOPT_TIMEVALUE, Z_LVAL_P(zoption));
+ } else {
+ HTTP_CURL_OPT(CURLOPT_TIMEVALUE, HTTP_GET_REQUEST_TIME() + Z_LVAL_P(zoption));
+ }
+ HTTP_CURL_OPT(CURLOPT_TIMECONDITION, range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE);
+ } else {
+ HTTP_CURL_OPT(CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
+ }
+ }
+
/* cookies, array('name' => 'value') */
if ((zoption = http_request_option(request, options, "cookies", IS_ARRAY))) {
phpstr_dtor(&request->_cache.cookies);
if (zend_hash_num_elements(Z_ARRVAL_P(zoption))) {
- if (SUCCESS == http_urlencode_hash_recursive(HASH_OF(zoption), &request->_cache.cookies, "; ", sizeof("; ")-1, NULL, 0)) {
+ zval *urlenc_cookies = NULL;
+ /* check whether cookies should not be urlencoded; default is to urlencode them */
+ if ((!(urlenc_cookies = http_request_option(request, options, "encodecookies", IS_BOOL))) || Z_BVAL_P(urlenc_cookies)) {
+ if (SUCCESS == http_urlencode_hash_recursive(HASH_OF(zoption), &request->_cache.cookies, "; ", lenof("; "), NULL, 0)) {
+ phpstr_fix(&request->_cache.cookies);
+ HTTP_CURL_OPT(CURLOPT_COOKIE, request->_cache.cookies.data);
+ }
+ } else {
+ HashPosition pos;
+ zval *cookie_val = NULL;
+ char *cookie_key = NULL;
+ ulong cookie_idx;
+
+ 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;
+ }
+ }
+
phpstr_fix(&request->_cache.cookies);
- HTTP_CURL_OPT(CURLOPT_COOKIE, request->_cache.cookies.data);
+ if (PHPSTR_LEN(&request->_cache.cookies)) {
+ HTTP_CURL_OPT(CURLOPT_COOKIE, PHPSTR_VAL(&request->_cache.cookies));
+ }
}
}
}
HTTP_CURL_OPT(CURLOPT_COOKIEJAR, Z_STRVAL_P(zoption));
}
- /* resume */
- if ((zoption = http_request_option(request, options, "resume", IS_LONG)) && (Z_LVAL_P(zoption) != 0)) {
- range_req = 1;
- HTTP_CURL_OPT(CURLOPT_RESUME_FROM, Z_LVAL_P(zoption));
- }
-
/* maxfilesize */
if ((zoption = http_request_option(request, options, "maxfilesize", IS_LONG))) {
HTTP_CURL_OPT(CURLOPT_MAXFILESIZE, Z_LVAL_P(zoption));
HTTP_CURL_OPT(CURLOPT_HTTP_VERSION, Z_LVAL_P(zoption));
}
- /* lastmodified */
- if ((zoption = http_request_option(request, options, "lastmodified", IS_LONG))) {
- if (Z_LVAL_P(zoption)) {
- if (Z_LVAL_P(zoption) > 0) {
- HTTP_CURL_OPT(CURLOPT_TIMEVALUE, Z_LVAL_P(zoption));
- } else {
- HTTP_CURL_OPT(CURLOPT_TIMEVALUE, HTTP_GET_REQUEST_TIME() + Z_LVAL_P(zoption));
- }
- HTTP_CURL_OPT(CURLOPT_TIMECONDITION, range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE);
- } else {
- HTTP_CURL_OPT(CURLOPT_TIMECONDITION, CURL_TIMECOND_NONE);
- }
- }
-
/* timeout, defaults to 0 */
if ((zoption = http_request_option(request, options, "timeout", IS_LONG))) {
HTTP_CURL_OPT(CURLOPT_TIMEOUT, Z_LVAL_P(zoption));
}
- /* connecttimeout, defaults to 3 */
+ /* connecttimeout, defaults to 0 */
if ((zoption = http_request_option(request, options, "connecttimeout", IS_LONG))) {
HTTP_CURL_OPT(CURLOPT_CONNECTTIMEOUT, Z_LVAL_P(zoption));
}
FOREACH_KEYVAL(pos, zoption, key, idx, param) {
if (key) {
- HTTP_CURL_OPT_STRING(CURLOPT_SSLCERT, 1);
- HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTTYPE, 0);
- HTTP_CURL_OPT_STRING(CURLOPT_SSLCERTPASSWD, 0);
+ 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_SSLKEY, 0);
- HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYTYPE, 0);
- HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYPASSWD, 0);
+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEY, 0, 0);
+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYTYPE, 0, 0);
+ HTTP_CURL_OPT_STRING(CURLOPT_SSLKEYPASSWD, 0, 0);
- HTTP_CURL_OPT_STRING(CURLOPT_SSLENGINE, 0);
- HTTP_CURL_OPT_LONG(CURLOPT_SSLVERSION);
+ HTTP_CURL_OPT_STRING(CURLOPT_SSLENGINE, 0, 0);
+ HTTP_CURL_OPT_LONG(CURLOPT_SSLVERSION, 0);
- HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYPEER);
- HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYHOST);
- HTTP_CURL_OPT_STRING(CURLOPT_SSL_CIPHER_LIST, 0);
+ HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYPEER, 1);
+ HTTP_CURL_OPT_LONG(CURLOPT_SSL_VERIFYHOST, 1);
+ HTTP_CURL_OPT_STRING(CURLOPT_SSL_CIPHER_LIST, 1, 0);
- HTTP_CURL_OPT_STRING(CURLOPT_CAINFO, 1);
- HTTP_CURL_OPT_STRING(CURLOPT_CAPATH, 1);
- HTTP_CURL_OPT_STRING(CURLOPT_RANDOM_FILE, 1);
- HTTP_CURL_OPT_STRING(CURLOPT_EGDSOCKET, 1);
+ HTTP_CURL_OPT_STRING(CURLOPT_CAINFO, -3, 1);
+ 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_CURL_INFO(CURLINFO_CONTENT_TYPE);
HTTP_CURL_INFO(CURLINFO_HTTPAUTH_AVAIL);
HTTP_CURL_INFO(CURLINFO_PROXYAUTH_AVAIL);
- /*HTTP_CURL_INFO(OS_ERRNO);*/
+ HTTP_CURL_INFO(CURLINFO_OS_ERRNO);
+ add_assoc_string(&array, "error", request->_error, 1);
HTTP_CURL_INFO(CURLINFO_NUM_CONNECTS);
#if LIBCURL_VERSION_NUM >= 0x070e01
HTTP_CURL_INFO_EX(CURLINFO_COOKIELIST, "cookies");