From 16ea91ddd08d15dd9b7206229fec6158f212adaf Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 6 May 2005 16:37:53 +0000 Subject: [PATCH] - vastly simplified curl api and renamed it to request api (not completely finished) # this should be the last major change --- config.w32 | 2 +- http.c | 12 +- http.dsp | 4 +- http_functions.c | 37 +- http_message_api.c | 6 +- http_methods.c | 76 +-- http_curl_api.c => http_request_api.c | 669 +++++++++++++++----------- http_request_object.c | 32 ++ http_util_object.c | 11 +- package.xml | 190 ++++---- php_http.h | 2 +- php_http_curl_api.h | 60 --- php_http_request_api.h | 108 +++++ php_http_request_object.h | 6 - php_http_std_defs.h | 2 +- phpstr/phpstr.h | 2 + tests/skip.inc | 6 +- 17 files changed, 701 insertions(+), 524 deletions(-) rename http_curl_api.c => http_request_api.c (62%) delete mode 100644 php_http_curl_api.h create mode 100644 php_http_request_api.h diff --git a/config.w32 b/config.w32 index fcb66b6..76adf5f 100644 --- a/config.w32 +++ b/config.w32 @@ -9,7 +9,7 @@ if (PHP_HTTP != "no") { "http_util_object.c http_message_object.c "+ "http_request_object.c http_response_object.c "+ "http_api.c http_auth_api.c http_cache_api.c "+ - "http_curl_api.c http_date_api.c http_headers_api.c "+ + "http_request_api.c http_date_api.c http_headers_api.c "+ "http_message_api.c http_send_api.c http_url_api.c ", null, "/I\"" + configure_module_dirname + "/phpstr\""); diff --git a/http.c b/http.c index b26751a..d766e42 100644 --- a/http.c +++ b/http.c @@ -68,9 +68,19 @@ ZEND_BEGIN_ARG_INFO(http_request_info_ref_4, 0) ZEND_ARG_PASS_INFO(0) ZEND_ARG_PASS_INFO(1) ZEND_END_ARG_INFO(); + +static +ZEND_BEGIN_ARG_INFO(http_request_info_ref_5, 0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(1) +ZEND_END_ARG_INFO(); #else static unsigned char http_request_info_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; static unsigned char http_request_info_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; +static unsigned char http_request_info_ref_5[] = {5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; #endif /* ZEND_ENGINE_2 */ #endif /* HTTP_HAVE_CURL */ @@ -107,7 +117,7 @@ function_entry http_functions[] = { PHP_FE(http_get, http_request_info_ref_3) PHP_FE(http_head, http_request_info_ref_3) PHP_FE(http_post_data, http_request_info_ref_4) - PHP_FE(http_post_array, http_request_info_ref_4) + PHP_FE(http_post_fields, http_request_info_ref_5) #endif PHP_FE(http_auth_basic, NULL) PHP_FE(http_auth_basic_cb, NULL) diff --git a/http.dsp b/http.dsp index b5eecd1..798e551 100644 --- a/http.dsp +++ b/http.dsp @@ -102,7 +102,7 @@ SOURCE=.\http_api.c # End Source File # Begin Source File -SOURCE=.\http_curl_api.c +SOURCE=.\http_request_api.c # End Source File # Begin Source File @@ -154,7 +154,7 @@ SOURCE=.\php_http_api.h # End Source File # Begin Source File -SOURCE=.\php_http_curl_api.h +SOURCE=.\php_http_request_api.h # End Source File # Begin Source File diff --git a/http_functions.c b/http_functions.c index bfbf22a..5dc49b5 100644 --- a/http_functions.c +++ b/http_functions.c @@ -33,9 +33,9 @@ #include "php_http_std_defs.h" #include "php_http_api.h" #include "php_http_auth_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_cache_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_date_api.h" #include "php_http_headers_api.h" #include "php_http_message_api.h" @@ -775,6 +775,7 @@ PHP_FUNCTION(http_post_data) char *URL, *postdata; int postdata_len, URL_len; phpstr response; + http_request_body body; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &postdata, &postdata_len, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -785,29 +786,39 @@ PHP_FUNCTION(http_post_data) array_init(info); } + body.type = HTTP_REQUEST_BODY_CSTRING; + body.data = postdata; + body.size = postdata_len; + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); - if (SUCCESS == http_post_data(URL, postdata, (size_t) postdata_len, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETVAL_PHPSTR_VAL(response); } else { - RETURN_FALSE; + RETVAL_FALSE; } + http_request_body_dtor(&body); } /* }}} */ -/* {{{ proto string http_post_array(string url, array data[, array options[, array &info]]) +/* {{{ proto string http_post_fields(string url, array data[, array files[, array options[, array &info]]]) * * Performs an HTTP POST request, posting www-form-urlencoded array data. * Returns the HTTP response as string. * See http_get() for a full list of available options. */ -PHP_FUNCTION(http_post_array) +PHP_FUNCTION(http_post_fields) { - zval *options = NULL, *info = NULL, *postdata; + zval *options = NULL, *info = NULL, *fields, *files = NULL; char *URL; int URL_len; phpstr response; + http_request_body body; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a/!z", &URL, &URL_len, &postdata, &options, &info) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|aa/!z", &URL, &URL_len, &fields, &files, &options, &info) != SUCCESS) { + RETURN_FALSE; + } + + if (SUCCESS != http_request_body_fill(&body, Z_ARRVAL_P(fields), files ? Z_ARRVAL_P(files) : NULL)) { RETURN_FALSE; } @@ -817,11 +828,12 @@ PHP_FUNCTION(http_post_array) } phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); - if (SUCCESS == http_post_array(URL, Z_ARRVAL_P(postdata), options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETVAL_PHPSTR_VAL(response); } else { - RETURN_FALSE; + RETVAL_FALSE; } + http_request_body_dtor(&body); } /* }}} */ @@ -993,4 +1005,3 @@ PHP_FUNCTION(http_test) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/http_message_api.c b/http_message_api.c index b1f5fbc..a0f5e59 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -26,7 +26,7 @@ #include "php_http_message_api.h" #include "php_http_headers_api.h" #include "php_http_send_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_url_api.h" #include "phpstr/phpstr.h" @@ -382,7 +382,8 @@ PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC) } if (!strcasecmp("POST", message->info.request.method)) { - rs = http_post_data(uri, PHPSTR_VAL(message), PHPSTR_LEN(message), Z_ARRVAL(options), NULL, NULL); + http_request_body body = {HTTP_REQUEST_BODY_CSTRING, PHPSTR_VAL(message), PHPSTR_LEN(message)}; + rs = http_post(uri, &body, Z_ARRVAL(options), NULL, NULL); } else if (!strcasecmp("GET", message->info.request.method)) { rs = http_get(uri, Z_ARRVAL(options), NULL, NULL); @@ -449,4 +450,3 @@ PHP_HTTP_API void _http_message_free(http_message *message) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/http_methods.c b/http_methods.c index e06f340..eaf3642 100644 --- a/http_methods.c +++ b/http_methods.c @@ -24,7 +24,7 @@ #include "php_http_std_defs.h" #include "php_http_api.h" #include "php_http_cache_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_date_api.h" #include "php_http_headers_api.h" #include "php_http_message_api.h" @@ -1920,75 +1920,24 @@ PHP_METHOD(HttpRequest, send) switch (Z_LVAL_P(meth)) { case HTTP_GET: - status = http_get_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + case HTTP_HEAD: + status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, NULL, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); break; - case HTTP_HEAD: - status = http_head_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + case HTTP_PUT: break; case HTTP_POST: - { - zval *post_files, *post_data; - - post_files = GET_PROP(obj, postFiles); - post_data = GET_PROP(obj, postData); - - if (!zend_hash_num_elements(Z_ARRVAL_P(post_files))) { - - /* urlencoded post */ - status = http_post_array_ex(obj->ch, request_uri, Z_ARRVAL_P(post_data), Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - - } else { - - /* - * multipart post - */ - char *key = NULL; - long idx; - zval **data; - struct curl_httppost *http_post_data[2] = {NULL, NULL}; - - /* normal data */ - FOREACH_KEYVAL(post_data, key, idx, data) { - if (key) { - convert_to_string_ex(data); - curl_formadd(&http_post_data[0], &http_post_data[1], - CURLFORM_COPYNAME, key, - CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data), - CURLFORM_CONTENTSLENGTH, Z_STRLEN_PP(data), - CURLFORM_END - ); - - /* reset */ - key = NULL; - } - } - - /* file data */ - FOREACH_VAL(post_files, data) { - zval **file, **type, **name; - - if ( SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) && - SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) && - SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) { - - curl_formadd(&http_post_data[0], &http_post_data[1], - CURLFORM_COPYNAME, Z_STRVAL_PP(name), - CURLFORM_FILE, Z_STRVAL_PP(file), - CURLFORM_CONTENTTYPE, Z_STRVAL_PP(type), - CURLFORM_END - ); - } - } + default: + { + http_request_body body; + zval *fields = GET_PROP(obj, postData), *files = GET_PROP(obj, postFiles); - status = http_post_curldata_ex(obj->ch, request_uri, http_post_data[0], Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - curl_formfree(http_post_data[0]); - } + if (SUCCESS == (status = http_request_body_fill(&body, Z_ARRVAL_P(fields), Z_ARRVAL_P(files)))) { + status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, &body, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + http_request_body_dtor(&body); } - break; - - default: + } break; } @@ -2041,4 +1990,3 @@ PHP_METHOD(HttpRequest, send) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/http_curl_api.c b/http_request_api.c similarity index 62% rename from http_curl_api.c rename to http_request_api.c index a0702e7..e2e5ab6 100644 --- a/http_curl_api.c +++ b/http_request_api.c @@ -31,158 +31,195 @@ #include "php_http.h" #include "php_http_std_defs.h" #include "php_http_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_url_api.h" ZEND_EXTERN_MODULE_GLOBALS(http) -#if LIBCURL_VERSION_NUM >= 0x070c01 -# define http_curl_reset(ch) curl_easy_reset(ch) -#else -# define http_curl_reset(ch) -#endif - #if LIBCURL_VERSION_NUM < 0x070c00 -# define http_curl_error(dummy) HTTP_G(curlerr) -# define curl_easy_strerror(code) "unkown error" -#else -# define http_curl_error(code) curl_easy_strerror(code) +# define curl_easy_strerror(code) HTTP_G(curlerr) #endif -#define http_curl_startup(ch, clean_curl, URL, options, response) \ - if (!ch) { \ - if (!(ch = curl_easy_init())) { \ - http_error(E_WARNING, HTTP_E_CURL, "Could not initialize curl"); \ - return FAILURE; \ - } \ - clean_curl = 1; \ - } else { \ - http_curl_reset(ch); \ - } \ - http_curl_setopts(ch, URL, options, response); - -#define http_curl_perform(ch, clean_curl, response) \ +#define HTTP_CURL_INFO(I) HTTP_CURL_INFO_EX(I, I) +#define HTTP_CURL_INFO_EX(I, X) \ + switch (CURLINFO_ ##I & ~CURLINFO_MASK) \ { \ - CURLcode result; \ - if (CURLE_OK != (result = curl_easy_perform(ch))) { \ - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not perform request: %s", curl_easy_strerror(result)); \ - http_curl_cleanup(ch, clean_curl, response); \ - return FAILURE; \ + case CURLINFO_STRING: \ + { \ + char *c; \ + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &c)) { \ + add_assoc_string(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), c ? c : "", 1); \ + } \ } \ + break; \ +\ + case CURLINFO_DOUBLE: \ + { \ + double d; \ + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &d)) { \ + add_assoc_double(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), d); \ + } \ + } \ + break; \ +\ + case CURLINFO_LONG: \ + { \ + long l; \ + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &l)) { \ + add_assoc_long(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), l); \ + } \ + } \ + break; \ + } + +#define HTTP_CURL_OPT(OPTION, p) curl_easy_setopt(ch, CURLOPT_##OPTION, (p)) +#define HTTP_CURL_OPT_STRING(keyname) HTTP_CURL_OPT_STRING_EX(keyname, keyname) +#define HTTP_CURL_OPT_SSL_STRING(keyname) HTTP_CURL_OPT_STRING_EX(keyname, SSL##keyname) +#define HTTP_CURL_OPT_SSL_STRING_(keyname) HTTP_CURL_OPT_STRING_EX(keyname, SSL_##keyname) +#define HTTP_CURL_OPT_STRING_EX(keyname, optname) \ + if (!strcasecmp(key, #keyname)) { \ + convert_to_string_ex(param); \ + HTTP_CURL_OPT(optname, http_curl_copystr(Z_STRVAL_PP(param))); \ + key = NULL; \ + continue; \ + } +#define HTTP_CURL_OPT_LONG(keyname) HTTP_OPT_SSL_LONG_EX(keyname, keyname) +#define HTTP_CURL_OPT_SSL_LONG(keyname) HTTP_CURL_OPT_LONG_EX(keyname, SSL##keyname) +#define HTTP_CURL_OPT_SSL_LONG_(keyname) HTTP_CURL_OPT_LONG_EX(keyname, SSL_##keyname) +#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ + if (!strcasecmp(key, #keyname)) { \ + convert_to_long_ex(param); \ + HTTP_CURL_OPT(optname, Z_LVAL_PP(param)); \ + key = NULL; \ + continue; \ } -#define http_curl_cleanup(ch, clean_curl, response) \ - zend_llist_clean(&HTTP_G(to_free)); \ - if (clean_curl) { \ - curl_easy_cleanup(ch); \ - ch = NULL; \ - } \ - phpstr_fix(PHPSTR(response)) +static const char *const http_request_methods[HTTP_MAX_REQUEST_METHOD + 1]; #define http_curl_copystr(s) _http_curl_copystr((s) TSRMLS_CC) static inline char *_http_curl_copystr(const char *str TSRMLS_DC); - -#define http_curl_setopts(c, u, o, r) _http_curl_setopts((c), (u), (o), (r) TSRMLS_CC) -static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, phpstr *response TSRMLS_DC); - #define http_curl_getopt(o, k, t) _http_curl_getopt_ex((o), (k), sizeof(k), (t) TSRMLS_CC) #define http_curl_getopt_ex(o, k, l, t) _http_curl_getopt_ex((o), (k), (l), (t) TSRMLS_CC) static inline zval *_http_curl_getopt_ex(HashTable *options, char *key, size_t keylen, int type TSRMLS_DC); - static size_t http_curl_write_callback(char *, size_t, size_t, void *); +static size_t http_curl_read_callback(void *, size_t, size_t, void *); static int http_curl_progress_callback(void *, double, double, double, double); static int http_curl_debug_callback(CURL *, curl_infotype, char *, size_t, void *); -#define http_curl_getinfo(c, h) _http_curl_getinfo((c), (h) TSRMLS_CC) -static inline void _http_curl_getinfo(CURL *ch, HashTable *info TSRMLS_DC); - -/* {{{ static inline char *http_curl_copystr(char *) */ -static inline char *_http_curl_copystr(const char *str TSRMLS_DC) -{ - char *new_str = estrdup(str); - zend_llist_add_element(&HTTP_G(to_free), &new_str); - return new_str; -} -/* }}} */ -/* {{{ static size_t http_curl_write_callback(char *, size_t, size_t, void *) */ -static size_t http_curl_write_callback(char *buf, size_t len, size_t n, void *s) -{ - return s ? phpstr_append(PHPSTR(s), buf, len * n) : len * n; -} -/* }}} */ - -/* {{{ 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) +/* {{{ STATUS http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */ +PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files TSRMLS_DC) { - zval *params_pass[4], params_local[4], retval, *func = (zval *) data; - TSRMLS_FETCH(); - - params_pass[0] = ¶ms_local[0]; - params_pass[1] = ¶ms_local[1]; - params_pass[2] = ¶ms_local[2]; - params_pass[3] = ¶ms_local[3]; + if (files && (zend_hash_num_elements(files) > 0)) { + char *key = NULL; + ulong idx; + zval **data; + struct curl_httppost *http_post_data[2] = {NULL, NULL}; + + /* normal data */ + FOREACH_HASH_KEYVAL(fields, key, idx, data) { + CURLcode err; + if (key) { + convert_to_string_ex(data); + err = curl_formadd(&http_post_data[0], &http_post_data[1], + CURLFORM_COPYNAME, key, + CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data), + CURLFORM_CONTENTSLENGTH, Z_STRLEN_PP(data), + CURLFORM_END + ); + if (CURLE_OK != err) { + http_error_ex(E_WARNING, HTTP_E_CURL, "Could not encode post fields: %s", curl_easy_strerror(err)); + curl_formfree(http_post_data[0]); + return FAILURE; + } - ZVAL_DOUBLE(params_pass[0], dltotal); - ZVAL_DOUBLE(params_pass[1], dlnow); - ZVAL_DOUBLE(params_pass[2], ultotal); - ZVAL_DOUBLE(params_pass[3], ulnow); + /* reset */ + key = NULL; + } + } - return call_user_function(EG(function_table), NULL, func, &retval, 4, params_pass TSRMLS_CC); -} -/* }}} */ + /* file data */ + FOREACH_HASH_VAL(files, data) { + CURLcode err; + zval **file, **type, **name; + if ( SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) && + SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) && + SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) { + err = curl_formadd(&http_post_data[0], &http_post_data[1], + CURLFORM_COPYNAME, Z_STRVAL_PP(name), + CURLFORM_FILE, Z_STRVAL_PP(file), + CURLFORM_CONTENTTYPE, Z_STRVAL_PP(type), + CURLFORM_END + ); + if (CURLE_OK != err) { + http_error_ex(E_WARNING, HTTP_E_CURL, "Could not encode post files: %s", curl_easy_strerror(err)); + curl_formfree(http_post_data[0]); + return FAILURE; + } + } + } -static int http_curl_debug_callback(CURL *ch, curl_infotype type, char *string, size_t length, void *data) -{ - zval *params_pass[2], params_local[2], retval, *func = (zval *) data; - TSRMLS_FETCH(); + body->type = HTTP_REQUEST_BODY_CURLPOST; + body->data = http_post_data[0]; + body->size = 0; - params_pass[0] = ¶ms_local[0]; - params_pass[1] = ¶ms_local[1]; + } else { + char *encoded; + size_t encoded_len; - ZVAL_LONG(params_pass[0], type); - ZVAL_STRINGL(params_pass[1], string, length, 1); + if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) { + http_error(E_WARNING, HTTP_E_ENCODE, "Could not encode post data"); + return FAILURE; + } - call_user_function(EG(function_table), NULL, func, &retval, 2, params_pass TSRMLS_CC); + body->type = HTTP_REQUEST_BODY_CSTRING; + body->data = encoded; + body->size = encoded_len; + } - return 0; + return SUCCESS; } -/* {{{ static inline zval *http_curl_getopt(HashTable *, char *, size_t, int) */ -static inline zval *_http_curl_getopt_ex(HashTable *options, char *key, size_t keylen, int type TSRMLS_DC) -{ - zval **zoption; +/* }}} */ - if (!options || (SUCCESS != zend_hash_find(options, key, keylen, (void **) &zoption))) { - return NULL; - } +/* {{{ void http_request_body_dtor(http_request_body *) */ +PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC) +{ + switch (body->type) + { + case HTTP_REQUEST_BODY_CSTRING: + efree(body->data); + break; - if (Z_TYPE_PP(zoption) != type) { - switch (type) - { - case IS_BOOL: convert_to_boolean_ex(zoption); break; - case IS_LONG: convert_to_long_ex(zoption); break; - case IS_DOUBLE: convert_to_double_ex(zoption); break; - case IS_STRING: convert_to_string_ex(zoption); break; - case IS_ARRAY: convert_to_array_ex(zoption); break; - case IS_OBJECT: convert_to_object_ex(zoption); break; - default: - break; - } + case HTTP_REQUEST_BODY_CURLPOST: + curl_formfree(body->data); + break; } - - return *zoption; } /* }}} */ -/* {{{ static void http_curl_setopts(CURL *, char *, HashTable *, phpstr *) */ -static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, phpstr *response TSRMLS_DC) +/* {{{ STATUS http_request_ex(CURL *, http_request_method, char *, http_request_body, HashTable, HashTable, phpstr *) */ +PHP_HTTP_API STATUS _http_request_ex(CURL *ch, http_request_method meth, const char *url, http_request_body *body, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) { + CURLcode result = CURLE_OK; + STATUS status = SUCCESS; + zend_bool clean_curl = 0, range_req = 0; zval *zoption; - zend_bool range_req = 0; -#define HTTP_CURL_OPT(OPTION, p) curl_easy_setopt(ch, CURLOPT_##OPTION, (p)) + /* check/init CURL handle */ + if (ch) { +#if LIBCURL_VERSION_NUM >= 0x070c01 + curl_easy_reset(ch); +#endif + } else { + if (ch = curl_easy_init()) { + clean_curl = 1; + } else { + http_error(E_WARNING, HTTP_E_CURL, "Could not initialize curl"); + return FAILURE; + } + } - /* standard options */ + /* set options */ if (url) { HTTP_CURL_OPT(URL, url); } @@ -190,6 +227,7 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph HTTP_CURL_OPT(HEADER, 0); HTTP_CURL_OPT(FILETIME, 1); HTTP_CURL_OPT(AUTOREFERER, 1); + HTTP_CURL_OPT(READFUNCTION, http_curl_read_callback); HTTP_CURL_OPT(WRITEFUNCTION, http_curl_write_callback); HTTP_CURL_OPT(HEADERFUNCTION, http_curl_write_callback); @@ -380,28 +418,7 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph /* ssl */ if (zoption = http_curl_getopt(options, "ssl", IS_ARRAY)) { -#define HTTP_CURL_OPT_STRING(keyname) HTTP_CURL_OPT_STRING_EX(keyname, keyname) -#define HTTP_CURL_OPT_SSL_STRING(keyname) HTTP_CURL_OPT_STRING_EX(keyname, SSL##keyname) -#define HTTP_CURL_OPT_SSL_STRING_(keyname) HTTP_CURL_OPT_STRING_EX(keyname, SSL_##keyname) -#define HTTP_CURL_OPT_STRING_EX(keyname, optname) \ - if (!strcasecmp(key, #keyname)) { \ - convert_to_string_ex(param); \ - HTTP_CURL_OPT(optname, http_curl_copystr(Z_STRVAL_PP(param))); \ - key = NULL; \ - continue; \ - } -#define HTTP_CURL_OPT_LONG(keyname) HTTP_OPT_SSL_LONG_EX(keyname, keyname) -#define HTTP_CURL_OPT_SSL_LONG(keyname) HTTP_CURL_OPT_LONG_EX(keyname, SSL##keyname) -#define HTTP_CURL_OPT_SSL_LONG_(keyname) HTTP_CURL_OPT_LONG_EX(keyname, SSL_##keyname) -#define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ - if (!strcasecmp(key, #keyname)) { \ - convert_to_long_ex(param); \ - HTTP_CURL_OPT(optname, Z_LVAL_PP(param)); \ - key = NULL; \ - continue; \ - } - - long idx; + ulong idx; char *key = NULL; zval **param; @@ -441,202 +458,307 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph HTTP_CURL_OPT(SSL_VERIFYPEER, 0); HTTP_CURL_OPT(SSL_VERIFYHOST, 0); } -} -/* }}} */ -/* {{{ static inline http_curl_getinfo(CURL, HashTable *) */ -static inline void _http_curl_getinfo(CURL *ch, HashTable *info TSRMLS_DC) -{ - zval array; - Z_ARRVAL(array) = info; + /* request method */ + switch (meth) + { + case HTTP_GET: + curl_easy_setopt(ch, CURLOPT_HTTPGET, 1); + break; + + case HTTP_HEAD: + curl_easy_setopt(ch, CURLOPT_NOBODY, 1); + break; + + case HTTP_POST: + curl_easy_setopt(ch, CURLOPT_POST, 1); + break; + + case HTTP_PUT: + curl_easy_setopt(ch, CURLOPT_UPLOAD, 1); + break; + + default: + if ((meth > HTTP_NO_REQUEST_METHOD) && (meth < HTTP_MAX_REQUEST_METHOD)) { + curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, http_request_methods[meth]); + } else { + http_error_ex(E_WARNING, HTTP_E_CURL, "Unsupported request method: %d", meth); + status = FAILURE; + goto http_request_end; + } + break; + } -#define HTTP_CURL_INFO(I) HTTP_CURL_INFO_EX(I, I) -#define HTTP_CURL_INFO_EX(I, X) \ - switch (CURLINFO_ ##I & ~CURLINFO_MASK) \ - { \ - case CURLINFO_STRING: \ - { \ - char *c; \ - if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &c)) { \ - add_assoc_string(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), c ? c : "", 1); \ - } \ - } \ - break; \ -\ - case CURLINFO_DOUBLE: \ - { \ - double d; \ - if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &d)) { \ - add_assoc_double(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), d); \ - } \ - } \ - break; \ -\ - case CURLINFO_LONG: \ - { \ - long l; \ - if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_ ##I, &l)) { \ - add_assoc_long(&array, pretty_key(http_curl_copystr(#X), sizeof(#X)-1, 0, 0), l); \ - } \ - } \ - break; \ + /* attach request body */ + if (body && (meth != HTTP_GET) && (meth != HTTP_HEAD)) { + switch (body->type) + { + case HTTP_REQUEST_BODY_CSTRING: + curl_easy_setopt(ch, CURLOPT_POSTFIELDS, (char *) body->data); + curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, body->size); + break; + + case HTTP_REQUEST_BODY_CURLPOST: + curl_easy_setopt(ch, CURLOPT_HTTPPOST, (struct curl_httppost *) body->data); + break; + + case HTTP_REQUEST_BODY_UPLOADFILE: + case HTTP_REQUEST_BODY_UPLOADDATA: + curl_easy_setopt(ch, CURLOPT_READDATA, body); + curl_easy_setopt(ch, CURLOPT_INFILESIZE, body->size); + break; + + default: + http_error_ex(E_WARNING, HTTP_E_CURL, "Unkown request body type: %d", body->type); + status = FAILURE; + goto http_request_end; + break; + } } - HTTP_CURL_INFO(EFFECTIVE_URL); + /* perform request */ + if (CURLE_OK == (result = curl_easy_perform(ch))) { + /* get curl info */ + if (info) { + zval array; + Z_ARRVAL(array) = info; + HTTP_CURL_INFO(EFFECTIVE_URL); #if LIBCURL_VERSION_NUM >= 0x070a07 - HTTP_CURL_INFO(RESPONSE_CODE); + HTTP_CURL_INFO(RESPONSE_CODE); #else - HTTP_CURL_INFO_EX(HTTP_CODE, RESPONSE_CODE); + HTTP_CURL_INFO_EX(HTTP_CODE, RESPONSE_CODE); #endif - HTTP_CURL_INFO(HTTP_CONNECTCODE); - + HTTP_CURL_INFO(HTTP_CONNECTCODE); #if LIBCURL_VERSION_NUM >= 0x070500 - HTTP_CURL_INFO(FILETIME); + HTTP_CURL_INFO(FILETIME); #endif - HTTP_CURL_INFO(TOTAL_TIME); - HTTP_CURL_INFO(NAMELOOKUP_TIME); - HTTP_CURL_INFO(CONNECT_TIME); - HTTP_CURL_INFO(PRETRANSFER_TIME); - HTTP_CURL_INFO(STARTTRANSFER_TIME); + HTTP_CURL_INFO(TOTAL_TIME); + HTTP_CURL_INFO(NAMELOOKUP_TIME); + HTTP_CURL_INFO(CONNECT_TIME); + HTTP_CURL_INFO(PRETRANSFER_TIME); + HTTP_CURL_INFO(STARTTRANSFER_TIME); #if LIBCURL_VERSION_NUM >= 0x070907 - HTTP_CURL_INFO(REDIRECT_TIME); - HTTP_CURL_INFO(REDIRECT_COUNT); + HTTP_CURL_INFO(REDIRECT_TIME); + HTTP_CURL_INFO(REDIRECT_COUNT); #endif - - HTTP_CURL_INFO(SIZE_UPLOAD); - HTTP_CURL_INFO(SIZE_DOWNLOAD); - HTTP_CURL_INFO(SPEED_DOWNLOAD); - HTTP_CURL_INFO(SPEED_UPLOAD); - - HTTP_CURL_INFO(HEADER_SIZE); - HTTP_CURL_INFO(REQUEST_SIZE); - - HTTP_CURL_INFO(SSL_VERIFYRESULT); + HTTP_CURL_INFO(SIZE_UPLOAD); + HTTP_CURL_INFO(SIZE_DOWNLOAD); + HTTP_CURL_INFO(SPEED_DOWNLOAD); + HTTP_CURL_INFO(SPEED_UPLOAD); + HTTP_CURL_INFO(HEADER_SIZE); + HTTP_CURL_INFO(REQUEST_SIZE); + HTTP_CURL_INFO(SSL_VERIFYRESULT); #if LIBCURL_VERSION_NUM >= 0x070c03 - /*HTTP_CURL_INFO(SSL_ENGINES); - todo: CURLINFO_SLIST */ + /*HTTP_CURL_INFO(SSL_ENGINES); todo: CURLINFO_SLIST */ #endif - - HTTP_CURL_INFO(CONTENT_LENGTH_DOWNLOAD); - HTTP_CURL_INFO(CONTENT_LENGTH_UPLOAD); - HTTP_CURL_INFO(CONTENT_TYPE); - + HTTP_CURL_INFO(CONTENT_LENGTH_DOWNLOAD); + HTTP_CURL_INFO(CONTENT_LENGTH_UPLOAD); + HTTP_CURL_INFO(CONTENT_TYPE); #if LIBCURL_VERSION_NUM >= 0x070a03 - /*HTTP_CURL_INFO(PRIVATE);*/ + /*HTTP_CURL_INFO(PRIVATE);*/ #endif - #if LIBCURL_VERSION_NUM >= 0x070a08 - HTTP_CURL_INFO(HTTPAUTH_AVAIL); - HTTP_CURL_INFO(PROXYAUTH_AVAIL); + HTTP_CURL_INFO(HTTPAUTH_AVAIL); + HTTP_CURL_INFO(PROXYAUTH_AVAIL); #endif - #if LIBCURL_VERSION_NUM >= 0x070c02 - /*HTTP_CURL_INFO(OS_ERRNO);*/ + /*HTTP_CURL_INFO(OS_ERRNO);*/ #endif - #if LIBCURL_VERSION_NUM >= 0x070c03 - HTTP_CURL_INFO(NUM_CONNECTS); + HTTP_CURL_INFO(NUM_CONNECTS); #endif -} -/* }}} */ - -/* {{{ STATUS http_get_ex(CURL *, char *, HashTable *, HashTable *, phpstr *) */ -PHP_HTTP_API STATUS _http_get_ex(CURL *ch, const char *URL, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) -{ - zend_bool clean_curl = 0; + } + } else { + http_error_ex(E_WARNING, HTTP_E_CURL, "Could not perform request: %s", curl_easy_strerror(result)); + status = FAILURE; + } - http_curl_startup(ch, clean_curl, URL, options, response); - curl_easy_setopt(ch, CURLOPT_HTTPGET, 1); - http_curl_perform(ch, clean_curl, response); +http_request_end: + /* free strings copied with http_curl_copystr() */ + zend_llist_clean(&HTTP_G(to_free)); - if (info) { - http_curl_getinfo(ch, info); + /* clean curl handle if acquired */ + if (clean_curl) { + curl_easy_cleanup(ch); + ch = NULL; } - http_curl_cleanup(ch, clean_curl, response); + /* finalize response */ + if (response) { + phpstr_fix(PHPSTR(response)); + } - return SUCCESS; + return status; } +/* }}} */ -/* {{{ STATUS http_head_ex(CURL *, char *, HashTable *, HashTable *, phpstr *) */ -PHP_HTTP_API STATUS _http_head_ex(CURL *ch, const char *URL, HashTable *options,HashTable *info, phpstr *response TSRMLS_DC) +/* {{{ char *http_request_method_string(http_request_method) */ +PHP_HTTP_API const char *_http_request_method_string(http_request_method m) { - zend_bool clean_curl = 0; - - http_curl_startup(ch, clean_curl, URL, options, response); - curl_easy_setopt(ch, CURLOPT_NOBODY, 1); - http_curl_perform(ch, clean_curl, response); - - if (info) { - http_curl_getinfo(ch, info); + if ((m > HTTP_NO_REQUEST_METHOD) && (m < HTTP_MAX_REQUEST_METHOD)) { + return http_request_methods[m]; } + return http_request_methods[0]; +} +/* }}} */ - http_curl_cleanup(ch, clean_curl, response); +/* {{{ char *http_request_methods[] */ +static const char *const http_request_methods[] = { + "UNKOWN", + /* HTTP/1.1 */ + "GET", + "HEAD", + "POST", + "PUT", + "DELETE", + "OPTIONS", + "TRACE", + "CONNECT", + /* WebDAV - RFC 2518 */ + "PROPFIND", + "PROPPATCH", + "MKCOL", + "COPY", + "MOVE", + "LOCK", + "UNLOCK", + /* WebDAV Versioning - RFC 3253 */ + "VERSION-CONTROL", + "REPORT", + "CHECKOUT", + "CHECKIN", + "UNCHECKOUT", + "MKWORKSPACE", + "UPDATE", + "LABEL", + "MERGE", + "BASELINE-CONTROL", + "MKACTIVITY", + /* WebDAV Access Control - RFC 3744 */ + "ACL", + NULL +}; +/* }}} */ - return SUCCESS; +/* {{{ static inline char *http_curl_copystr(char *) */ +static inline char *_http_curl_copystr(const char *str TSRMLS_DC) +{ + char *new_str = estrdup(str); + zend_llist_add_element(&HTTP_G(to_free), &new_str); + return new_str; } +/* }}} */ -/* {{{ STATUS http_post_data_ex(CURL *, char *, char *, size_t, HashTable *, HashTable *, phpstr *) */ -PHP_HTTP_API STATUS _http_post_data_ex(CURL *ch, const char *URL, char *postdata, - size_t postdata_len, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) +/* {{{ static size_t http_curl_write_callback(char *, size_t, size_t, void *) */ +static size_t http_curl_write_callback(char *buf, size_t len, size_t n, void *s) { - zend_bool clean_curl = 0; + return s ? phpstr_append(PHPSTR(s), buf, len * n) : len * n; +} +/* }}} */ - http_curl_startup(ch, clean_curl, URL, options, response); - curl_easy_setopt(ch, CURLOPT_POST, 1); - curl_easy_setopt(ch, CURLOPT_POSTFIELDS, postdata); - curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, postdata_len); - http_curl_perform(ch, clean_curl, response); +/* {{{ 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) +{ + static char *offset = NULL, *original = NULL; + http_request_body *body = (http_request_body *) s; - if (info) { - http_curl_getinfo(ch, info); - } + switch (body->type) + { + case HTTP_REQUEST_BODY_UPLOADFILE: + { + TSRMLS_FETCH(); + return php_stream_read((php_stream *) body->data, data, len * n); + } + break; - http_curl_cleanup(ch, clean_curl, response); + case HTTP_REQUEST_BODY_UPLOADDATA: + { + size_t avail; + if (original != s) { + original = offset = s; + } + if ((avail = body->size - (offset - original)) < 1) { + return 0; + } + if (avail < (len * n)) { + memcpy(data, offset, avail); + offset += avail; + return avail; + } else { + memcpy(data, offset, len * n); + offset += len * n; + return len * n; + } + } + break; - return SUCCESS; + default: + return 0; + break; + } } /* }}} */ -/* {{{ STATUS http_post_array_ex(CURL *, char *, HashTable *, HashTable *, HashTable *, phpstr *) */ -PHP_HTTP_API STATUS _http_post_array_ex(CURL *ch, const char *URL, HashTable *postarray, - HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) +/* {{{ 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) { - STATUS status; - char *encoded; - size_t encoded_len; + zval *params_pass[4], params_local[4], retval, *func = (zval *) data; + TSRMLS_FETCH(); - if (SUCCESS != http_urlencode_hash_ex(postarray, 1, NULL, 0, &encoded, &encoded_len)) { - http_error(E_WARNING, HTTP_E_ENCODE, "Could not encode post data"); - return FAILURE; - } + params_pass[0] = ¶ms_local[0]; + params_pass[1] = ¶ms_local[1]; + params_pass[2] = ¶ms_local[2]; + params_pass[3] = ¶ms_local[3]; - status = http_post_data_ex(ch, URL, encoded, encoded_len, options, info, response); - efree(encoded); + ZVAL_DOUBLE(params_pass[0], dltotal); + ZVAL_DOUBLE(params_pass[1], dlnow); + ZVAL_DOUBLE(params_pass[2], ultotal); + ZVAL_DOUBLE(params_pass[3], ulnow); - return status; + return call_user_function(EG(function_table), NULL, func, &retval, 4, params_pass TSRMLS_CC); } /* }}} */ -/* {{{ STATUS http_post_curldata_ex(CURL *, char *, curl_httppost *, HashTable *, HashTable *, phpstr *) */ -PHP_HTTP_API STATUS _http_post_curldata_ex(CURL *ch, const char *URL, struct curl_httppost *curldata, - HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) +static int http_curl_debug_callback(CURL *ch, curl_infotype type, char *string, size_t length, void *data) { - zend_bool clean_curl = 0; + zval *params_pass[2], params_local[2], retval, *func = (zval *) data; + TSRMLS_FETCH(); - http_curl_startup(ch, clean_curl, URL, options, response); - curl_easy_setopt(ch, CURLOPT_POST, 1); - curl_easy_setopt(ch, CURLOPT_HTTPPOST, curldata); - http_curl_perform(ch, clean_curl, response); + params_pass[0] = ¶ms_local[0]; + params_pass[1] = ¶ms_local[1]; + + ZVAL_LONG(params_pass[0], type); + ZVAL_STRINGL(params_pass[1], string, length, 1); + + call_user_function(EG(function_table), NULL, func, &retval, 2, params_pass TSRMLS_CC); + + return 0; +} +/* {{{ static inline zval *http_curl_getopt(HashTable *, char *, size_t, int) */ +static inline zval *_http_curl_getopt_ex(HashTable *options, char *key, size_t keylen, int type TSRMLS_DC) +{ + zval **zoption; - if (info) { - http_curl_getinfo(ch, info); + if (!options || (SUCCESS != zend_hash_find(options, key, keylen, (void **) &zoption))) { + return NULL; } - http_curl_cleanup(ch, clean_curl, response); + if (Z_TYPE_PP(zoption) != type) { + switch (type) + { + case IS_BOOL: convert_to_boolean_ex(zoption); break; + case IS_LONG: convert_to_long_ex(zoption); break; + case IS_DOUBLE: convert_to_double_ex(zoption); break; + case IS_STRING: convert_to_string_ex(zoption); break; + case IS_ARRAY: convert_to_array_ex(zoption); break; + case IS_OBJECT: convert_to_object_ex(zoption); break; + default: + break; + } + } - return SUCCESS; + return *zoption; } /* }}} */ @@ -648,3 +770,4 @@ PHP_HTTP_API STATUS _http_post_curldata_ex(CURL *ch, const char *URL, struct cur * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ + diff --git a/http_request_object.c b/http_request_object.c index 64a76ef..2cfe21a 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -31,6 +31,7 @@ #include "php_http_std_defs.h" #include "php_http_request_object.h" +#include "php_http_request_api.h" #ifdef ZEND_ENGINE_2 #ifdef HTTP_HAVE_CURL @@ -97,9 +98,40 @@ static zend_object_handlers http_request_object_handlers; void _http_request_object_init(INIT_FUNC_ARGS) { HTTP_REGISTER_CLASS_EX(HttpRequest, http_request_object, NULL, 0); + + /* HTTP/1.1 */ HTTP_LONG_CONSTANT("HTTP_GET", HTTP_GET); HTTP_LONG_CONSTANT("HTTP_HEAD", HTTP_HEAD); HTTP_LONG_CONSTANT("HTTP_POST", HTTP_POST); + HTTP_LONG_CONSTANT("HTTP_PUT", HTTP_PUT); + HTTP_LONG_CONSTANT("HTTP_DELETE", HTTP_DELETE); + HTTP_LONG_CONSTANT("HTTP_OPTIONS", HTTP_OPTIONS); + HTTP_LONG_CONSTANT("HTTP_TRACE", HTTP_TRACE); + HTTP_LONG_CONSTANT("HTTP_CONNECT", HTTP_CONNECT); + /* WebDAV - RFC 2518 */ + HTTP_LONG_CONSTANT("HTTP_PROPFIND", HTTP_PROPFIND); + HTTP_LONG_CONSTANT("HTTP_PROPPATCH", HTTP_PROPPATCH); + HTTP_LONG_CONSTANT("HTTP_MKCOL", HTTP_MKCOL); + HTTP_LONG_CONSTANT("HTTP_COPY", HTTP_COPY); + HTTP_LONG_CONSTANT("HTTP_MOVE", HTTP_MOVE); + HTTP_LONG_CONSTANT("HTTP_LOCK", HTTP_LOCK); + HTTP_LONG_CONSTANT("HTTP_UNLOCK", HTTP_UNLOCK); + /* WebDAV Versioning - RFC 3253 */ + HTTP_LONG_CONSTANT("HTTP_VERSION_CONTROL", HTTP_VERSION_CONTROL); + HTTP_LONG_CONSTANT("HTTP_REPORT", HTTP_REPORT); + HTTP_LONG_CONSTANT("HTTP_CHECKOUT", HTTP_CHECKOUT); + HTTP_LONG_CONSTANT("HTTP_CHECKIN", HTTP_CHECKIN); + HTTP_LONG_CONSTANT("HTTP_UNCHECKOUT", HTTP_UNCHECKOUT); + HTTP_LONG_CONSTANT("HTTP_MKWORKSPACE", HTTP_MKWORKSPACE); + HTTP_LONG_CONSTANT("HTTP_UPDATE", HTTP_UPDATE); + HTTP_LONG_CONSTANT("HTTP_LABEL", HTTP_LABEL); + HTTP_LONG_CONSTANT("HTTP_MERGE", HTTP_MERGE); + HTTP_LONG_CONSTANT("HTTP_BASELINE_CONTROL", HTTP_BASELINE_CONTROL); + HTTP_LONG_CONSTANT("HTTP_MKACTIVITY", HTTP_MKACTIVITY); + /* WebDAV Access Control - RFC 3744 */ + HTTP_LONG_CONSTANT("HTTP_ACL", HTTP_ACL); + + # if LIBCURL_VERSION_NUM >= 0x070a05 HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC); HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST); diff --git a/http_util_object.c b/http_util_object.c index 0c6ccf7..bae9119 100644 --- a/http_util_object.c +++ b/http_util_object.c @@ -42,6 +42,15 @@ ZEND_BEGIN_ARG_INFO(http_request_info_ref_4, 0) ZEND_ARG_PASS_INFO(0) ZEND_ARG_PASS_INFO(1) ZEND_END_ARG_INFO(); + +static +ZEND_BEGIN_ARG_INFO(http_request_info_ref_5, 0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(0) + ZEND_ARG_PASS_INFO(1) +ZEND_END_ARG_INFO(); #endif /* HTTP_HAVE_CURL */ zend_class_entry *http_util_object_ce; @@ -68,7 +77,7 @@ zend_function_entry http_util_object_fe[] = { HTTP_UTIL_ME(get, http_get, http_request_info_ref_3) HTTP_UTIL_ME(head, http_head, http_request_info_ref_3) HTTP_UTIL_ME(postData, http_post_data, http_request_info_ref_4) - HTTP_UTIL_ME(postArray, http_post_array, http_request_info_ref_4) + HTTP_UTIL_ME(postFields, http_post_fields, http_request_info_ref_5) #endif /* HTTP_HAVE_CURL */ HTTP_UTIL_ME(authBasic, http_auth_basic, NULL) HTTP_UTIL_ME(authBasicCallback, http_auth_basic_cb, NULL) diff --git a/package.xml b/package.xml index 29972c2..5e8ebd1 100644 --- a/package.xml +++ b/package.xml @@ -1,95 +1,95 @@ - - - - pecl_http - Extended HTTP support - - - - PHP License 3.0 - - - - mike - Michael Wallner - mike@php.net - lead - - - - - 0.8.0dev - 2005-05-00 - beta - - - - - - - CREDITS - EXPERIMENTAL - docs/functions.html - - http.dsp - config.w32 - config.m4 - - phpstr/phpstr.h - phpstr/phpstr.c - - php_http.h - php_http_std_defs.h - php_http_api.h - php_http_auth_api.h - php_http_cache_api.h - php_http_curl_api.h - php_http_date_api.h - php_http_headers_api.h - php_http_message_api.h - php_http_send_api.h - php_http_url_api.h - php_http_util_object.h - php_http_message_object.h - php_http_request_object.h - php_http_response_object.h - php_http_exception_object.h - - http.c - http_functions.c - http_methods.c - http_api.c - http_auth_api.c - http_cache_api.c - http_curl_api.c - http_Date_api.c - http_headers_api.c - http_message_api.c - http_send_api.c - http_url_api.c - http_util_object.c - http_message_object.c - http_request_object.c - http_response_object.c - http_exception_object.c - - - - - + + + + pecl_http + Extended HTTP support + + + + PHP License 3.0 + + + + mike + Michael Wallner + mike@php.net + lead + + + + + 0.8.0dev + 2005-05-00 + beta + + + + + + + CREDITS + EXPERIMENTAL + docs/functions.html + + http.dsp + config.w32 + config.m4 + + phpstr/phpstr.h + phpstr/phpstr.c + + php_http.h + php_http_std_defs.h + php_http_api.h + php_http_auth_api.h + php_http_cache_api.h + php_http_date_api.h + php_http_headers_api.h + php_http_message_api.h + php_http_request_api.h + php_http_send_api.h + php_http_url_api.h + php_http_util_object.h + php_http_message_object.h + php_http_request_object.h + php_http_response_object.h + php_http_exception_object.h + + http.c + http_functions.c + http_methods.c + http_api.c + http_auth_api.c + http_cache_api.c + http_date_api.c + http_headers_api.c + http_message_api.c + http_request_api.c + http_send_api.c + http_url_api.c + http_util_object.c + http_message_object.c + http_request_object.c + http_response_object.c + http_exception_object.c + + + + + diff --git a/php_http.h b/php_http.h index c2c8b10..59189a9 100644 --- a/php_http.h +++ b/php_http.h @@ -83,7 +83,7 @@ PHP_FUNCTION(http_get_request_headers); PHP_FUNCTION(http_get); PHP_FUNCTION(http_head); PHP_FUNCTION(http_post_data); -PHP_FUNCTION(http_post_array); +PHP_FUNCTION(http_post_fields); #endif /* HTTP_HAVE_CURL */ PHP_FUNCTION(http_auth_basic); PHP_FUNCTION(http_auth_basic_cb); diff --git a/php_http_curl_api.h b/php_http_curl_api.h deleted file mode 100644 index df6f267..0000000 --- a/php_http_curl_api.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PECL :: http | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, that | - | is bundled with this package in the file LICENSE, and is available | - | through the world-wide-web at http://www.php.net/license/3_0.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. | - +----------------------------------------------------------------------+ - | Copyright (c) 2004-2005 Michael Wallner | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#ifndef PHP_HTTP_CURL_API_H -#define PHP_HTTP_CURL_API_H - -#include "php_http_std_defs.h" -#include "phpstr/phpstr.h" - -#ifdef PHP_WIN32 -# include -#endif - -#include - -#define http_get(u, o, i, r) _http_get_ex(NULL, (u), (o), (i), (r) TSRMLS_CC) -#define http_get_ex(c, u, o, i, r) _http_get_ex((c), (u), (o), (i), (r) TSRMLS_CC) -PHP_HTTP_API STATUS _http_get_ex(CURL *ch, const char *URL, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); - -#define http_head(u, o, i, r) _http_head_ex(NULL, (u), (o), (i), (r) TSRMLS_CC) -#define http_head_ex(c, u, o, i, r) _http_head_ex((c), (u), (o), (i), (r) TSRMLS_CC) -PHP_HTTP_API STATUS _http_head_ex(CURL *ch, const char *URL, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); - -#define http_post_data(u, pd, pl, o, i, r) _http_post_data_ex(NULL, (u), (pd), (pl), (o), (i), (r) TSRMLS_CC) -#define http_post_data_ex(c, u, pd, pl, o, i, r) _http_post_data_ex((c), (u), (pd), (pl), (o), (i), (r) TSRMLS_CC) -PHP_HTTP_API STATUS _http_post_data_ex(CURL *ch, const char *URL, char *postdata, size_t postdata_len, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); - -#define http_post_array(u, p, o, i, r) _http_post_array_ex(NULL, (u), (p), (o), (i), (r) TSRMLS_CC) -#define http_post_array_ex(c, u, p, o, i, r) _http_post_array_ex((c), (u), (p), (o), (i), (r) TSRMLS_CC) -PHP_HTTP_API STATUS _http_post_array_ex(CURL *ch, const char *URL, HashTable *postarray, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); - -#define http_post_curldata(u, h, o, i, r) _http_post_curldata_ex(NULL, (u), (h), (o), (i), (r) TSRMLS_CC) -#define http_post_curldata_ex(c, u, h, o, i, r) _http_post_curldata_ex((c), (u), (h), (o), (i), (r) TSRMLS_CC) -PHP_HTTP_API STATUS _http_post_curldata_ex(CURL *ch, const char *URL, struct curl_httppost *curldata, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); - -#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/php_http_request_api.h b/php_http_request_api.h new file mode 100644 index 0000000..0b82d66 --- /dev/null +++ b/php_http_request_api.h @@ -0,0 +1,108 @@ +/* + +----------------------------------------------------------------------+ + | PECL :: http | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, that | + | is bundled with this package in the file LICENSE, and is available | + | through the world-wide-web at http://www.php.net/license/3_0.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. | + +----------------------------------------------------------------------+ + | Copyright (c) 2004-2005 Michael Wallner | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_HTTP_REQUEST_API_H +#define PHP_HTTP_REQUEST_API_H + +#include "php_http_std_defs.h" +#include "phpstr/phpstr.h" + +#ifdef PHP_WIN32 +# include +#endif + +#include + +typedef enum { + HTTP_NO_REQUEST_METHOD = 0, + /* HTTP/1.1 */ + HTTP_GET = 1, + HTTP_HEAD = 2, + HTTP_POST = 3, + HTTP_PUT = 4, + HTTP_DELETE = 5, + HTTP_OPTIONS = 6, + HTTP_TRACE = 7, + HTTP_CONNECT = 8, + /* WebDAV - RFC 2518 */ + HTTP_PROPFIND = 9, + HTTP_PROPPATCH = 10, + HTTP_MKCOL = 11, + HTTP_COPY = 12, + HTTP_MOVE = 13, + HTTP_LOCK = 14, + HTTP_UNLOCK = 15, + /* WebDAV Versioning - RFC 3253 */ + HTTP_VERSION_CONTROL = 16, + HTTP_REPORT = 17, + HTTP_CHECKOUT = 18, + HTTP_CHECKIN = 19, + HTTP_UNCHECKOUT = 20, + HTTP_MKWORKSPACE = 21, + HTTP_UPDATE = 22, + HTTP_LABEL = 23, + HTTP_MERGE = 24, + HTTP_BASELINE_CONTROL = 25, + HTTP_MKACTIVITY = 26, + /* WebDAV Access Control - RFC 3744 */ + HTTP_ACL = 27, + HTTP_MAX_REQUEST_METHOD = 28 +} http_request_method; + +#define HTTP_REQUEST_BODY_CSTRING 0 +#define HTTP_REQUEST_BODY_CURLPOST 1 +#define HTTP_REQUEST_BODY_UPLOADFILE 2 +#define HTTP_REQUEST_BODY_UPLOADDATA 3 +typedef struct { + int type; + void *data; + size_t size; +} http_request_body; + +#define http_request_method_string(m) _http_request_method((m)) +PHP_HTTP_API const char *_http_request_method_string(http_request_method m); + +#define http_request_body_fill(b, fields, files) _http_request_body_fill((b), (fields), (files) TSRMLS_CC) +PHP_HTTP_API _http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files TSRMLS_DC); + +#define http_request_body_dtor(b) _http_request_body_dtor((b) TSRMLS_CC) +PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC); + +#define http_request(meth, url, body, opt, info, resp) _http_request_ex(NULL, (meth), (url), (body), (opt), (info), (resp) TSRMLS_CC) +#define http_request_ex(ch, meth, url, body, opt, info, resp) _http_request_ex((ch), (meth), (url), (body), (opt), (info), (resp) TSRMLS_CC) +PHP_HTTP_API STATUS _http_request_ex(CURL *ch, http_request_method meth, const char *URL, http_request_body *body, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC); + +#define http_get(u, o, i, r) _http_request_ex(NULL, HTTP_GET, (u), NULL, (o), (i), (r) TSRMLS_CC) +#define http_get_ex(c, u, o, i, r) _http_request_ex((c), HTTP_GET, (u), NULL, (o), (i), (r) TSRMLS_CC) + +#define http_head(u, o, i, r) _http_request_ex(NULL, HTTP_HEAD, (u), NULL, (o), (i), (r) TSRMLS_CC) +#define http_head_ex(c, u, o, i, r) _http_request_ex((c), HTTP_HEAD, (u), NULL, (o), (i), (r) TSRMLS_CC) + +#define http_post(u, b, o, i, r) _http_request_ex(NULL, HTTP_POST, (u), (b), (o), (i), (r) TSRMLS_CC) +#define http_post_ex(c, u, b, o, i, r) _http_request_ex((c), HTTP_POST, (u), (b), (o), (i), (r) TSRMLS_CC) + +#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/php_http_request_object.h b/php_http_request_object.h index 9af6e8b..a845857 100644 --- a/php_http_request_object.h +++ b/php_http_request_object.h @@ -34,12 +34,6 @@ typedef struct { phpstr response; } http_request_object; -typedef enum { - HTTP_GET = 1, - HTTP_HEAD, - HTTP_POST, -} http_request_method; - extern zend_class_entry *http_request_object_ce; extern zend_function_entry http_request_object_fe[]; diff --git a/php_http_std_defs.h b/php_http_std_defs.h index 186a8b0..ab80130 100644 --- a/php_http_std_defs.h +++ b/php_http_std_defs.h @@ -155,7 +155,7 @@ typedef int STATUS; } /* }}} */ -#define HTTP_LONG_CONSTANT(name, const) REGISTER_LONG_CONSTANT(name, const, CONST_CS | CONST_PERSISTENT); +#define HTTP_LONG_CONSTANT(name, const) REGISTER_LONG_CONSTANT(name, const, CONST_CS | CONST_PERSISTENT) /* {{{ objects & properties */ #ifdef ZEND_ENGINE_2 diff --git a/phpstr/phpstr.h b/phpstr/phpstr.h index cb7d06a..2dc6fe1 100644 --- a/phpstr/phpstr.h +++ b/phpstr/phpstr.h @@ -31,6 +31,8 @@ #define RETURN_PHPSTR_PTR(STR) RETURN_PHPSTR((STR), PHPSTR_FREE_PTR, 0) #define RETURN_PHPSTR_VAL(STR) RETURN_PHPSTR(&(STR), PHPSTR_FREE_NOT, 0) +#define RETVAL_PHPSTR_PTR(STR) RETVAL_PHPSTR((STR), PHPSTR_FREE_PTR, 0) +#define RETVAL_PHPSTR_VAL(STR) RETVAL_PHPSTR(&(STR), PHPSTR_FREE_NOT, 0) /* RETURN_PHPSTR(buf, PHPSTR_FREE_PTR, 0) */ #define RETURN_PHPSTR(STR, free, dup) \ RETVAL_PHPSTR((STR), (free), (dup)); \ diff --git a/tests/skip.inc b/tests/skip.inc index 64dba34..f27d355 100644 --- a/tests/skip.inc +++ b/tests/skip.inc @@ -1,4 +1,4 @@ - \ No newline at end of file +?> -- 2.30.2