From b08947e98f1832091c8a9f6dea3799e0524d2822 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 29 Jul 2005 08:57:37 +0000 Subject: [PATCH] - fix INI entries - add INI entry http.only_exceptions - use custom error codes so that http.only_exceptions is honored - introduce several different exception classes - use http_curl_conv struct for the curl callback --- KnownIssues.txt | 1 - http.c | 9 +++-- http_api.c | 6 ++-- http_exception_object.c | 66 +++++++++++++++++++++++++++++++------ http_functions.c | 11 +++---- http_headers_api.c | 7 ++-- http_message_api.c | 9 +++-- http_message_object.c | 30 +++++++++-------- http_request_api.c | 54 ++++++++++++++++++++---------- http_request_object.c | 14 ++++---- http_request_pool_api.c | 30 ++++++++++++----- http_response_object.c | 10 +++--- http_send_api.c | 8 ++--- http_url_api.c | 10 +++--- php_http.h | 4 +++ php_http_request_api.h | 13 +++++++- php_http_request_pool_api.h | 3 ++ php_http_std_defs.h | 35 ++++++++++++++------ tests/INI_001.phpt | 9 ++--- tests/run-tests.diff | 2 +- 20 files changed, 224 insertions(+), 107 deletions(-) diff --git a/KnownIssues.txt b/KnownIssues.txt index dfb4e6f..339ea9f 100644 --- a/KnownIssues.txt +++ b/KnownIssues.txt @@ -4,6 +4,5 @@ $Id$ Issues I don't know how to solve yet are as follows: -- INI entry allowed_methods is not working properly - Reflection on static class members does not work diff --git a/http.c b/http.c index 3b05887..0acb05c 100644 --- a/http.c +++ b/http.c @@ -139,6 +139,7 @@ static inline void http_globals_init(zend_http_globals *G) zend_llist_init(&G->request.copies.strings, sizeof(char *), http_request_data_free_string, 0); zend_llist_init(&G->request.copies.slists, sizeof(struct curl_slist *), http_request_data_free_slist, 0); zend_llist_init(&G->request.copies.contexts, sizeof(http_curl_callback_ctx *), http_request_data_free_context, 0); + zend_llist_init(&G->request.copies.convs, sizeof(http_curl_conv *), http_request_data_free_conv, 0); #endif } @@ -151,6 +152,7 @@ static inline void http_globals_free(zend_http_globals *G) zend_llist_clean(&G->request.copies.strings); zend_llist_clean(&G->request.copies.slists); zend_llist_clean(&G->request.copies.contexts); + zend_llist_clean(&G->request.copies.convs); #endif } /* }}} */ @@ -177,8 +179,11 @@ PHP_INI_MH(http_update_allowed_methods) } PHP_INI_BEGIN() - HTTP_PHP_INI_ENTRY("http.allowed_methods", NULL, PHP_INI_ALL, http_update_allowed_methods, request.methods.allowed) - HTTP_PHP_INI_ENTRY("http.cache_log", NULL, PHP_INI_ALL, OnUpdateString, log.cache) + HTTP_PHP_INI_ENTRY("http.allowed_methods", "", PHP_INI_ALL, http_update_allowed_methods, request.methods.allowed) + HTTP_PHP_INI_ENTRY("http.cache_log", "", PHP_INI_ALL, OnUpdateString, log.cache) +#ifdef ZEND_ENGINE_2 + HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions) +#endif PHP_INI_END() /* }}} */ diff --git a/http_api.c b/http_api.c index e54974f..8e683a1 100644 --- a/http_api.c +++ b/http_api.c @@ -182,7 +182,7 @@ void _http_error_ex(long type, long code, const char *format, ...) STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRMLS_DC) { if (SUCCESS != http_send_status_header(status, header)) { - http_error_ex(E_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : ""); + http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : ""); if (free_header && header) { efree(header); } @@ -273,10 +273,10 @@ PHP_HTTP_API const char *_http_chunked_decode(const char *encoded, size_t encode } else { efree(*decoded); if (no_crlf) { - http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid character (expected 0x0D 0x0A; got: 0x%x 0x%x)", *n_ptr, *(n_ptr + 1)); + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0D 0x0A; got: 0x%x 0x%x)", *n_ptr, *(n_ptr + 1)); } else { char *error = estrndup(n_ptr, strcspn(n_ptr, "\r\n \0")); - http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded); + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded); efree(error); } diff --git a/http_exception_object.c b/http_exception_object.c index af84046..a35eb0e 100644 --- a/http_exception_object.c +++ b/http_exception_object.c @@ -29,22 +29,50 @@ #include "php_http_std_defs.h" #include "php_http_exception_object.h" +#define HTTP_EX_DEF_CE http_exception_object_ce zend_class_entry *http_exception_object_ce; -zend_function_entry http_exception_object_fe[] = {{NULL, NULL, NULL}}; +#define HTTP_EX_CE(name) http_ ##name## _exception_object_ce +zend_class_entry *HTTP_EX_CE(runtime); +zend_class_entry *HTTP_EX_CE(header); +zend_class_entry *HTTP_EX_CE(malformed_headers); +zend_class_entry *HTTP_EX_CE(request_method); +zend_class_entry *HTTP_EX_CE(message_type); +zend_class_entry *HTTP_EX_CE(invalid_param); +zend_class_entry *HTTP_EX_CE(encoding); +zend_class_entry *HTTP_EX_CE(request); +zend_class_entry *HTTP_EX_CE(request_pool); +zend_class_entry *HTTP_EX_CE(socket); +zend_class_entry *HTTP_EX_CE(response); +zend_class_entry *HTTP_EX_CE(url); void _http_exception_object_init(INIT_FUNC_ARGS) { - HTTP_REGISTER_CLASS(HttpException, http_exception_object, zend_exception_get_default(), 0); + HTTP_REGISTER_EXCEPTION(HttpException, http_exception_object_ce, zend_exception_get_default()); + HTTP_REGISTER_EXCEPTION(HttpRuntimeException, HTTP_EX_CE(runtime), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpInvalidParamException, HTTP_EX_CE(invalid_param), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpHeaderException, HTTP_EX_CE(header), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpMalformedHeadersException, HTTP_EX_CE(malformed_headers), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpRequestMethodException, HTTP_EX_CE(request_method), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpMessageTypeException, HTTP_EX_CE(message_type), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpEncodingException, HTTP_EX_CE(encoding), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpRequestException, HTTP_EX_CE(request), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpRequestPoolException, HTTP_EX_CE(request_pool), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpSocketException, HTTP_EX_CE(socket), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpResponseException, HTTP_EX_CE(response), HTTP_EX_DEF_CE); + HTTP_REGISTER_EXCEPTION(HttpUrlException, HTTP_EX_CE(url), HTTP_EX_DEF_CE); - HTTP_LONG_CONSTANT("HTTP_E_UNKNOWN", HTTP_E_UNKOWN); - HTTP_LONG_CONSTANT("HTTP_E_PARSE", HTTP_E_PARSE); + HTTP_LONG_CONSTANT("HTTP_E_RUNTIME", HTTP_E_RUNTIME); + HTTP_LONG_CONSTANT("HTTP_E_INVALID_PARAM", HTTP_E_INVALID_PARAM); HTTP_LONG_CONSTANT("HTTP_E_HEADER", HTTP_E_HEADER); - HTTP_LONG_CONSTANT("HTTP_E_OBUFFER", HTTP_E_OBUFFER); - HTTP_LONG_CONSTANT("HTTP_E_CURL", HTTP_E_CURL); - HTTP_LONG_CONSTANT("HTTP_E_ENCODE", HTTP_E_ENCODE); - HTTP_LONG_CONSTANT("HTTP_E_PARAM", HTTP_E_PARAM); + HTTP_LONG_CONSTANT("HTTP_E_MALFORMED_HEADERS", HTTP_E_MALFORMED_HEADERS); + HTTP_LONG_CONSTANT("HTTP_E_REQUEST_METHOD", HTTP_E_REQUEST_METHOD); + HTTP_LONG_CONSTANT("HTTP_E_MESSAGE_TYPE", HTTP_E_MESSAGE_TYPE); + HTTP_LONG_CONSTANT("HTTP_E_ENCODING", HTTP_E_ENCODING); + HTTP_LONG_CONSTANT("HTTP_E_REQUEST", HTTP_E_REQUEST); + HTTP_LONG_CONSTANT("HTTP_E_REQUEST_POOL", HTTP_E_REQUEST_POOL); + HTTP_LONG_CONSTANT("HTTP_E_SOCKET", HTTP_E_SOCKET); + HTTP_LONG_CONSTANT("HTTP_E_RESPONSE", HTTP_E_RESPONSE); HTTP_LONG_CONSTANT("HTTP_E_URL", HTTP_E_URL); - HTTP_LONG_CONSTANT("HTTP_E_MSG", HTTP_E_MSG); } zend_class_entry *_http_exception_get_default() @@ -54,7 +82,25 @@ zend_class_entry *_http_exception_get_default() zend_class_entry *_http_exception_get_for_code(long code) { - return http_exception_object_ce; + zend_class_entry *ex = http_exception_object_ce; + + switch (code) + { + case HTTP_E_RUNTIME: ex = HTTP_EX_CE(runtime); break; + case HTTP_E_INVALID_PARAM: ex = HTTP_EX_CE(invalid_param); break; + case HTTP_E_HEADER: ex = HTTP_EX_CE(header); break; + case HTTP_E_MALFORMED_HEADERS: ex = HTTP_EX_CE(malformed_headers); break; + case HTTP_E_REQUEST_METHOD: ex = HTTP_EX_CE(request_method); break; + case HTTP_E_MESSAGE_TYPE: ex = HTTP_EX_CE(message_type); break; + case HTTP_E_ENCODING: ex = HTTP_EX_CE(encoding); break; + case HTTP_E_REQUEST: ex = HTTP_EX_CE(request); break; + case HTTP_E_REQUEST_POOL: ex = HTTP_EX_CE(request_pool); break; + case HTTP_E_SOCKET: ex = HTTP_EX_CE(socket); break; + case HTTP_E_RESPONSE: ex = HTTP_EX_CE(response); break; + case HTTP_E_URL: ex = HTTP_EX_CE(url); break; + } + + return ex; } #endif diff --git a/http_functions.c b/http_functions.c index e9cd9f7..737ae32 100644 --- a/http_functions.c +++ b/http_functions.c @@ -202,7 +202,7 @@ PHP_FUNCTION(http_send_status) RETURN_FALSE; } if (status < 100 || status > 510) { - http_error_ex(E_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status); + http_error_ex(HE_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status); RETURN_FALSE; } @@ -474,7 +474,7 @@ PHP_FUNCTION(http_redirect) array_init(params); } if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) { - http_error(E_WARNING, HTTP_E_ENCODE, "Could not append session information"); + http_error(HE_WARNING, HTTP_E_RUNTIME, "Could not append session information"); } } @@ -618,7 +618,6 @@ PHP_FUNCTION(http_split_response) array_init(zheaders); if (SUCCESS != http_split_response(response, response_len, Z_ARRVAL_P(zheaders), &body, &body_len)) { - http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP response"); RETURN_FALSE; } @@ -642,7 +641,6 @@ PHP_FUNCTION(http_parse_headers) array_init(return_value); if (SUCCESS != http_parse_headers(header, return_value)) { - http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP headers"); zval_dtor(return_value); RETURN_FALSE; } @@ -1227,7 +1225,7 @@ PHP_FUNCTION(http_build_query) } if (Z_TYPE_P(formdata) != IS_ARRAY && Z_TYPE_P(formdata) != IS_OBJECT) { - http_error(E_WARNING, HTTP_E_PARAM, "Parameter 1 expected to be Array or Object. Incorrect value given."); + http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Parameter 1 expected to be Array or Object. Incorrect value given."); RETURN_FALSE; } @@ -1254,7 +1252,7 @@ PHP_FUNCTION(http_build_query) PHP_FUNCTION(http_test) { - RETURN_NULL(); + RETURN_BOOL(HTTP_G(only_exceptions)); } /* @@ -1265,3 +1263,4 @@ PHP_FUNCTION(http_test) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ + diff --git a/http_headers_api.c b/http_headers_api.c index f59ba16..11815f2 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -30,6 +30,8 @@ #include +ZEND_EXTERN_MODULE_GLOBALS(http); + /* {{{ static int http_sort_q(const void *, const void *) */ static int http_sort_q(const void *a, const void *b TSRMLS_DC) { @@ -112,9 +114,6 @@ PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_ range = Z_STRVAL_P(zrange); if (strncmp(range, "bytes=", sizeof("bytes=") - 1)) { - /* should we really issue a notice for a client misbehaviour? - http_error(E_NOTICE, HTTP_E_HEADER, "Range header misses bytes="); - */ return RANGE_NO; } @@ -258,7 +257,7 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *header if (header_len < 2 || !strchr(header, ':')) { - http_error(E_WARNING, HTTP_E_PARSE, "Cannot parse too short or malformed HTTP headers"); + http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Cannot parse too short or malformed HTTP headers"); return FAILURE; } diff --git a/http_message_api.c b/http_message_api.c index e4ded1e..3dc2341 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -31,6 +31,8 @@ #include "phpstr/phpstr.h" +ZEND_EXTERN_MODULE_GLOBALS(http); + #define http_message_headers_cb _http_message_headers_cb static void _http_message_headers_cb(const char *http_line, HashTable **headers, void **message TSRMLS_DC) { @@ -382,21 +384,21 @@ PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC) if (!strcasecmp("HEAD", message->info.request.method)) { rs = http_head(uri, Z_ARRVAL(options), NULL, NULL); } else { - http_error_ex(E_WARNING, HTTP_E_MSG, + http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Cannot send HttpMessage. Request method %s not supported", message->info.request.method); } efree(uri); #else - http_error(E_WARNING, HTTP_E_MSG, "HTTP requests not supported - ext/http was not linked against libcurl."); + http_error(HE_WARNING, HTTP_E_RUNTIME, "HTTP requests not supported - ext/http was not linked against libcurl."); #endif } break; case HTTP_MSG_NONE: default: - http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is neither of type HTTP_MSG_REQUEST nor HTTP_MSG_RESPONSE"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is neither of type HTTP_MSG_REQUEST nor HTTP_MSG_RESPONSE"); break; } @@ -456,3 +458,4 @@ 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_message_object.c b/http_message_object.c index 027cbdf..8365a59 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -31,6 +31,8 @@ #include "phpstr/phpstr.h" +ZEND_EXTERN_MODULE_GLOBALS(http); + #define HTTP_BEGIN_ARGS(method, ret_ref, req_args) HTTP_BEGIN_ARGS_EX(HttpMessage, method, ret_ref, req_args) #define HTTP_EMPTY_ARGS(method, ret_ref) HTTP_EMPTY_ARGS_EX(HttpMessage, method, ret_ref) #define HTTP_MESSAGE_ME(method, visibility) PHP_ME(HttpMessage, method, HTTP_ARGS(HttpMessage, method), visibility) @@ -225,7 +227,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type fprintf(stderr, "Read HttpMessage::$%s\n", Z_STRVAL_P(member)); #endif if (!EG(scope) || !instanceof_function(EG(scope), obj->zo.ce TSRMLS_CC)) { - zend_error(E_WARNING, "Cannot access protected property %s::$%s", obj->zo.ce->name, Z_STRVAL_P(member)); + zend_error(HE_WARNING, "Cannot access protected property %s::$%s", obj->zo.ce->name, Z_STRVAL_P(member)); return EG(uninitialized_zval_ptr); } @@ -325,7 +327,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va fprintf(stderr, "Write HttpMessage::$%s\n", Z_STRVAL_P(member)); #endif if (!EG(scope) || !instanceof_function(EG(scope), obj->zo.ce TSRMLS_CC)) { - zend_error(E_WARNING, "Cannot access protected property %s::$%s", obj->zo.ce->name, Z_STRVAL_P(member)); + zend_error(HE_WARNING, "Cannot access protected property %s::$%s", obj->zo.ce->name, Z_STRVAL_P(member)); } switch (zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1)) @@ -648,7 +650,7 @@ PHP_METHOD(HttpMessage, getResponseCode) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(RESPONSE, obj->message)) { - http_error(E_NOTICE, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_RESPONSE"); + http_error(HE_NOTICE, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_RESPONSE"); RETURN_NULL(); } @@ -669,7 +671,7 @@ PHP_METHOD(HttpMessage, setResponseCode) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(RESPONSE, obj->message)) { - http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_RESPONSE"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_RESPONSE"); RETURN_FALSE; } @@ -677,7 +679,7 @@ PHP_METHOD(HttpMessage, setResponseCode) RETURN_FALSE; } if (code < 100 || code > 510) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Invalid response code (100-510): %ld", code); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid response code (100-510): %ld", code); RETURN_FALSE; } @@ -699,7 +701,7 @@ PHP_METHOD(HttpMessage, getRequestMethod) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(REQUEST, obj->message)) { - http_error(E_NOTICE, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_REQUEST"); + http_error(HE_NOTICE, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); RETURN_NULL(); } @@ -720,7 +722,7 @@ PHP_METHOD(HttpMessage, setRequestMethod) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(REQUEST, obj->message)) { - http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_REQUEST"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); RETURN_FALSE; } @@ -728,11 +730,11 @@ PHP_METHOD(HttpMessage, setRequestMethod) RETURN_FALSE; } if (method_len < 1) { - http_error(E_WARNING, HTTP_E_PARAM, "Cannot set HttpMessage::requestMethod to an empty string"); + http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestMethod to an empty string"); RETURN_FALSE; } if (SUCCESS != http_check_method(method)) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Unkown request method: %s", method); + http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unkown request method: %s", method); RETURN_FALSE; } @@ -753,7 +755,7 @@ PHP_METHOD(HttpMessage, getRequestUri) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(REQUEST, obj->message)) { - http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_REQUEST"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); RETURN_NULL(); } @@ -775,14 +777,14 @@ PHP_METHOD(HttpMessage, setRequestUri) getObject(http_message_object, obj); if (!HTTP_MSG_TYPE(REQUEST, obj->message)) { - http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_REQUEST"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); RETURN_FALSE; } if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &URI, &URIlen)) { RETURN_FALSE; } if (URIlen < 1) { - http_error(E_WARNING, HTTP_E_PARAM, "Cannot set HttpMessage::requestUri to an empty string"); + http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestUri to an empty string"); RETURN_FALSE; } @@ -840,14 +842,14 @@ PHP_METHOD(HttpMessage, setHttpVersion) } if (HTTP_MSG_TYPE(NONE, obj->message)) { - http_error(E_WARNING, HTTP_E_MSG, "Message is neither of type HTTP_MSG_RESPONSE nor HTTP_MSG_REQUEST"); + http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "Message is neither of type HTTP_MSG_RESPONSE nor HTTP_MSG_REQUEST"); RETURN_FALSE; } convert_to_double(zv); sprintf(v, "%1.1lf", Z_DVAL_P(zv)); if (strcmp(v, "1.0") && strcmp(v, "1.1")) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Invalid HTTP protocol version (1.0 or 1.1): %s", v); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid HTTP protocol version (1.0 or 1.1): %s", v); RETURN_FALSE; } diff --git a/http_request_api.c b/http_request_api.c index 13a14e4..d2a8445 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -101,12 +101,6 @@ ZEND_EXTERN_MODULE_GLOBALS(http); continue; \ } -typedef struct _http_curl_conv { - phpstr *response; - phpstr *request; - curl_infotype last_info; -} http_curl_conv; - static const char *const http_request_methods[HTTP_MAX_REQUEST_METHOD + 1]; #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) @@ -178,6 +172,12 @@ void *_http_request_data_copy(int type, void *data TSRMLS_DC) return data; } + case COPY_CONV: + { + zend_llist_add_element(&HTTP_G(request).copies.convs, &data); + return data; + } + default: { return data; @@ -207,6 +207,13 @@ void _http_request_data_free_context(void *context) } /* }}} */ +/* {{{ _http_request_data_free_conv(http_curl_conv **) */ +void _http_request_data_free_conv(void *conv) +{ + efree(*((http_curl_conv **) conv)); +} +/* }}} */ + /* {{{ http_request_body *http_request_body_new() */ PHP_HTTP_API http_request_body *_http_request_body_new(TSRMLS_D) { @@ -236,7 +243,7 @@ PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable * CURLFORM_END ); if (CURLE_OK != err) { - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not encode post fields: %s", curl_easy_strerror(err)); + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err)); curl_formfree(http_post_data[0]); return FAILURE; } @@ -260,12 +267,12 @@ PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable * CURLFORM_END ); if (CURLE_OK != err) { - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not encode post files: %s", curl_easy_strerror(err)); + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err)); curl_formfree(http_post_data[0]); return FAILURE; } } else { - http_error(E_NOTICE, HTTP_E_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry"); + http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry"); } } @@ -278,7 +285,7 @@ PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable * size_t encoded_len; 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"); + http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data"); return FAILURE; } @@ -618,7 +625,7 @@ PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, char if (http_request_method_exists(0, meth, NULL)) { curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, http_request_method_name(meth)); } else { - http_error_ex(E_WARNING, HTTP_E_CURL, "Unsupported request method: %d", meth); + http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unsupported request method: %d", meth); return FAILURE; } break; @@ -643,7 +650,8 @@ PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, char break; default: - http_error_ex(E_WARNING, HTTP_E_CURL, "Unknown request body type: %d", body->type); + /* shouldn't ever happen */ + http_error_ex(HE_ERROR, 0, "Unknown request body type: %d", body->type); return FAILURE; break; } @@ -653,17 +661,27 @@ PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, char } /* }}} */ +/* {{{ 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)); + 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))); +} +/* }}} */ + /* {{{ STATUS http_request_exec(CURL *, HashTable *) */ PHP_HTTP_API STATUS _http_request_exec(CURL *ch, HashTable *info, phpstr *response, phpstr *request TSRMLS_DC) { CURLcode result; - http_curl_conv conv = {response, request, -1}; - HTTP_CURL_OPT(DEBUGDATA, http_curl_callback_data(&conv)); + http_request_conv(ch, response, request); /* perform request */ 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_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not perform request: %s", curl_easy_strerror(result)); return FAILURE; } else { /* get curl info */ @@ -737,7 +755,7 @@ PHP_HTTP_API STATUS _http_request_ex(CURL *ch, http_request_method meth, char *u if ((clean_curl = (!ch))) { if (!(ch = curl_easy_init())) { - http_error(E_WARNING, HTTP_E_CURL, "Could not initialize curl."); + http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initialize curl."); return FAILURE; } } @@ -823,7 +841,7 @@ PHP_HTTP_API STATUS _http_request_method_unregister(unsigned long method TSRMLS_ char *http_method; if (SUCCESS != zend_hash_index_find(&HTTP_G(request).methods.custom, HTTP_CUSTOM_REQUEST_METHOD(method), (void **) &zmethod)) { - http_error_ex(E_NOTICE, HTTP_E_PARAM, "Request method with id %lu does not exist", method); + http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Request method with id %lu does not exist", method); return FAILURE; } @@ -831,7 +849,7 @@ PHP_HTTP_API STATUS _http_request_method_unregister(unsigned long method TSRMLS_ if ( (SUCCESS != zend_hash_index_del(&HTTP_G(request).methods.custom, HTTP_CUSTOM_REQUEST_METHOD(method))) || (SUCCESS != zend_hash_del(EG(zend_constants), http_method, strlen(http_method) + 1))) { - http_error_ex(E_NOTICE, 0, "Could not unregister request method: %s", http_method); + http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Could not unregister request method: %s", http_method); efree(http_method); return FAILURE; } diff --git a/http_request_object.c b/http_request_object.c index 638539e..571f521 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -39,6 +39,8 @@ #endif #include +ZEND_EXTERN_MODULE_GLOBALS(http); + #define HTTP_BEGIN_ARGS(method, ret_ref, req_args) HTTP_BEGIN_ARGS_EX(HttpRequest, method, ret_ref, req_args) #define HTTP_EMPTY_ARGS(method, ret_ref) HTTP_EMPTY_ARGS_EX(HttpRequest, method, ret_ref) #define HTTP_REQUEST_ME(method, visibility) PHP_ME(HttpRequest, method, HTTP_ARGS(HttpRequest, method), visibility) @@ -403,7 +405,7 @@ STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ return FAILURE; } if ((!obj->ch) && (!(obj->ch = curl_easy_init()))) { - http_error(E_WARNING, HTTP_E_CURL, "Could not initilaize curl"); + http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initilaize curl"); return FAILURE; } @@ -989,7 +991,7 @@ PHP_METHOD(HttpRequest, setContentType) } if (!strchr(ctype, '/')) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", ctype); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", ctype); RETURN_FALSE; } @@ -1206,7 +1208,7 @@ PHP_METHOD(HttpRequest, addPostFile) if (type_len) { if (!strchr(type, '/')) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", type); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", type); RETURN_FALSE; } } else { @@ -1545,7 +1547,7 @@ PHP_METHOD(HttpRequest, getResponseInfo) if (SUCCESS == zend_hash_find(Z_ARRVAL_P(info), pretty_key(info_name, info_len, 0, 0), info_len + 1, (void **) &infop)) { RETURN_ZVAL(*infop, 1, ZVAL_PTR_DTOR); } else { - http_error_ex(E_NOTICE, HTTP_E_PARAM, "Could not find response info named %s", info_name); + http_error_ex(HE_NOTICE, HTTP_E_INVALID_PARAM, "Could not find response info named %s", info_name); RETURN_FALSE; } } else { @@ -1589,7 +1591,6 @@ PHP_METHOD(HttpRequest, getRequestMessage) NO_ARGS; IF_RETVAL_USED { - zval *message; http_message *msg; getObject(http_request_object, obj); @@ -1607,7 +1608,6 @@ PHP_METHOD(HttpRequest, getHistory) NO_ARGS; IF_RETVAL_USED { - zval *history; http_message *msg; getObject(http_request_object, obj); @@ -1664,7 +1664,7 @@ PHP_METHOD(HttpRequest, send) SET_EH_THROW_HTTP(); if (obj->pool) { - http_error(E_WARNING, HTTP_E_CURL, "Cannot perform HttpRequest::send() while attached to an HttpRequestPool"); + http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot perform HttpRequest::send() while attached to an HttpRequestPool"); SET_EH_NORMAL(); RETURN_FALSE; } diff --git a/http_request_pool_api.c b/http_request_pool_api.c index c9e5278..1775293 100644 --- a/http_request_pool_api.c +++ b/http_request_pool_api.c @@ -34,6 +34,8 @@ # define HTTP_DEBUG_REQPOOLS 0 #endif +ZEND_EXTERN_MODULE_GLOBALS(http); + static void http_request_pool_freebody(http_request_body **body); static int http_request_pool_compare_handles(void *h1, void *h2); @@ -51,7 +53,7 @@ PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool if (!pool->ch) { if (!(pool->ch = curl_multi_init())) { - http_error(E_WARNING, HTTP_E_CURL, "Could not initialize curl"); + http_error(HE_WARNING, HTTP_E_REQUEST, "Could not initialize curl"); if (free_pool) { efree(pool); } @@ -77,17 +79,17 @@ PHP_HTTP_API STATUS _http_request_pool_attach(http_request_pool *pool, zval *req fprintf(stderr, "Attaching HttpRequest(#%d) %p to pool %p\n", Z_OBJ_HANDLE_P(request), req, pool); #endif if (req->pool) { - http_error_ex(E_WARNING, HTTP_E_CURL, "HttpRequest object(#%d) is already member of %s HttpRequestPool", Z_OBJ_HANDLE_P(request), req->pool == pool ? "this" : "another"); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "HttpRequest object(#%d) is already member of %s HttpRequestPool", Z_OBJ_HANDLE_P(request), req->pool == pool ? "this" : "another"); } else { http_request_body *body = http_request_body_new(); - if (SUCCESS != http_request_object_requesthandler(req, request, body)) { - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not initialize HttpRequest object for attaching to the HttpRequestPool"); + if (SUCCESS != http_request_pool_requesthandler(request, body)) { + http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not initialize HttpRequest object for attaching to the HttpRequestPool"); } else { CURLMcode code = curl_multi_add_handle(pool->ch, req->ch); if ((CURLM_OK != code) && (CURLM_CALL_MULTI_PERFORM != code)) { - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not attach HttpRequest object to the HttpRequestPool: %s", curl_multi_strerror(code)); + http_error_ex(HE_WARNING, HTTP_E_REQUEST_POOL, "Could not attach HttpRequest object to the HttpRequestPool: %s", curl_multi_strerror(code)); } else { req->pool = pool; @@ -122,7 +124,7 @@ PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *req fprintf(stderr, "HttpRequest object(#%d) %p is not attached to any HttpRequestPool\n", Z_OBJ_HANDLE_P(request), req); #endif } else if (req->pool != pool) { - http_error_ex(E_WARNING, HTTP_E_CURL, "HttpRequest object(#%d) is not attached to this HttpRequestPool", Z_OBJ_HANDLE_P(request)); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "HttpRequest object(#%d) is not attached to this HttpRequestPool", Z_OBJ_HANDLE_P(request)); } else { CURLMcode code; @@ -132,7 +134,7 @@ PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *req fprintf(stderr, "> %d HttpRequests remaining in pool %p\n", zend_llist_count(&pool->handles), pool); #endif if (CURLM_OK != (code = curl_multi_remove_handle(pool->ch, req->ch))) { - http_error_ex(E_WARNING, HTTP_E_CURL, "Could not detach HttpRequest object from the HttpRequestPool: %s", curl_multi_strerror(code)); + http_error_ex(HE_WARNING, HTTP_E_REQUEST_POOL, "Could not detach HttpRequest object from the HttpRequestPool: %s", curl_multi_strerror(code)); } else { return SUCCESS; } @@ -180,7 +182,7 @@ PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool TSRMLS_DC) fprintf(stderr, "> %d unfinished requests of pool %p remaining\n", pool->unfinished, pool); #endif if (SUCCESS != http_request_pool_select(pool)) { - http_error(E_WARNING, HTTP_E_CURL, "Socket error"); + http_error(HE_WARNING, HTTP_E_SOCKET, "Socket error"); return FAILURE; } } @@ -229,6 +231,18 @@ PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool) } /* }}} */ +/* {{{ STATUS http_request_pool_requesthandler(zval *, http_request_body *) */ +STATUS _http_request_pool_requesthandler(zval *request, http_request_body *body TSRMLS_DC) +{ + getObjectEx(http_request_object, req, request); + if (SUCCESS == http_request_object_requesthandler(req, request, body)) { + http_request_conv(req->ch, &req->response, &req->request); + return SUCCESS; + } + return FAILURE; +} +/* }}} */ + /* {{{ void http_request_pool_responsehandler(zval **) */ void _http_request_pool_responsehandler(zval **req TSRMLS_DC) { diff --git a/http_response_object.c b/http_response_object.c index c95956c..5bdbf14 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -211,8 +211,6 @@ static inline void _http_response_object_declare_default_properties(TSRMLS_D) DCL_STATIC_PROP_N(PROTECTED, contentDisposition); DCL_STATIC_PROP(PROTECTED, long, bufferSize, HTTP_SENDBUF_SIZE); DCL_STATIC_PROP(PROTECTED, double, throttleDelay, 0.0); - - DCL_STATIC_PROP(PUBLIC, string, dummy, "EMPTY"); } /* ### USERLAND ### */ @@ -303,7 +301,7 @@ PHP_METHOD(HttpResponse, setCacheControl) } if (strcmp(ccontrol, "public") && strcmp(ccontrol, "private") && strcmp(ccontrol, "no-cache")) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol); RETURN_FALSE; } else { USE_STATIC_PROP(); @@ -343,7 +341,7 @@ PHP_METHOD(HttpResponse, setContentType) } if (!strchr(ctype, '/')) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Content type '%s' doesn't seem to contain a primary and a secondary part", ctype); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Content type '%s' doesn't seem to contain a primary and a secondary part", ctype); RETURN_FALSE; } @@ -638,13 +636,13 @@ PHP_METHOD(HttpResponse, send) RETURN_FALSE; } if (SG(headers_sent)) { - http_error(E_WARNING, HTTP_E_HEADER, "Cannot send HttpResponse, headers have already been sent"); + http_error(HE_WARNING, HTTP_E_RESPONSE, "Cannot send HttpResponse, headers have already been sent"); RETURN_FALSE; } sent = GET_STATIC_PROP(sent); if (Z_LVAL_P(sent)) { - http_error(E_WARNING, HTTP_E_UNKOWN, "Cannot send HttpResponse, response has already been sent"); + http_error(HE_WARNING, HTTP_E_RESPONSE, "Cannot send HttpResponse, response has already been sent"); RETURN_FALSE; } else { Z_LVAL_P(sent) = 1; diff --git a/http_send_api.c b/http_send_api.c index b89102d..73aa0b6 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -155,7 +155,7 @@ PHP_HTTP_API STATUS _http_send_status_header_ex(int status, const char *header, STATUS ret; sapi_header_line h = {(char *) header, header ? strlen(header) : 0, status}; if (SUCCESS != (ret = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, &h TSRMLS_CC))) { - http_error_ex(E_WARNING, HTTP_E_HEADER, "Could not send header: %s (%d)", header, status); + http_error_ex(HE_WARNING, HTTP_E_HEADER, "Could not send header: %s (%d)", header, status); } return ret; } @@ -186,7 +186,7 @@ PHP_HTTP_API STATUS _http_send_etag(const char *etag, size_t etag_len TSRMLS_DC) char *etag_header; if (!etag_len){ - http_error_ex(E_WARNING, HTTP_E_HEADER, "Attempt to send empty ETag (previous: %s)\n", HTTP_G(send).unquoted_etag); + http_error_ex(HE_WARNING, HTTP_E_HEADER, "Attempt to send empty ETag (previous: %s)\n", HTTP_G(send).unquoted_etag); return FAILURE; } @@ -222,7 +222,7 @@ PHP_HTTP_API STATUS _http_send_content_type(const char *content_type, size_t ct_ char *ct_header; if (!strchr(content_type, '/')) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Content-Type '%s' doesn't seem to consist of a primary and a secondary part", content_type); + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Content-Type '%s' doesn't seem to consist of a primary and a secondary part", content_type); return FAILURE; } @@ -382,7 +382,7 @@ PHP_HTTP_API STATUS _http_send(const void *data_ptr, size_t data_size, http_send char *etag = NULL; if (!(etag = http_etag(data_ptr, data_size, data_mode))) { - http_error(E_NOTICE, HTTP_E_PARAM, "Failed to generate ETag for data source"); + http_error(HE_NOTICE, HTTP_E_RUNTIME, "Failed to generate ETag for data source"); } else { http_send_etag(etag, 32); if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) { diff --git a/http_url_api.c b/http_url_api.c index d3f32e7..e66781f 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -58,14 +58,14 @@ PHP_HTTP_API char *_http_absolute_url_ex( if ((!url || !url_len) && ( (!(url = SG(request_info).request_uri)) || (!(url_len = strlen(SG(request_info).request_uri))))) { - http_error(E_WARNING, HTTP_E_PARAM, "Cannot build an absolute URI if supplied URL and REQUEST_URI is empty"); + http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot build an absolute URI if supplied URL and REQUEST_URI is empty"); return NULL; } URL = ecalloc(1, HTTP_URI_MAXLEN + 1); uri = estrndup(url, url_len); if (!(purl = php_url_parse(uri))) { - http_error_ex(E_WARNING, HTTP_E_PARSE, "Could not parse supplied URL: %s", url); + http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse supplied URL: %s", url); return NULL; } @@ -116,7 +116,7 @@ PHP_HTTP_API char *_http_absolute_url_ex( #define HTTP_URI_STRLCATL(URL, full_len, add_string) HTTP_URI_STRLCAT(URL, full_len, add_string, strlen(add_string)) #define HTTP_URI_STRLCAT(URL, full_len, add_string, add_len) \ if ((full_len += add_len) > HTTP_URI_MAXLEN) { \ - http_error_ex(E_NOTICE, HTTP_E_URL, \ + http_error_ex(HE_NOTICE, HTTP_E_URL, \ "Absolute URI would have exceeded max URI length (%d bytes) - " \ "tried to add %d bytes ('%s')", \ HTTP_URI_MAXLEN, add_len, add_string); \ @@ -223,7 +223,7 @@ PHP_HTTP_API STATUS _http_urlencode_hash_implementation_ex( zval **zdata = NULL, *copyzval; if (!ht || !formstr) { - http_error(E_WARNING, HTTP_E_PARAM, "Invalid parameters"); + http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid parameters"); return FAILURE; } @@ -262,7 +262,7 @@ PHP_HTTP_API STATUS _http_urlencode_hash_implementation_ex( #endif if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) { - http_error(E_WARNING, HTTP_E_ENCODE, "Error traversing form data array."); + http_error(HE_WARNING, HTTP_E_ENCODING, "Error traversing form data array."); return FAILURE; } if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) { diff --git a/php_http.h b/php_http.h index 4dde9f9..e951d7d 100644 --- a/php_http.h +++ b/php_http.h @@ -37,6 +37,9 @@ extern int http_module_number; ZEND_BEGIN_MODULE_GLOBALS(http) +#ifdef ZEND_ENGINE_2 + zend_bool only_exceptions; +#endif struct _http_globals_etag { zend_bool started; PHP_MD5_CTX md5ctx; @@ -65,6 +68,7 @@ ZEND_BEGIN_MODULE_GLOBALS(http) zend_llist strings; zend_llist slists; zend_llist contexts; + zend_llist convs; } copies; # if LIBCURL_VERSION_NUM < 0x070c00 char error[CURL_ERROR_SIZE + 1]; diff --git a/php_http_request_api.h b/php_http_request_api.h index 6841938..e3f969b 100644 --- a/php_http_request_api.h +++ b/php_http_request_api.h @@ -80,9 +80,16 @@ typedef struct { void *data; } http_curl_callback_ctx; +typedef struct { + phpstr *response; + phpstr *request; + curl_infotype last_info; +} http_curl_conv; + #define COPY_STRING 1 #define COPY_SLIST 2 #define COPY_CONTEXT 3 +#define COPY_CONV 4 #define http_request_data_copy(type, data) _http_request_data_copy((type), (data) TSRMLS_CC) extern void *_http_request_data_copy(int type, void *data TSRMLS_DC); #define http_request_data_free_string _http_request_data_free_string @@ -91,6 +98,11 @@ extern void _http_request_data_free_string(void *string); extern void _http_request_data_free_slist(void *list); #define http_request_data_free_context _http_request_data_free_context extern void _http_request_data_free_context(void *context); +#define http_request_data_free_conv _http_request_data_free_conv +extern void _http_request_data_free_conv(void *conv); + +#define http_request_conv(ch, rs, rq) _http_request_conv((ch), (rs), (rq) TSRMLS_CC) +extern void _http_request_conv(CURL *ch, phpstr* response, phpstr *request TSRMLS_DC); #define http_request_global_init _http_request_global_init extern STATUS _http_request_global_init(void); @@ -154,4 +166,3 @@ PHP_HTTP_API STATUS _http_request_ex(CURL *ch, http_request_method meth, char *U * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ - diff --git a/php_http_request_pool_api.h b/php_http_request_pool_api.h index 3243de9..d357596 100644 --- a/php_http_request_pool_api.h +++ b/php_http_request_pool_api.h @@ -19,6 +19,7 @@ #define PHP_HTTP_REQUEST_POOL_API_H #include "php_http_std_defs.h" +#include "php_http_request_api.h" #include "phpstr/phpstr.h" #ifdef PHP_WIN32 @@ -36,6 +37,8 @@ typedef struct { #define http_request_pool_responsehandler _http_request_pool_responsehandler extern void _http_request_pool_responsehandler(zval **req TSRMLS_DC); +#define http_request_pool_requesthandler(r, b) _http_request_pool_requesthandler((r), (b) TSRMLS_CC) +extern STATUS _http_request_pool_requesthandler(zval *request, http_request_body *body TSRMLS_DC); #define http_request_pool_init(p) _http_request_pool_init((p) TSRMLS_CC) PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool TSRMLS_DC); diff --git a/php_http_std_defs.h b/php_http_std_defs.h index dce34fa..115ece2 100644 --- a/php_http_std_defs.h +++ b/php_http_std_defs.h @@ -191,6 +191,14 @@ typedef int STATUS; name## _ce->ce_flags |= flags; \ } +# define HTTP_REGISTER_EXCEPTION(classname, cename, parent) \ + { \ + zend_class_entry ce; \ + INIT_CLASS_ENTRY(ce, #classname, NULL); \ + ce.create_object = NULL; \ + cename = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \ + } + # define getObject(t, o) getObjectEx(t, o, getThis()) # define getObjectEx(t, o, v) t * o = ((t *) zend_object_store_get_object(v TSRMLS_CC)) # define putObject(t, o) zend_objects_store_put(o, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) t## _free, NULL TSRMLS_CC); @@ -325,16 +333,23 @@ typedef int STATUS; #ifndef E_THROW # define E_THROW 0 #endif - -#define HTTP_E_UNKOWN 0L -#define HTTP_E_PARSE 1L -#define HTTP_E_HEADER 2L -#define HTTP_E_OBUFFER 3L -#define HTTP_E_CURL 4L -#define HTTP_E_ENCODE 5L -#define HTTP_E_PARAM 6L -#define HTTP_E_URL 7L -#define HTTP_E_MSG 8L +#define HE_THROW E_THROW +#define HE_NOTICE (HTTP_G(only_exceptions) ? E_THROW : E_NOTICE) +#define HE_WARNING (HTTP_G(only_exceptions) ? E_THROW : E_WARNING) +#define HE_ERROR (HTTP_G(only_exceptions) ? E_THROW : E_ERROR) + +#define HTTP_E_RUNTIME 1L +#define HTTP_E_INVALID_PARAM 2L +#define HTTP_E_HEADER 3L +#define HTTP_E_MALFORMED_HEADERS 4L +#define HTTP_E_REQUEST_METHOD 5L +#define HTTP_E_MESSAGE_TYPE 6L +#define HTTP_E_ENCODING 7L +#define HTTP_E_REQUEST 8L +#define HTTP_E_REQUEST_POOL 9L +#define HTTP_E_SOCKET 10L +#define HTTP_E_RESPONSE 11L +#define HTTP_E_URL 12L #ifdef ZEND_ENGINE_2 # define HTTP_BEGIN_ARGS_EX(class, method, ret_ref, req_args) static ZEND_BEGIN_ARG_INFO_EX(args_for_ ##class## _ ##method , 0, ret_ref, req_args) diff --git a/tests/INI_001.phpt b/tests/INI_001.phpt index b960811..9210aad 100644 --- a/tests/INI_001.phpt +++ b/tests/INI_001.phpt @@ -7,17 +7,18 @@ include 'skip.inc'; --FILE-- --EXPECTF-- %sTEST -bool(true) string(9) "cache.log" -bool(true) string(15) "POST, HEAD, GET" +string(1) "1" Done diff --git a/tests/run-tests.diff b/tests/run-tests.diff index 9295b87..385d424 100644 --- a/tests/run-tests.diff +++ b/tests/run-tests.diff @@ -34,7 +34,7 @@ diff -u -r1.223 run-tests.php + if (!empty($section_text['ENV'])) { + foreach (explode("\n", $section_text['ENV']) as $env) { + $env = explode('=', $env); -+ ($env = trim($env)) and putenv($env[0] .'='); ++ putenv($env[0] .'='); + } + } + -- 2.30.2