From 27d26668aa55316946f376d1fc4a8014c5fb4de7 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 15:36:00 +0000 Subject: [PATCH 01/16] - even better use a object struct member for that crap --- http.c | 2 -- http_message_object.c | 5 ++--- php_http.h | 1 - php_http_message_object.h | 1 + 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/http.c b/http.c index 9aa6878..50f387b 100644 --- a/http.c +++ b/http.c @@ -283,8 +283,6 @@ PHP_RSHUTDOWN_FUNCTION(http) phpstr_dtor(&HTTP_G(curlbuf)); #endif - zval_dtor(&HTTP_G(message_object_tmp_property)); - return SUCCESS; } /* }}} */ diff --git a/http_message_object.c b/http_message_object.c index 17c9492..2e968b8 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -28,8 +28,6 @@ #ifdef ZEND_ENGINE_2 -ZEND_EXTERN_MODULE_GLOBALS(http); - #define http_message_object_declare_default_properties() _http_message_object_declare_default_properties(TSRMLS_C) static inline void _http_message_object_declare_default_properties(TSRMLS_D); #define http_message_object_read_prop _http_message_object_read_prop @@ -105,6 +103,7 @@ static void _http_message_object_free(zend_object *object TSRMLS_DC) if (o->message) { http_message_free(o->message); } + zval_dtor(&o->_tmp_property); efree(o); } @@ -112,7 +111,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type { getObjectEx(http_message_object, obj, object); http_message *msg = obj->message; - zval *return_value = &HTTP_G(message_object_tmp_property); + zval *return_value = &obj->_tmp_property; 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)); diff --git a/php_http.h b/php_http.h index 0c00e66..ca29137 100644 --- a/php_http.h +++ b/php_http.h @@ -47,7 +47,6 @@ ZEND_BEGIN_MODULE_GLOBALS(http) char curlerr[CURL_ERROR_SIZE + 1]; # endif zend_llist to_free; - zval message_object_tmp_property; #endif /* HTTP_HAVE_CURL */ ZEND_END_MODULE_GLOBALS(http) diff --git a/php_http_message_object.h b/php_http_message_object.h index 399aca3..5e87b59 100644 --- a/php_http_message_object.h +++ b/php_http_message_object.h @@ -24,6 +24,7 @@ typedef struct { zend_object zo; http_message *message; + zval _tmp_property; } http_message_object; extern zend_class_entry *http_message_object_ce; -- 2.30.2 From e006146f6dc8601b2123d10e87311d06325231e7 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 16:05:25 +0000 Subject: [PATCH 02/16] - update --- package.xml | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/package.xml b/package.xml index 64c0ef6..85516db 100644 --- a/package.xml +++ b/package.xml @@ -8,14 +8,13 @@ * Building absolute URIs * RFC compliant HTTP redirects * RFC compliant HTTP date handling -* Parsing of HTTP headers and responses +* Parsing of HTTP headers and messages * Caching by "Last-Modified" and/or ETag (with 'on the fly' option for ETag generation from buffered output) * Sending data/files/streams with (multiple) ranges support * Negotiating user preferred language/charset * Convenient request functions to HEAD/GET/POST if libcurl is available * HTTP auth hooks (Basic) -* HTTPi, HTTPi_Response and HTTPi_Request classes (HTTPi_Request only with libcurl) ]]> PHP License 3.0 @@ -30,17 +29,11 @@ - 0.7.0 - 2005-03-24 + 0.8.0dev + 2005-04-00 beta @@ -51,6 +44,7 @@ EXPERIMENTAL docs/functions.html + http.dsp config.w32 config.m4 @@ -58,15 +52,37 @@ 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_std_defs.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 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 -- 2.30.2 From fcebff9b60cdeede7970f5b4bb7b01318b4415c3 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 17:45:34 +0000 Subject: [PATCH 03/16] - use exceptions in constructors and HttpRequest::send() --- config.m4 | 3 +- config.w32 | 2 +- http.c | 2 ++ http_exception_object.c | 71 +++++++++++++++++++++++++++++++++++++ http_methods.c | 58 +++++++++++++++--------------- package.xml | 2 ++ php_http_exception_object.h | 50 ++++++++++++++++++++++++++ php_http_std_defs.h | 5 +++ 8 files changed, 163 insertions(+), 30 deletions(-) create mode 100644 http_exception_object.c create mode 100644 php_http_exception_object.h diff --git a/config.m4 b/config.m4 index 9fb219f..8b3a49f 100644 --- a/config.m4 +++ b/config.m4 @@ -72,7 +72,8 @@ dnl ---- dnl DONE dnl ---- PHP_HTTP_SOURCES="http.c http_functions.c http_methods.c phpstr/phpstr.c \ - http_util_object.c http_message_object.c http_request_object.c http_response_object.c \ + http_util_object.c http_message_object.c http_request_object.c \ + http_response_object.c http_exception_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_message_api.c http_send_api.c http_url_api.c" PHP_NEW_EXTENSION([http], $PHP_HTTP_SOURCES, [$ext_shared]) diff --git a/config.w32 b/config.w32 index 93e5330..fcb66b6 100644 --- a/config.w32 +++ b/config.w32 @@ -5,7 +5,7 @@ ARG_ENABLE("http", "whether to enable extended HTTP support", "no"); if (PHP_HTTP != "no") { EXTENSION("http", - "http.c http_functions.c http_methods.c "+ + "http.c http_functions.c http_methods.c http_exception_object.c "+ "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 "+ diff --git a/http.c b/http.c index 50f387b..3902443 100644 --- a/http.c +++ b/http.c @@ -44,6 +44,7 @@ # ifdef HTTP_HAVE_CURL # include "php_http_request_object.h" # endif +# include "php_http_exception_object.h" #endif #include "phpstr/phpstr.h" @@ -233,6 +234,7 @@ PHP_MINIT_FUNCTION(http) # ifdef HTTP_HAVE_CURL http_request_object_init(INIT_FUNC_ARGS_PASSTHRU); # endif /* HTTP_HAVE_CURL */ + http_exception_object_init(INIT_FUNC_ARGS_PASSTHRU); #endif /* ZEND_ENGINE_2 */ return SUCCESS; diff --git a/http_exception_object.c b/http_exception_object.c new file mode 100644 index 0000000..5af0dc5 --- /dev/null +++ b/http_exception_object.c @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | 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$ */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" + +#include "php_http.h" +#include "php_http_std_defs.h" + +#ifdef ZEND_ENGINE_2 + +#include "php_http_exception_object.h" +#include "zend_exceptions.h" + +zend_class_entry *http_exception_object_ce; +zend_function_entry http_exception_object_fe[] = { + {NULL, NULL, NULL} +}; + +void _http_exception_object_init(INIT_FUNC_ARGS) +{ + HTTP_REGISTER_CLASS(HttpException, http_exception_object, zend_exception_get_default(), 0); +} + +zend_class_entry *_http_exception_get_default() +{ + return http_exception_object_ce; +} + +void _http_exception_throw_ce_ex(zend_class_entry *ce, int code TSRMLS_DC) +{ + static char * const errors[] = { + "Unkown Error" + }; + + if (!ce) { + ce = http_exception_get_default(); + } + + zend_throw_exception(ce, errors[code], code 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/http_methods.c b/http_methods.c index a6e2f20..6b77947 100644 --- a/http_methods.c +++ b/http_methods.c @@ -33,6 +33,7 @@ #include "php_http_message_object.h" #include "php_http_response_object.h" #include "php_http_request_object.h" +#include "php_http_exception_object.h" #ifdef ZEND_ENGINE_2 @@ -51,13 +52,12 @@ PHP_METHOD(HttpResponse, __construct) zend_bool do_cache = 0, do_gzip = 0; getObject(http_response_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &do_cache, &do_gzip)) { - // throw exception - return; + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &do_cache, &do_gzip)) { + UPD_PROP(obj, long, cache, do_cache); + UPD_PROP(obj, long, gzip, do_gzip); } - - UPD_PROP(obj, long, cache, do_cache); - UPD_PROP(obj, long, gzip, do_gzip); + SET_EH_NORMAL(); } /* }}} */ @@ -553,7 +553,7 @@ PHP_METHOD(HttpMessage, setRaw) { zval *message; getObject(http_message_object, obj); - + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &message)) { return; } @@ -571,7 +571,7 @@ PHP_METHOD(HttpMessage, getBody) { zval *body; getObject(http_message_object, obj); - + NO_ARGS; body = GET_PROP(obj, body); @@ -587,9 +587,9 @@ PHP_METHOD(HttpMessage, getHeaders) { zval *headers; getObject(http_message_object, obj); - + NO_ARGS; - + headers = GET_PROP(obj, headers); array_init(return_value); array_copy(headers, return_value); @@ -613,22 +613,22 @@ PHP_METHOD(HttpRequest, __construct) long meth = -1; getObject(http_request_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &URL, &URL_len, &meth)) { - return; - } - - INIT_PARR(obj, options); - INIT_PARR(obj, responseInfo); - INIT_PARR(obj, responseData); - INIT_PARR(obj, postData); - INIT_PARR(obj, postFiles); + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &URL, &URL_len, &meth)) { + INIT_PARR(obj, options); + INIT_PARR(obj, responseInfo); + INIT_PARR(obj, responseData); + INIT_PARR(obj, postData); + INIT_PARR(obj, postFiles); - if (URL) { - UPD_PROP(obj, string, url, URL); - } - if (meth > -1) { - UPD_PROP(obj, long, method, meth); + if (URL) { + UPD_PROP(obj, string, url, URL); + } + if (meth > -1) { + UPD_PROP(obj, long, method, meth); + } } + SET_EH_NORMAL(); } /* }}} */ @@ -1518,6 +1518,8 @@ PHP_METHOD(HttpRequest, send) getObject(http_request_object, obj); NO_ARGS; + + SET_EH_THROW_HTTP(); if ((!obj->ch) && (!(obj->ch = curl_easy_init()))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initilaize cURL"); @@ -1621,9 +1623,7 @@ PHP_METHOD(HttpRequest, send) efree(request_uri); /* final data handling */ - if (status != SUCCESS) { - RETURN_FALSE; - } else { + if (status == SUCCESS) { char *body = NULL; size_t body_len = 0; zval *zheaders; @@ -1645,7 +1645,9 @@ PHP_METHOD(HttpRequest, send) RETURN_TRUE; } - /* */ + + SET_EH_NORMAL(); + RETURN_SUCCESS(status); } /* }}} */ /* }}} */ diff --git a/package.xml b/package.xml index 85516db..53a26c6 100644 --- a/package.xml +++ b/package.xml @@ -66,6 +66,7 @@ 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 @@ -83,6 +84,7 @@ http_message_object.c http_request_object.c http_response_object.c + http_exception_object.c diff --git a/php_http_exception_object.h b/php_http_exception_object.h new file mode 100644 index 0000000..423704a --- /dev/null +++ b/php_http_exception_object.h @@ -0,0 +1,50 @@ +/* + +----------------------------------------------------------------------+ + | 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_EXCEPTION_OBJECT_H +#define PHP_HTTP_EXCEPTION_OBJECT_H +#ifdef ZEND_ENGINE_2 + +extern zend_class_entry *http_exception_object_ce; +extern zend_function_entry http_exception_object_fe[]; + +#define http_exception_object_init _http_exception_object_init +extern void _http_exception_object_init(INIT_FUNC_ARGS); + +#define http_exception_get_default _http_exception_get_default +extern zend_class_entry *_http_exception_get_default(); + +#define http_exception_throw() http_exception_throw_ex(0) +#define http_exception_throw_ex(code) http_exception_throw_ce_ex(NULL, code) +#define http_exception_throw_ce(ce) http_exception_throw_ce_ex(ce, 0) +#define http_exception_throw_ce_ex(ce, code) _http_exception_throw_ce_ex(ce, code TSRMLS_CC) +extern void _http_exception_throw_ce_ex(zend_class_entry *ce, int code TSRMLS_DC); + +#define HTTP_E_UNKOWN 0 + +#endif +#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_std_defs.h b/php_http_std_defs.h index e79a9b0..49591cd 100644 --- a/php_http_std_defs.h +++ b/php_http_std_defs.h @@ -137,6 +137,11 @@ typedef int STATUS; } \ } +# define SET_EH_THROW() SET_EH_THROW_EX(zend_exception_get_default()) +# define SET_EH_THROW_HTTP() SET_EH_THROW_EX(http_exception_get_default()) +# define SET_EH_THROW_EX(ex) php_set_error_handling(EH_THROW, ex TSRMLS_CC) +# define SET_EH_NORMAL() php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC) + #endif /* ZEND_ENGINE_2 */ /* }}} */ -- 2.30.2 From 9d8cf5d730afef90ea9dcabc606d732e52e15306 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 17:51:43 +0000 Subject: [PATCH 04/16] - missing include - unused var --- http_methods.c | 3 +-- http_send_api.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/http_methods.c b/http_methods.c index 6b77947..f43141b 100644 --- a/http_methods.c +++ b/http_methods.c @@ -531,7 +531,6 @@ PHP_METHOD(HttpResponse, send) PHP_METHOD(HttpMessage, __construct) { zval *message = NULL; - int message_len; getObject(http_message_object, obj); if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/", &message)) { @@ -1518,7 +1517,7 @@ PHP_METHOD(HttpRequest, send) getObject(http_request_object, obj); NO_ARGS; - + SET_EH_THROW_HTTP(); if ((!obj->ch) && (!(obj->ch = curl_easy_init()))) { diff --git a/http_send_api.c b/http_send_api.c index b4b4267..44b29a5 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -21,8 +21,7 @@ #include "php.h" #include "php_streams.h" -#include "snprintf.h" - +#include "ext/standard/php_lcg.h" #include "SAPI.h" #include "php_http.h" -- 2.30.2 From 3fae71eb51f3b0f09cf61639991a44051da8c0bc Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 20:16:54 +0000 Subject: [PATCH 05/16] - renamed response.status to response.code --- http_message_api.c | 4 ++-- php_http_message_api.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http_message_api.c b/http_message_api.c index 1e6ac3a..04564af 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -99,7 +99,7 @@ PHP_HTTP_API void _http_message_parse_headers_callback(void **message, char *htt if (!strncmp(http_line, "HTTP/1.", lenof("HTTP/1."))) { new->type = HTTP_MSG_RESPONSE; new->info.response.http_version = atof(http_line + lenof("HTTP/")); - new->info.response.status = atoi(http_line + lenof("HTTP/1.1 ")); + new->info.response.code = atoi(http_line + lenof("HTTP/1.1 ")); } else // request if (!strncmp(http_line + line_length - lenof("HTTP/1.1"), "HTTP/1.", lenof("HTTP/1."))) { @@ -135,7 +135,7 @@ PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_ case HTTP_MSG_RESPONSE: phpstr_appendf(&str, "HTTP/%1.1f %d" HTTP_CRLF, msg->info.response.http_version, - msg->info.response.status); + msg->info.response.code); break; } diff --git a/php_http_message_api.h b/php_http_message_api.h index 13bf62e..78355a6 100644 --- a/php_http_message_api.h +++ b/php_http_message_api.h @@ -54,7 +54,7 @@ struct _http_message { struct { float http_version; - int status; + int code; } response; } info; -- 2.30.2 From 325520da64f5ae1ecea2f7395fc808ade28da9ea Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 20:17:35 +0000 Subject: [PATCH 06/16] - renamed response.status to response.code - added HttpMessage::get* methods --- http_message_object.c | 35 +++++++-- http_methods.c | 153 ++++++++++++++++++++++++++++++++++++-- php_http_message_object.h | 12 +++ 3 files changed, 185 insertions(+), 15 deletions(-) diff --git a/http_message_object.c b/http_message_object.c index 2e968b8..fe4a628 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -43,6 +43,16 @@ zend_function_entry http_message_object_fe[] = { PHP_ME(HttpMessage, setRaw, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpMessage, getBody, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpMessage, getHeaders, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, getType, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, getResponseCode, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, getRequestMethod, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, getRequestUri, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, getHttpVersion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpMessage, toString, NULL, ZEND_ACC_PUBLIC) + + ZEND_MALIAS(HttpMessage, __toString, toString, NULL, ZEND_ACC_PUBLIC) + + PHP_ME(HttpMessage, fromString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; static zend_object_handlers http_message_object_handlers; @@ -51,19 +61,28 @@ void _http_message_object_init(INIT_FUNC_ARGS) { HTTP_REGISTER_CLASS_EX(HttpMessage, http_message_object, NULL, 0); + HTTP_LONG_CONSTANT("HTTP_MSG_NONE", HTTP_MSG_NONE); + HTTP_LONG_CONSTANT("HTTP_MSG_REQUEST", HTTP_MSG_REQUEST); + HTTP_LONG_CONSTANT("HTTP_MSG_RESPONSE", HTTP_MSG_RESPONSE); + http_message_object_handlers.read_property = http_message_object_read_prop; http_message_object_handlers.write_property = http_message_object_write_prop; http_message_object_handlers.get_properties = http_message_object_get_props; } zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC) +{ + return http_message_object_new_ex(ce, NULL); +} + +zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg TSRMLS_DC) { zend_object_value ov; http_message_object *o; o = ecalloc(1, sizeof(http_message_object)); o->zo.ce = ce; - o->message = http_message_new(); + o->message = msg ? msg : http_message_new(); ALLOC_HASHTABLE(OBJ_PROP(o)); zend_hash_init(OBJ_PROP(o), 0, NULL, ZVAL_PTR_DTOR, 0); @@ -85,7 +104,7 @@ static inline void _http_message_object_declare_default_properties(TSRMLS_D) DCL_PROP(PROTECTED, string, requestMethod, ""); DCL_PROP(PROTECTED, string, requestUri, ""); - DCL_PROP(PROTECTED, long, responseStatus, 0); + DCL_PROP(PROTECTED, long, responseCode, 0); DCL_PROP_N(PROTECTED, httpVersion); DCL_PROP_N(PROTECTED, headers); @@ -191,9 +210,9 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } break; - case HTTP_MSG_PROPHASH_RESPONSE_STATUS: + case HTTP_MSG_PROPHASH_RESPONSE_CODE: if (msg->type == HTTP_MSG_RESPONSE) { - RETVAL_LONG(msg->info.response.status); + RETVAL_LONG(msg->info.response.code); } else { RETVAL_NULL(); } @@ -279,7 +298,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_PROPHASH_RESPONSE_STATUS: if (msg->type == HTTP_MSG_RESPONSE) { - msg->info.response.status = Z_LVAL_P(value); + msg->info.response.code = Z_LVAL_P(value); } break; } @@ -327,14 +346,14 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) { case HTTP_MSG_REQUEST: ASSOC_PROP(obj, double, "httpVersion", msg->info.request.http_version); - ASSOC_PROP(obj, long, "responseStatus", 0); + ASSOC_PROP(obj, long, "responseCode", 0); ASSOC_STRING(obj, "requestMethod", msg->info.request.method); ASSOC_STRING(obj, "requestUri", msg->info.request.URI); break; case HTTP_MSG_RESPONSE: ASSOC_PROP(obj, double, "httpVersion", msg->info.response.http_version); - ASSOC_PROP(obj, long, "responseStatus", msg->info.response.status); + ASSOC_PROP(obj, long, "responseCode", msg->info.response.code); ASSOC_STRING(obj, "requestMethod", empty_string); ASSOC_STRING(obj, "requestUri", empty_string); break; @@ -342,7 +361,7 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) case HTTP_MSG_NONE: default: ASSOC_PROP(obj, double, "httpVersion", 0.0); - ASSOC_PROP(obj, long, "responseStatus", 0); + ASSOC_PROP(obj, long, "responseCode", 0); ASSOC_STRING(obj, "requestMethod", empty_string); ASSOC_STRING(obj, "requestUri", empty_string); break; diff --git a/http_methods.c b/http_methods.c index f43141b..23631c5 100644 --- a/http_methods.c +++ b/http_methods.c @@ -523,6 +523,29 @@ PHP_METHOD(HttpResponse, send) /* {{{ HttpMessage */ +/* {{{ static HttpMessage HttpMessage::fromString(string raw_message) + * + * Create an HttpMessage object from a string. + */ +PHP_METHOD(HttpMessage, fromString) +{ + char *string = NULL; + int length = 0; + http_message *msg = NULL; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) { + RETURN_NULL(); + } + + if (!(msg = http_message_parse(string, length))) { + RETURN_NULL(); + } + + Z_TYPE_P(return_value) = IS_OBJECT; + return_value->value.obj = http_message_object_from_msg(msg); +} +/* }}} */ + /* {{{ void HttpMessage::__construct([string raw_message]) * * Instantiate a new HttpMessage object based on the optionally provided @@ -533,14 +556,14 @@ PHP_METHOD(HttpMessage, __construct) zval *message = NULL; getObject(http_message_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/", &message)) { - return; - } - - if (message) { - convert_to_string(message); - SET_PROP(obj, raw, message); + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/", &message)) { + if (message) { + convert_to_string(message); + SET_PROP(obj, raw, message); + } } + SET_EH_NORMAL(); } /* }}} */ @@ -595,6 +618,122 @@ PHP_METHOD(HttpMessage, getHeaders) } /* }}} */ +/* {{{ long HttpMessage::getType() + * + * Get Message Type. (HTTP_MSG_NONE|HTTP_MSG_REQUEST|HTTP_MSG_RESPONSE) + */ +PHP_METHOD(HttpMessage, getType) +{ + zval *type; + getObject(http_message_object, obj); + + NO_ARGS; + + type = GET_PROP(obj, type); + RETURN_LONG(Z_LVAL_P(type)); +} +/* }}} */ + +/* {{{ int HttpMessage::getResponseCode() + * + * Get the Response Code of the Message. + */ +PHP_METHOD(HttpMessage, getResponseCode) +{ + zval *status; + getObject(http_message_object, obj); + + NO_ARGS; + + if (obj->message->type != HTTP_MSG_RESPONSE) { + RETURN_NULL(); + } + + status = GET_PROP(obj, responseCode); + RETURN_LONG(Z_LVAL_P(status)); +} +/* }}} */ + +/* {{{ string HttpMessage::getRequestMethod() + * + * Get the Request Method of the Message. + */ +PHP_METHOD(HttpMessage, getRequestMethod) +{ + zval *method; + getObject(http_message_object, obj); + + NO_ARGS; + + if (obj->message->type != HTTP_MSG_REQUEST) { + RETURN_NULL(); + } + + method = GET_PROP(obj, requestMethod); + RETURN_STRINGL(Z_STRVAL_P(method), Z_STRLEN_P(method), 1); +} +/* }}} */ + +/* {{{ string HttpMessage::getRequestUri() + * + * Get the Request URI of the Message. + */ +PHP_METHOD(HttpMessage, getRequestUri) +{ + zval *uri; + getObject(http_message_object, obj); + + NO_ARGS; + + if (obj->message->type != HTTP_MSG_REQUEST) { + RETURN_NULL(); + } + + uri = GET_PROP(obj, requestUri); + RETURN_STRINGL(Z_STRVAL_P(uri), Z_STRLEN_P(uri), 1); +} +/* }}} */ + +/* {{{ string HttpMessage::getHttpVersion() + * + * Get the HTTP Protocol Version of the Message. + */ +PHP_METHOD(HttpMessage, getHttpVersion) +{ + zval *version; + char ver[4] = {0}; + getObject(http_message_object, obj); + + NO_ARGS; + + version = GET_PROP(obj, httpVersion); + + if (Z_TYPE_P(version) == IS_NULL) { + RETURN_NULL(); + } + + sprintf(ver, "1.1f", Z_DVAL_P(version)); + RETURN_STRINGL(ver, 3, 1); +} +/* }}} */ + +/* {{{ string HttpMessage::toString() + * + * Get the string representation of the Message. + */ +PHP_METHOD(HttpMessage, toString) +{ + char *string; + size_t length; + getObject(http_message_object, obj); + + NO_ARGS; + + http_message_tostring(obj->message, &string, &length); + RETURN_STRINGL(string, length, 0); +} +/* }}} */ + /* }}} */ #ifdef HTTP_HAVE_CURL diff --git a/php_http_message_object.h b/php_http_message_object.h index 5e87b59..484c562 100644 --- a/php_http_message_object.h +++ b/php_http_message_object.h @@ -34,6 +34,9 @@ extern zend_function_entry http_message_object_fe[]; extern void _http_message_object_init(INIT_FUNC_ARGS); #define http_message_object_new _http_message_object_new extern zend_object_value _http_message_object_new(zend_class_entry *ce TSRMLS_DC); +#define http_message_object_new_ex(ce, msg) _http_message_object_new_ex(ce, msg TSRMLS_CC) +#define http_message_object_from_msg(msg) _http_message_object_new_ex(http_message_object_ce, msg TSRMLS_CC) +extern zend_object_value _http_message_object_new_ex(zend_class_entry *ce, http_message *msg TSRMLS_DC); #define http_message_object_free _http_message_object_free extern void _http_message_object_free(zend_object *object TSRMLS_DC); @@ -46,11 +49,20 @@ extern void _http_message_object_free(zend_object *object TSRMLS_DC); #define HTTP_MSG_PROPHASH_REQUEST_METHOD 1669022159LU #define HTTP_MSG_PROPHASH_REQUEST_URI 3208695486LU #define HTTP_MSG_PROPHASH_RESPONSE_STATUS 3857097400LU +#define HTTP_MSG_PROPHASH_RESPONSE_CODE 1305615119LU PHP_METHOD(HttpMessage, __construct); PHP_METHOD(HttpMessage, setRaw); PHP_METHOD(HttpMessage, getBody); PHP_METHOD(HttpMessage, getHeaders); +PHP_METHOD(HttpMessage, getType); +PHP_METHOD(HttpMessage, getResponseCode); +PHP_METHOD(HttpMessage, getRequestMethod); +PHP_METHOD(HttpMessage, getRequestUri); +PHP_METHOD(HttpMessage, getHttpVersion); +PHP_METHOD(HttpMessage, toString); + +PHP_METHOD(HttpMessage, fromString); #endif #endif -- 2.30.2 From 96b6d481cfa03fae8c40a6ab7c2156036b082d7d Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Apr 2005 20:29:08 +0000 Subject: [PATCH 07/16] - no empty_string anymore --- http_headers_api.c | 9 +++++---- http_message_object.c | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/http_headers_api.c b/http_headers_api.c index b9fe7b1..cc4e609 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -271,14 +271,14 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, Z_ARRVAL(array) = headers; } } else - + /* "header: value" pair */ if (colon) { /* skip empty key */ if (header != colon) { zval **previous = NULL; - char *value = empty_string; + char *value; int keylen = colon - header; char *key = estrndup(header, keylen); @@ -296,6 +296,7 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, if (value_len > 0) { value = estrndup(colon, value_len); } else { + value = estrdup(""); value_len = 0; } @@ -343,7 +344,7 @@ PHP_HTTP_API void _http_parse_headers_default_callback(void **cb_data, char *htt { zval array; Z_ARRVAL(array) = *headers; - + /* response */ if (!strncmp(http_line, "HTTP/1.", lenof("HTTP/1."))) { add_assoc_stringl(&array, "Response Status", http_line + lenof("HTTP/1.x "), line_length - lenof("HTTP/1.x \r\n"), 1); @@ -351,7 +352,7 @@ PHP_HTTP_API void _http_parse_headers_default_callback(void **cb_data, char *htt /* request */ if (!strncmp(http_line + line_length - lenof("HTTP/1.x\r\n"), "HTTP/1.", lenof("HTTP/1."))) { char *sep = strchr(http_line, ' '); - + add_assoc_stringl(&array, "Request Method", http_line, sep - http_line, 1); add_assoc_stringl(&array, "Request Uri", sep + 1, strstr(sep, "HTTP/1.") - sep + 1 + 1, 1); } diff --git a/http_message_object.c b/http_message_object.c index fe4a628..a8540e7 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -173,7 +173,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type if (msg->len) { RETVAL_STRINGL(msg->raw, msg->len, 1); } else { - RETVAL_STRINGL(empty_string, 0, 1); + RETVAL_STRINGL("", 0, 1); } } else { RETVAL_NULL(); @@ -327,7 +327,7 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) int m_prop_len; \ Z_ARRVAL(array) = OBJ_PROP(obj); \ zend_mangle_property_name(&m_prop_name, &m_prop_len, "*", 1, name, lenof(name), 1); \ - add_assoc_stringl_ex(&array, m_prop_name, sizeof(name)+4, val, len, val != empty_string); \ + add_assoc_stringl_ex(&array, m_prop_name, sizeof(name)+4, val, len, 1); \ } zend_hash_clean(OBJ_PROP(obj)); @@ -354,16 +354,16 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) case HTTP_MSG_RESPONSE: ASSOC_PROP(obj, double, "httpVersion", msg->info.response.http_version); ASSOC_PROP(obj, long, "responseCode", msg->info.response.code); - ASSOC_STRING(obj, "requestMethod", empty_string); - ASSOC_STRING(obj, "requestUri", empty_string); + ASSOC_STRING(obj, "requestMethod", ""); + ASSOC_STRING(obj, "requestUri", ""); break; case HTTP_MSG_NONE: default: ASSOC_PROP(obj, double, "httpVersion", 0.0); ASSOC_PROP(obj, long, "responseCode", 0); - ASSOC_STRING(obj, "requestMethod", empty_string); - ASSOC_STRING(obj, "requestUri", empty_string); + ASSOC_STRING(obj, "requestMethod", ""); + ASSOC_STRING(obj, "requestUri", ""); break; } -- 2.30.2 From bf7c808caf569c8533a1e7226765cff87c462ab7 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 08:03:20 +0000 Subject: [PATCH 08/16] * typo --- http_functions.c | 2 +- http_message_object.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http_functions.c b/http_functions.c index 9b57b64..0b39b72 100644 --- a/http_functions.c +++ b/http_functions.c @@ -981,7 +981,7 @@ PHP_FUNCTION(http_build_query) } formstr = phpstr_new(); - if (SUCCESS != http_urlencode_hash_implementation_ex(HASH_OF(formdata), formstr, arg_sep, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL) TSRMLS_CC)) { + if (SUCCESS != http_urlencode_hash_implementation_ex(HASH_OF(formdata), formstr, arg_sep, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL))) { phpstr_free(formstr); RETURN_FALSE; } diff --git a/http_message_object.c b/http_message_object.c index a8540e7..e23f555 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -296,7 +296,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va } break; - case HTTP_MSG_PROPHASH_RESPONSE_STATUS: + case HTTP_MSG_PROPHASH_RESPONSE_CODE: if (msg->type == HTTP_MSG_RESPONSE) { msg->info.response.code = Z_LVAL_P(value); } -- 2.30.2 From 3a658eda7fbc2ad5c8d2534ae69c4683266dab95 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 13:34:34 +0000 Subject: [PATCH 09/16] - removed unused stuff --- http_exception_object.c | 13 ------------- php_http_exception_object.h | 8 -------- 2 files changed, 21 deletions(-) diff --git a/http_exception_object.c b/http_exception_object.c index 5af0dc5..44c5c2a 100644 --- a/http_exception_object.c +++ b/http_exception_object.c @@ -45,19 +45,6 @@ zend_class_entry *_http_exception_get_default() return http_exception_object_ce; } -void _http_exception_throw_ce_ex(zend_class_entry *ce, int code TSRMLS_DC) -{ - static char * const errors[] = { - "Unkown Error" - }; - - if (!ce) { - ce = http_exception_get_default(); - } - - zend_throw_exception(ce, errors[code], code TSRMLS_CC); -} - #endif /* diff --git a/php_http_exception_object.h b/php_http_exception_object.h index 423704a..e89c576 100644 --- a/php_http_exception_object.h +++ b/php_http_exception_object.h @@ -28,14 +28,6 @@ extern void _http_exception_object_init(INIT_FUNC_ARGS); #define http_exception_get_default _http_exception_get_default extern zend_class_entry *_http_exception_get_default(); -#define http_exception_throw() http_exception_throw_ex(0) -#define http_exception_throw_ex(code) http_exception_throw_ce_ex(NULL, code) -#define http_exception_throw_ce(ce) http_exception_throw_ce_ex(ce, 0) -#define http_exception_throw_ce_ex(ce, code) _http_exception_throw_ce_ex(ce, code TSRMLS_CC) -extern void _http_exception_throw_ce_ex(zend_class_entry *ce, int code TSRMLS_DC); - -#define HTTP_E_UNKOWN 0 - #endif #endif -- 2.30.2 From fb4cc3c3eda3bb4dd15ec99a4f372ccfd78b7473 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 13:35:20 +0000 Subject: [PATCH 10/16] - smarter check for allowed methods --- http.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/http.c b/http.c index 3902443..be06ac5 100644 --- a/http.c +++ b/http.c @@ -27,6 +27,8 @@ # include #endif +#include + #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" @@ -163,14 +165,24 @@ static void php_http_init_globals(zend_http_globals *http_globals) #define http_check_allowed_methods(m, l) _http_check_allowed_methods((m), (l) TSRMLS_CC) static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_DC) { - if (length && SG(request_info).request_method && (!strstr(methods, SG(request_info).request_method))) { - char *allow_header = emalloc(length + sizeof("Allow: ")); - sprintf(allow_header, "Allow: %s", methods); - http_send_header(allow_header); - efree(allow_header); - http_send_status(405); - zend_bailout(); + char *found, *header; + + if (!length || !SG(request_info).request_method) { + return; } + + if ( (found = strstr(methods, SG(request_info).request_method)) && + (found == SG(request_info).request_method || !isalpha(found[-1])) && + (!isalpha(found[strlen(SG(request_info).request_method) + 1]))) { + return; + } + + header = emalloc(length + sizeof("Allow: ")); + sprintf(header, "Allow: %s", methods); + http_send_header(header); + efree(header); + http_send_status(405); + zend_bailout(); } /* }}} */ @@ -293,7 +305,7 @@ PHP_RSHUTDOWN_FUNCTION(http) PHP_MINFO_FUNCTION(http) { #ifdef ZEND_ENGINE_2 -# define HTTP_FUNC_AVAIL(CLASS) "procedural, object oriented (class " CLASS ")" +# define HTTP_FUNC_AVAIL(CLASS) "procedural, object oriented (" CLASS ")" #else # define HTTP_FUNC_AVAIL(CLASS) "procedural" #endif @@ -301,7 +313,7 @@ PHP_MINFO_FUNCTION(http) #ifdef HTTP_HAVE_CURL # define HTTP_CURL_VERSION curl_version() # ifdef ZEND_ENGINE_2 -# define HTTP_CURL_AVAIL(CLASS) "procedural, object oriented (class " CLASS ")" +# define HTTP_CURL_AVAIL(CLASS) "procedural, object oriented (" CLASS ")" # else # define HTTP_CURL_AVAIL(CLASS) "procedural" # endif @@ -320,7 +332,7 @@ PHP_MINFO_FUNCTION(http) php_info_print_table_start(); php_info_print_table_header(2, "Functionality", "Availability"); - php_info_print_table_row(2, "Miscellaneous Utilities:", HTTP_FUNC_AVAIL("HttpUtil")); + php_info_print_table_row(2, "Miscellaneous Utilities:", HTTP_FUNC_AVAIL("HttpUtil, HttpMessage")); php_info_print_table_row(2, "Extended HTTP Responses:", HTTP_FUNC_AVAIL("HttpResponse")); php_info_print_table_row(2, "Extended HTTP Requests:", HTTP_CURL_AVAIL("HttpRequest")); php_info_print_table_end(); -- 2.30.2 From 2253ca28b6a5699a8e2d62a0458ced3cb7a3107a Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 13:35:46 +0000 Subject: [PATCH 11/16] - added custom error function which is able to throw exceptions --- http_api.c | 39 +++++++++++++++++++++++++++++++-------- php_http_api.h | 7 ++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/http_api.c b/http_api.c index a548e13..9960f2b 100644 --- a/http_api.c +++ b/http_api.c @@ -32,10 +32,14 @@ #include "php_http_cache_api.h" #include "php_http_headers_api.h" +#ifdef ZEND_ENGINE_2 +# include "php_http_exception_object.h" +#endif + ZEND_EXTERN_MODULE_GLOBALS(http); /* char *pretty_key(char *, size_t, zend_bool, zebd_bool) */ -char *pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen) +char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen) { if (key && key_len) { unsigned i, wasalpha; @@ -58,6 +62,29 @@ char *pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen } /* }}} */ +/* {{{ void http_error(long, long, char*) */ +void _http_error_ex(long type, long code, const char *format, ...) +{ + va_list args; + TSRMLS_FETCH(); + + va_start(args, format); + if (type == E_THROW) { +#ifdef ZEND_ENGINE_2 + char *message; + vspprintf(&message, 0, format, args); + zend_throw_exception(http_exception_get_default(), message, code TSRMLS_CC); +#else + type = E_WARNING; +#endif + } + if (type != E_THROW) { + php_verror(NULL, "", type, format, args TSRMLS_CC); + } + va_end(args); +} +/* }}} */ + /* {{{ static STATUS http_ob_stack_get(php_ob_buffer *, php_ob_buffer **) */ static STATUS http_ob_stack_get(php_ob_buffer *o, php_ob_buffer **s) { @@ -186,8 +213,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len /* read in chunk size */ while (isxdigit(*e_ptr)) { if (i == 9) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Chunk size is too long: 0x%s...", hex_len); + http_error_ex(E_WARNING, HTTP_E_PARSE, "Chunk size is too long: 0x%s...", hex_len); efree(*decoded); return FAILURE; } @@ -201,9 +227,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len /* new line */ if (strncmp(e_ptr, HTTP_CRLF, 2)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Invalid character (expected 0x0D 0x0A; got: %x %x)", - *e_ptr, *(e_ptr + 1)); + http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid character (expected 0x0D 0x0A; got: %x %x)", *e_ptr, *(e_ptr + 1)); efree(*decoded); return FAILURE; } @@ -213,8 +237,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len char *error = NULL; chunk_len = strtol(hex_len, &error, 16); if (error == hex_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Invalid chunk size string: '%s'", hex_len); + http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size string: '%s'", hex_len); efree(*decoded); return FAILURE; } diff --git a/php_http_api.h b/php_http_api.h index b7327b4..d08a2a9 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -20,7 +20,12 @@ #include "php_http_std_defs.h" -char *pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen); +#define pretty_key(key, key_len, uctitle, xhyphen) _http_pretty_key(key, key_len, uctitle, xhyphen) +extern char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen); + +#define http_error(type, code, string) _http_error_ex(type, code, "%s", string) +#define http_error_ex _http_error_ex +extern void _http_error_ex(long type, long code, const char *format, ...); #define HTTP_GSC(var, name, ret) HTTP_GSP(var, name, return ret) #define HTTP_GSP(var, name, ret) \ -- 2.30.2 From 6a9c33f395f4293eb122c6e884a35c0153537446 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 13:35:57 +0000 Subject: [PATCH 12/16] - error constants --- php_http_std_defs.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php_http_std_defs.h b/php_http_std_defs.h index 49591cd..b4aee3f 100644 --- a/php_http_std_defs.h +++ b/php_http_std_defs.h @@ -142,9 +142,21 @@ typedef int STATUS; # define SET_EH_THROW_EX(ex) php_set_error_handling(EH_THROW, ex TSRMLS_CC) # define SET_EH_NORMAL() php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC) +# ifndef E_THROW +# define E_THROW 0 +# endif + #endif /* ZEND_ENGINE_2 */ /* }}} */ +#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 #endif /* PHP_HTTP_STD_DEFS_H */ -- 2.30.2 From cf9967800843ea01e77b374b4d78fad4bc18a3f6 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 13:37:09 +0000 Subject: [PATCH 13/16] - use custom error function - smarter response handling for http_request using http_message --- http_cache_api.c | 6 +- http_curl_api.c | 117 +++++++++++++++----------------------- http_functions.c | 58 ++++++++++--------- http_headers_api.c | 5 +- http_methods.c | 108 +++++++++++++++++++++-------------- http_request_object.c | 7 ++- http_send_api.c | 32 ++++------- http_url_api.c | 11 ++-- php_http_curl_api.h | 31 +++++----- php_http_request_object.h | 4 ++ 10 files changed, 189 insertions(+), 190 deletions(-) diff --git a/http_cache_api.c b/http_cache_api.c index 8df1ada..7d61040 100644 --- a/http_cache_api.c +++ b/http_cache_api.c @@ -157,7 +157,7 @@ PHP_HTTP_API STATUS _http_cache_last_modified(time_t last_modified, if (SUCCESS == http_send_status(304)) { zend_bailout(); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified"); + http_error(E_WARNING, HTTP_E_HEADER, "Could not send 304 Not Modified"); return FAILURE; } } @@ -179,7 +179,7 @@ PHP_HTTP_API STATUS _http_cache_etag(const char *etag, size_t etag_len, if (SUCCESS == http_send_status(304)) { zend_bailout(); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified"); + http_error(E_WARNING, HTTP_E_HEADER, "Could not send 304 Not Modified"); return FAILURE; } } @@ -191,7 +191,7 @@ PHP_HTTP_API STATUS _http_cache_etag(const char *etag, size_t etag_len, HTTP_G(etag_started) = 1; return SUCCESS; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not start ob_etaghandler"); + http_error(E_WARNING, HTTP_E_OBUFFER, "Could not start ob_etaghandler"); return FAILURE; } } diff --git a/http_curl_api.c b/http_curl_api.c index b576b2f..2df24e5 100644 --- a/http_curl_api.c +++ b/http_curl_api.c @@ -49,52 +49,48 @@ ZEND_EXTERN_MODULE_GLOBALS(http) # define http_curl_error(code) curl_easy_strerror(code) #endif -#define http_curl_startup(ch, clean_curl, URL, options) \ +#define http_curl_startup(ch, clean_curl, URL, options, response) \ if (!ch) { \ if (!(ch = curl_easy_init())) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize curl"); \ + 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); + http_curl_setopts(ch, URL, options, response); -#define http_curl_perform(ch, clean_curl) \ +#define http_curl_perform(ch, clean_curl, response) \ { \ CURLcode result; \ if (CURLE_OK != (result = curl_easy_perform(ch))) { \ - http_curl_cleanup(ch, clean_curl); \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not perform request: %s", curl_easy_strerror(result)); \ + 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; \ } \ } -#define http_curl_cleanup(ch, clean_curl) \ - phpstr_dtor(&HTTP_G(curlbuf)); \ +#define http_curl_cleanup(ch, clean_curl, response) \ zend_llist_clean(&HTTP_G(to_free)); \ if (clean_curl) { \ curl_easy_cleanup(ch); \ ch = NULL; \ - } - -#define http_curl_copybuf(d, l) \ - phpstr_data(&HTTP_G(curlbuf), d, l) + } \ + phpstr_fix(PHPSTR(response)) #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) _http_curl_setopts((c), (u), (o) TSRMLS_CC) -static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options 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) _http_curl_getopt((o), (k) TSRMLS_CC, 0) #define http_curl_getopt1(o, k, t1) _http_curl_getopt((o), (k) TSRMLS_CC, 1, (t1)) #define http_curl_getopt2(o, k, t1, t2) _http_curl_getopt((o), (k) TSRMLS_CC, 2, (t1), (t2)) static inline zval *_http_curl_getopt(HashTable *options, char *key TSRMLS_DC, int checks, ...); -static size_t http_curl_body_callback(char *, size_t, size_t, void *); -static size_t http_curl_hdrs_callback(char *, size_t, size_t, void *); +static size_t http_curl_callback(char *, size_t, 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); @@ -108,25 +104,10 @@ static inline char *_http_curl_copystr(const char *str TSRMLS_DC) } /* }}} */ -/* {{{ static size_t http_curl_body_callback(char *, size_t, size_t, void *) */ -static size_t http_curl_body_callback(char *buf, size_t len, size_t n, void *s) -{ - TSRMLS_FETCH(); - phpstr_append(&HTTP_G(curlbuf), buf, len *= n); - return len; -} -/* }}} */ - -/* {{{ static size_t http_curl_hdrs_callback(char *, size_t, size_t, void *) */ -static size_t http_curl_hdrs_callback(char *buf, size_t len, size_t n, void *s) +/* {{{ static size_t http_curl_callback(char *, size_t, size_t, void *) */ +static size_t http_curl_callback(char *buf, size_t len, size_t n, void *s) { - TSRMLS_FETCH(); - - /* discard previous headers */ - if (HTTP_G(curlbuf).used && (!strncmp(buf, "HTTP/1.", sizeof("HTTP/1.") - 1))) { - phpstr_free(&HTTP_G(curlbuf)); - } - phpstr_append(&HTTP_G(curlbuf), buf, len *= n); + phpstr_append(PHPSTR(s), buf, len *= n); return len; } /* }}} */ @@ -157,8 +138,8 @@ static inline zval *_http_curl_getopt(HashTable *options, char *key TSRMLS_DC, i } /* }}} */ -/* {{{ static void http_curl_setopts(CURL *, char *, HashTable *) */ -static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options TSRMLS_DC) +/* {{{ 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) { zval *zoption; zend_bool range_req = 0; @@ -171,8 +152,10 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options TSR HTTP_CURL_OPT(FILETIME, 1); HTTP_CURL_OPT(NOPROGRESS, 1); HTTP_CURL_OPT(AUTOREFERER, 1); - HTTP_CURL_OPT(WRITEFUNCTION, http_curl_body_callback); - HTTP_CURL_OPT(HEADERFUNCTION, http_curl_hdrs_callback); + HTTP_CURL_OPT(WRITEFUNCTION, http_curl_callback); + HTTP_CURL_OPT(HEADERFUNCTION, http_curl_callback); + HTTP_CURL_OPT(WRITEDATA, response); + HTTP_CURL_OPT(WRITEHEADER, response); #if defined(ZTS) && (LIBCURL_VERSION_NUM >= 0x070a00) HTTP_CURL_OPT(NOSIGNAL, 1); #endif @@ -496,108 +479,100 @@ static inline void _http_curl_getinfo(CURL *ch, HashTable *info TSRMLS_DC) } /* }}} */ -/* {{{ STATUS http_get_ex(CURL *, char *, HashTable *, HashTable *, char **, size_t *) */ -PHP_HTTP_API STATUS _http_get_ex(CURL *ch, const char *URL, HashTable *options, - HashTable *info, char **data, size_t *data_len TSRMLS_DC) +/* {{{ 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; - http_curl_startup(ch, clean_curl, URL, options); + http_curl_startup(ch, clean_curl, URL, options, response); curl_easy_setopt(ch, CURLOPT_HTTPGET, 1); - http_curl_perform(ch, clean_curl); + http_curl_perform(ch, clean_curl, response); if (info) { http_curl_getinfo(ch, info); } - http_curl_copybuf(data, data_len); - http_curl_cleanup(ch, clean_curl); + http_curl_cleanup(ch, clean_curl, response); return SUCCESS; } -/* {{{ STATUS http_head_ex(CURL *, char *, HashTable *, HashTable *, char **data, size_t *) */ -PHP_HTTP_API STATUS _http_head_ex(CURL *ch, const char *URL, HashTable *options, - HashTable *info, char **data, size_t *data_len TSRMLS_DC) +/* {{{ 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) { zend_bool clean_curl = 0; - http_curl_startup(ch, clean_curl, URL, options); + http_curl_startup(ch, clean_curl, URL, options, response); curl_easy_setopt(ch, CURLOPT_NOBODY, 1); - http_curl_perform(ch, clean_curl); + http_curl_perform(ch, clean_curl, response); if (info) { http_curl_getinfo(ch, info); } - http_curl_copybuf(data, data_len); - http_curl_cleanup(ch, clean_curl); + http_curl_cleanup(ch, clean_curl, response); return SUCCESS; } -/* {{{ STATUS http_post_data_ex(CURL *, char *, char *, size_t, HashTable *, HashTable *, char **, size_t *) */ +/* {{{ 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, char **data, - size_t *data_len TSRMLS_DC) + size_t postdata_len, HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) { zend_bool clean_curl = 0; - http_curl_startup(ch, clean_curl, URL, options); + 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); + http_curl_perform(ch, clean_curl, response); if (info) { http_curl_getinfo(ch, info); } - http_curl_copybuf(data, data_len); - http_curl_cleanup(ch, clean_curl); + http_curl_cleanup(ch, clean_curl, response); return SUCCESS; } /* }}} */ -/* {{{ STATUS http_post_array_ex(CURL *, char *, HashTable *, HashTable *, HashTable *, char **, size_t *) */ +/* {{{ 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, char **data, size_t *data_len TSRMLS_DC) + HashTable *options, HashTable *info, phpstr *response TSRMLS_DC) { STATUS status; char *encoded; size_t encoded_len; if (SUCCESS != http_urlencode_hash_ex(postarray, 1, NULL, 0, &encoded, &encoded_len)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not encode post data"); + http_error(E_WARNING, HTTP_E_ENCODE, "Could not encode post data"); return FAILURE; } - status = http_post_data_ex(ch, URL, encoded, encoded_len, options, info, data, data_len); + status = http_post_data_ex(ch, URL, encoded, encoded_len, options, info, response); efree(encoded); return status; } /* }}} */ -/* {{{ STATUS http_post_curldata_ex(CURL *, char *, curl_httppost *, HashTable *, HashTable *, char **, size_t *) */ -PHP_HTTP_API STATUS _http_post_curldata_ex(CURL *ch, const char *URL, - struct curl_httppost *curldata, HashTable *options, HashTable *info, - char **data, size_t *data_len TSRMLS_DC) +/* {{{ 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) { zend_bool clean_curl = 0; - http_curl_startup(ch, clean_curl, URL, options); + 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); + http_curl_perform(ch, clean_curl, response); if (info) { http_curl_getinfo(ch, info); } - http_curl_copybuf(data, data_len); - http_curl_cleanup(ch, clean_curl); + http_curl_cleanup(ch, clean_curl, response); return SUCCESS; } diff --git a/http_functions.c b/http_functions.c index 0b39b72..96f3277 100644 --- a/http_functions.c +++ b/http_functions.c @@ -203,7 +203,7 @@ PHP_FUNCTION(http_send_status) RETURN_FALSE; } if (status < 100 || status > 510) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid HTTP status code (100-510): %d", status); + http_error_ex(E_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status); RETURN_FALSE; } @@ -410,7 +410,7 @@ PHP_FUNCTION(ob_httpetaghandler) if (mode & PHP_OUTPUT_HANDLER_START) { if (HTTP_G(etag_started)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "ob_httpetaghandler can only be used once"); + http_error(E_WARNING, HTTP_E_OBUFFER, "ob_httpetaghandler can only be used once"); RETURN_STRINGL(data, data_len, 1); } http_send_header("Cache-Control: " HTTP_DEFAULT_CACHECONTROL); @@ -418,7 +418,7 @@ PHP_FUNCTION(ob_httpetaghandler) } if (OG(ob_nesting_level) > 1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "ob_httpetaghandler must be started prior to other output buffers"); + http_error(E_WARNING, HTTP_E_OBUFFER, "ob_httpetaghandler must be started prior to other output buffers"); RETURN_STRINGL(data, data_len, 1); } @@ -462,7 +462,7 @@ PHP_FUNCTION(http_redirect) array_init(params); } if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not append session information"); + http_error(E_WARNING, HTTP_E_ENCODE, "Could not append session information"); } } @@ -609,7 +609,7 @@ PHP_FUNCTION(http_split_response) array_init(zheaders); if (SUCCESS != http_split_response(zresponse, zheaders, zbody)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP response"); + http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP response"); RETURN_FALSE; } @@ -637,7 +637,7 @@ PHP_FUNCTION(http_parse_headers) header_len = rnrn - header + 2; } if (SUCCESS != http_parse_headers(header, header_len, return_value)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP headers"); + http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP headers"); zval_dtor(return_value); RETURN_FALSE; } @@ -730,10 +730,10 @@ PHP_FUNCTION(http_get_request_headers) */ PHP_FUNCTION(http_get) { - char *URL, *data = NULL; - size_t data_len = 0; - int URL_len; zval *options = NULL, *info = NULL; + char *URL; + int URL_len; + phpstr response; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a/!z", &URL, &URL_len, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -744,8 +744,9 @@ PHP_FUNCTION(http_get) array_init(info); } - if (SUCCESS == http_get(URL, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) { - RETURN_STRINGL(data, data_len, 0); + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); + if (SUCCESS == http_get(URL, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETURN_PHPSTR_VAL(response); } else { RETURN_FALSE; } @@ -760,10 +761,10 @@ PHP_FUNCTION(http_get) */ PHP_FUNCTION(http_head) { - char *URL, *data = NULL; - size_t data_len = 0; - int URL_len; zval *options = NULL, *info = NULL; + char *URL; + int URL_len; + phpstr response; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a/!z", &URL, &URL_len, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -774,8 +775,9 @@ PHP_FUNCTION(http_head) array_init(info); } - if (SUCCESS == http_head(URL, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) { - RETURN_STRINGL(data, data_len, 0); + phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); + if (SUCCESS == http_head(URL, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { + RETURN_PHPSTR_VAL(response); } else { RETURN_FALSE; } @@ -790,10 +792,10 @@ PHP_FUNCTION(http_head) */ PHP_FUNCTION(http_post_data) { - char *URL, *postdata, *data = NULL; - size_t data_len = 0; - int postdata_len, URL_len; zval *options = NULL, *info = NULL; + char *URL, *postdata; + int postdata_len, URL_len; + phpstr response; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!z", &URL, &URL_len, &postdata, &postdata_len, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -804,8 +806,9 @@ PHP_FUNCTION(http_post_data) array_init(info); } - if (SUCCESS == http_post_data(URL, postdata, (size_t) postdata_len, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) { - RETURN_STRINGL(data, data_len, 0); + 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); } else { RETURN_FALSE; } @@ -820,10 +823,10 @@ PHP_FUNCTION(http_post_data) */ PHP_FUNCTION(http_post_array) { - char *URL, *data = NULL; - size_t data_len = 0; - int URL_len; zval *options = NULL, *info = NULL, *postdata; + char *URL; + int URL_len; + phpstr response; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a/!z", &URL, &URL_len, &postdata, &options, &info) != SUCCESS) { RETURN_FALSE; @@ -834,8 +837,9 @@ PHP_FUNCTION(http_post_array) array_init(info); } - if (SUCCESS == http_post_array(URL, Z_ARRVAL_P(postdata), Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) { - RETURN_STRINGL(data, data_len, 0); + 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); } else { RETURN_FALSE; } @@ -972,7 +976,7 @@ PHP_FUNCTION(http_build_query) } if (Z_TYPE_P(formdata) != IS_ARRAY && Z_TYPE_P(formdata) != IS_OBJECT) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter 1 expected to be Array or Object. Incorrect value given."); + http_error(E_WARNING, HTTP_E_PARAM, "Parameter 1 expected to be Array or Object. Incorrect value given."); RETURN_FALSE; } diff --git a/http_headers_api.c b/http_headers_api.c index cc4e609..09673e9 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -111,7 +111,7 @@ 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)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Range header misses bytes="); + http_error(E_NOTICE, HTTP_E_HEADER, "Range header misses bytes="); return RANGE_NO; } @@ -248,7 +248,8 @@ PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, size_t header_len, Z_ARRVAL(array) = headers; - if (header_len < 2) { + if (header_len < 2 || !strchr(header, ':')) { + http_error(E_WARNING, HTTP_E_PARSE, "Cannot parse too short or malformed HTTP headers"); return FAILURE; } diff --git a/http_methods.c b/http_methods.c index 23631c5..af7586d 100644 --- a/http_methods.c +++ b/http_methods.c @@ -27,6 +27,7 @@ #include "php_http_curl_api.h" #include "php_http_date_api.h" #include "php_http_headers_api.h" +#include "php_http_message_api.h" #include "php_http_send_api.h" #include "php_http_url_api.h" @@ -152,7 +153,7 @@ PHP_METHOD(HttpResponse, setCacheControl) } if ((!raw) && (strcmp(ccontrol, "public") && strcmp(ccontrol, "private") && strcmp(ccontrol, "no-cache"))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol); + http_error_ex(E_WARNING, HTTP_E_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol); RETURN_FALSE; } @@ -193,8 +194,7 @@ PHP_METHOD(HttpResponse, setContentType) } if (!strchr(ctype, '/')) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Content type '%s' doesn't seem to contain a primary and a secondary part", ctype); + http_error_ex(E_WARNING, HTTP_E_PARAM, "Content type '%s' doesn't seem to contain a primary and a secondary part", ctype); RETURN_FALSE; } @@ -711,7 +711,7 @@ PHP_METHOD(HttpMessage, getHttpVersion) if (Z_TYPE_P(version) == IS_NULL) { RETURN_NULL(); } - + sprintf(ver, "1.1f", Z_DVAL_P(version)); RETURN_STRINGL(ver, 3, 1); } @@ -726,9 +726,9 @@ PHP_METHOD(HttpMessage, toString) char *string; size_t length; getObject(http_message_object, obj); - + NO_ARGS; - + http_message_tostring(obj->message, &string, &length); RETURN_STRINGL(string, length, 0); } @@ -1139,9 +1139,7 @@ PHP_METHOD(HttpRequest, setContentType) } if (!strchr(ctype, '/')) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Content-Type '%s' doesn't seem to contain a primary and a secondary part", - ctype); + http_error_ex(E_WARNING, HTTP_E_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", ctype); RETURN_FALSE; } @@ -1352,7 +1350,7 @@ PHP_METHOD(HttpRequest, addPostFile) if (type_len) { if (!strchr(type, '/')) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", type); + http_error_ex(E_WARNING, HTTP_E_PARAM, "Content-Type '%s' doesn't seem to contain a primary and a secondary part", type); RETURN_FALSE; } } else { @@ -1570,19 +1568,13 @@ PHP_METHOD(HttpRequest, getResponseBody) */ PHP_METHOD(HttpRequest, getResponseCode) { - zval **code, **hdrs, *data; + zval *code; getObject(http_request_object, obj); NO_ARGS; - data = GET_PROP(obj, responseData); - if ( (SUCCESS == zend_hash_find(Z_ARRVAL_P(data), "headers", sizeof("headers"), (void **) &hdrs)) && - (SUCCESS == zend_hash_find(Z_ARRVAL_PP(hdrs), "Response Status", sizeof("Response Status"), (void **) &code))) { - RETVAL_STRINGL(Z_STRVAL_PP(code), Z_STRLEN_PP(code), 1); - convert_to_long(return_value); - } else { - RETURN_FALSE; - } + code = GET_PROP(obj, responseCode); + RETURN_LONG(Z_LVAL_P(code)); } /* }}} */ @@ -1608,7 +1600,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 { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not find response info named %s", info_name); + http_error_ex(E_NOTICE, HTTP_E_PARAM, "Could not find response info named %s", info_name); RETURN_FALSE; } } else { @@ -1618,6 +1610,24 @@ PHP_METHOD(HttpRequest, getResponseInfo) } /* }}}*/ +/* {{{ proto HttpMessage HttpRequest::getResponseMessage() + * + * Get the full response as HttpMessage object. + */ +PHP_METHOD(HttpRequest, getResponseMessage) +{ + zval *message; + getObject(http_request_object, obj); + + NO_ARGS; + + message = GET_PROP(obj, responseMessage); + Z_TYPE_P(return_value) = IS_OBJECT; + return_value->is_ref = 1; + return_value->value.obj = message->value.obj; + zval_add_ref(&return_value); +} + /* {{{ proto bool HttpRequest::send() * * Send the HTTP request. @@ -1628,8 +1638,13 @@ PHP_METHOD(HttpRequest, getResponseInfo) * $r = new HttpRequest('http://example.com/feed.rss', HTTP_GET); * $r->setOptions(array('lastmodified' => filemtime('local.rss'))); * $r->addQueryData(array('category' => 3)); - * if ($r->send() && $r->getResponseCode() == 200) { - * file_put_contents('local.rss', $r->getResponseBody()); + * try { + * $r->send(); + * if ($r->getResponseCode() == 200) { + * file_put_contents('local.rss', $r->getResponseBody()); + * } + * } catch (HttpException $ex) { + * echo $ex; * } * ?> * @@ -1651,8 +1666,7 @@ PHP_METHOD(HttpRequest, send) { STATUS status = FAILURE; zval *meth, *URL, *qdata, *opts, *info, *resp; - char *response_data, *request_uri; - size_t response_len; + char *request_uri; getObject(http_request_object, obj); NO_ARGS; @@ -1660,7 +1674,7 @@ PHP_METHOD(HttpRequest, send) SET_EH_THROW_HTTP(); if ((!obj->ch) && (!(obj->ch = curl_easy_init()))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initilaize cURL"); + http_error(E_WARNING, HTTP_E_CURL, "Could not initilaize curl"); RETURN_FALSE; } @@ -1686,11 +1700,11 @@ 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), &response_data, &response_len); + status = http_get_ex(obj->ch, request_uri, 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), &response_data, &response_len); + status = http_head_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); break; case HTTP_POST: @@ -1703,7 +1717,7 @@ PHP_METHOD(HttpRequest, send) 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), &response_data, &response_len); + 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 { @@ -1748,7 +1762,7 @@ PHP_METHOD(HttpRequest, send) } } - status = http_post_curldata_ex(obj->ch, request_uri, http_post_data[0], Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &response_data, &response_len); + 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]); } } @@ -1762,26 +1776,32 @@ PHP_METHOD(HttpRequest, send) /* final data handling */ if (status == SUCCESS) { - char *body = NULL; - size_t body_len = 0; - zval *zheaders; + http_message *msg; - MAKE_STD_ZVAL(zheaders) - array_init(zheaders); + if (msg = http_message_parse(PHPSTR_VAL(&obj->response), PHPSTR_LEN(&obj->response))) { + zval *headers, *message; + char *body; + size_t body_len; - if (SUCCESS != http_split_response_ex(response_data, response_len, Z_ARRVAL_P(zheaders), &body, &body_len)) { - zval_dtor(zheaders); - efree(zheaders), - efree(response_data); - RETURN_FALSE; - } + UPD_PROP(obj, long, responseCode, msg->info.response.code); - add_assoc_zval(resp, "headers", zheaders); - add_assoc_stringl(resp, "body", body, body_len, 0); + MAKE_STD_ZVAL(headers) + array_init(headers); - efree(response_data); + zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + phpstr_data(PHPSTR(msg), &body, &body_len); - RETURN_TRUE; + add_assoc_zval(resp, "headers", headers); + add_assoc_stringl(resp, "body", body, body_len, 0); + + message = GET_PROP(obj, responseMessage); + zval_dtor(message); + Z_TYPE_P(message) = IS_OBJECT; + message->value.obj = http_message_object_from_msg(msg); + SET_PROP(obj, responseMessage, message); + } else { + status = FAILURE; + } } SET_EH_NORMAL(); diff --git a/http_request_object.c b/http_request_object.c index 5887bf2..64a76ef 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -88,6 +88,7 @@ zend_function_entry http_request_object_fe[] = { PHP_ME(HttpRequest, getResponseCode, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpRequest, getResponseBody, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpRequest, getResponseInfo, NULL, ZEND_ACC_PUBLIC) + PHP_ME(HttpRequest, getResponseMessage, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -115,6 +116,8 @@ zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC) o->zo.ce = ce; o->ch = curl_easy_init(); + phpstr_init_ex(&o->response, HTTP_CURLBUF_SIZE, 0); + ALLOC_HASHTABLE(OBJ_PROP(o)); zend_hash_init(OBJ_PROP(o), 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); @@ -132,6 +135,8 @@ static inline void _http_request_object_declare_default_properties(TSRMLS_D) DCL_PROP_N(PROTECTED, options); DCL_PROP_N(PROTECTED, responseInfo); DCL_PROP_N(PROTECTED, responseData); + DCL_PROP_N(PROTECTED, responseCode); + DCL_PROP_N(PROTECTED, responseMessage); DCL_PROP_N(PROTECTED, postData); DCL_PROP_N(PROTECTED, postFiles); @@ -153,8 +158,8 @@ void _http_request_object_free(zend_object *object TSRMLS_DC) } if (o->ch) { curl_easy_cleanup(o->ch); - o->ch = NULL; } + phpstr_dtor(&o->response); efree(o); } diff --git a/http_send_api.c b/http_send_api.c index 44b29a5..9318efd 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -124,8 +124,12 @@ static STATUS _http_send_chunk(const void *data, size_t begin, size_t end, http_ /* {{{ STATUS http_send_status_header(int, char *) */ PHP_HTTP_API STATUS _http_send_status_header(int status, const char *header TSRMLS_DC) { + STATUS ret; sapi_header_line h = {(char *) header, strlen(header), status}; - return sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC); + if (SUCCESS != (ret = sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC))) { + http_error_ex(E_WARNING, HTTP_E_HEADER, "Could not send header: %s (%d)", header, status); + } + return ret; } /* }}} */ @@ -154,8 +158,7 @@ PHP_HTTP_API STATUS _http_send_etag(const char *etag, size_t etag_len TSRMLS_DC) char *etag_header; if (!etag_len){ - php_error_docref(NULL TSRMLS_CC,E_ERROR, - "Attempt to send empty ETag (previous: %s)\n", HTTP_G(etag)); + http_error_ex(E_WARNING, HTTP_E_HEADER, "Attempt to send empty ETag (previous: %s)\n", HTTP_G(etag)); return FAILURE; } @@ -167,9 +170,7 @@ PHP_HTTP_API STATUS _http_send_etag(const char *etag, size_t etag_len TSRMLS_DC) etag_header = ecalloc(1, sizeof("ETag: \"\"") + etag_len); sprintf(etag_header, "ETag: \"%s\"", etag); - if (SUCCESS != (status = http_send_header(etag_header))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't send '%s' header", etag_header); - } + status = http_send_header(etag_header); efree(etag_header); return status; } @@ -182,10 +183,7 @@ PHP_HTTP_API STATUS _http_send_cache_control(const char *cache_control, size_t c char *cc_header = ecalloc(1, sizeof("Cache-Control: ") + cc_len); sprintf(cc_header, "Cache-Control: %s", cache_control); - if (SUCCESS != (status = http_send_header(cc_header))) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, - "Could not send '%s' header", cc_header); - } + status = http_send_header(cc_header); efree(cc_header); return status; } @@ -198,9 +196,7 @@ PHP_HTTP_API STATUS _http_send_content_type(const char *content_type, size_t ct_ char *ct_header; if (!strchr(content_type, '/')) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Content-Type '%s' doesn't seem to consist of a primary and a secondary part", - 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); return FAILURE; } @@ -212,11 +208,7 @@ PHP_HTTP_API STATUS _http_send_content_type(const char *content_type, size_t ct_ ct_header = ecalloc(1, sizeof("Content-Type: ") + ct_len); sprintf(ct_header, "Content-Type: %s", content_type); - - if (SUCCESS != (status = http_send_header(ct_header))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Couldn't send '%s' header", ct_header); - } + status = http_send_header(ct_header); efree(ct_header); return status; } @@ -236,9 +228,7 @@ PHP_HTTP_API STATUS _http_send_content_disposition(const char *filename, size_t sprintf(cd_header, "Content-Disposition: attachment; filename=\"%s\"", filename); } - if (SUCCESS != (status = http_send_header(cd_header))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't send '%s' header", cd_header); - } + status = http_send_header(cd_header); efree(cd_header); return status; } diff --git a/http_url_api.c b/http_url_api.c index 8788064..459b618 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -59,13 +59,12 @@ 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))))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Cannot build an absolute URI if supplied URL and REQUEST_URI is empty"); + http_error(E_WARNING, HTTP_E_PARAM, "Cannot build an absolute URI if supplied URL and REQUEST_URI is empty"); return NULL; } if (!(purl = php_url_parse((char *) url))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse supplied URL"); + http_error_ex(E_WARNING, HTTP_E_PARSE, "Could not parse supplied URL: %s", url); return NULL; } @@ -116,7 +115,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) { \ - php_error_docref(NULL TSRMLS_CC, E_NOTICE, \ + http_error_ex(E_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); \ @@ -195,7 +194,6 @@ PHP_HTTP_API STATUS _http_urlencode_hash_ex(HashTable *hash, zend_bool override_ } if (SUCCESS != http_urlencode_hash_implementation(hash, qstr, arg_sep)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't encode query data"); phpstr_free(qstr); return FAILURE; } @@ -222,6 +220,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"); return FAILURE; } @@ -260,7 +259,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)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array."); + http_error(E_WARNING, HTTP_E_ENCODE, "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_curl_api.h b/php_http_curl_api.h index 586259e..df6f267 100644 --- a/php_http_curl_api.h +++ b/php_http_curl_api.h @@ -19,6 +19,7 @@ #define PHP_HTTP_CURL_API_H #include "php_http_std_defs.h" +#include "phpstr/phpstr.h" #ifdef PHP_WIN32 # include @@ -26,25 +27,25 @@ #include -#define http_get(u, o, i, d, l) _http_get_ex(NULL, (u), (o), (i), (d), (l) TSRMLS_CC) -#define http_get_ex(c, u, o, i, d, l) _http_get_ex((c), (u), (o), (i), (d), (l) TSRMLS_CC) -PHP_HTTP_API STATUS _http_get_ex(CURL *ch, const char *URL, HashTable *options, HashTable *info, char **data, size_t *data_len TSRMLS_DC); +#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, d, l) _http_head_ex(NULL, (u), (o), (i), (d), (l) TSRMLS_CC) -#define http_head_ex(c, u, o, i, d, l) _http_head_ex((c), (u), (o), (i), (d), (l) TSRMLS_CC) -PHP_HTTP_API STATUS _http_head_ex(CURL *ch, const char *URL, HashTable *options, HashTable *info, char **data, size_t *data_len 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, d, l) _http_post_data_ex(NULL, (u), (pd), (pl), (o), (i), (d), (l) TSRMLS_CC) -#define http_post_data_ex(c, u, pd, pl, o, i, d, l) _http_post_data_ex((c), (u), (pd), (pl), (o), (i), (d), (l) 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, char **data, size_t *data_len 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, d, l) _http_post_array_ex(NULL, (u), (p), (o), (i), (d), (l) TSRMLS_CC) -#define http_post_array_ex(c, u, p, o, i, d, l) _http_post_array_ex((c), (u), (p), (o), (i), (d), (l) TSRMLS_CC) -PHP_HTTP_API STATUS _http_post_array_ex(CURL *ch, const char *URL, HashTable *postarray, HashTable *options, HashTable *info, char **data, size_t *data_len 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, d, l) _http_post_curldata_ex(NULL, (u), (h), (o), (i), (d), (l) TSRMLS_CC) -#define http_post_curldata_ex(c, u, h, o, i, d, l) _http_post_curldata_ex((c), (u), (h), (o), (i), (d), (l) TSRMLS_CC) -PHP_HTTP_API STATUS _http_post_curldata_ex(CURL *ch, const char *URL, struct curl_httppost *curldata, HashTable *options, HashTable *info, char **data, size_t *data_len 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 diff --git a/php_http_request_object.h b/php_http_request_object.h index 7cd3e74..9af6e8b 100644 --- a/php_http_request_object.h +++ b/php_http_request_object.h @@ -26,9 +26,12 @@ #include +#include "phpstr/phpstr.h" + typedef struct { zend_object zo; CURL *ch; + phpstr response; } http_request_object; typedef enum { @@ -85,6 +88,7 @@ PHP_METHOD(HttpRequest, getResponseCookie); PHP_METHOD(HttpRequest, getResponseCode); PHP_METHOD(HttpRequest, getResponseBody); PHP_METHOD(HttpRequest, getResponseInfo); +PHP_METHOD(HttpRequest, getResponseMessage); #endif #endif -- 2.30.2 From 8cdf77bbae1974a94d69ab757cbda38b88299e5f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 15:14:07 +0000 Subject: [PATCH 14/16] - fix & enhance option setting *walk through the options even if the options array is empty, so that some default options will be set *always convert options --- http_curl_api.c | 101 ++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/http_curl_api.c b/http_curl_api.c index 2df24e5..e94e5dc 100644 --- a/http_curl_api.c +++ b/http_curl_api.c @@ -85,10 +85,8 @@ 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) _http_curl_getopt((o), (k) TSRMLS_CC, 0) -#define http_curl_getopt1(o, k, t1) _http_curl_getopt((o), (k) TSRMLS_CC, 1, (t1)) -#define http_curl_getopt2(o, k, t1, t2) _http_curl_getopt((o), (k) TSRMLS_CC, 2, (t1), (t2)) -static inline zval *_http_curl_getopt(HashTable *options, char *key TSRMLS_DC, int checks, ...); +#define http_curl_getopt(o, k, t) _http_curl_getopt((o), (k), (t) TSRMLS_CC) +static inline zval *_http_curl_getopt(HashTable *options, char *key, int type TSRMLS_DC); static size_t http_curl_callback(char *, size_t, size_t, void *); @@ -112,29 +110,30 @@ static size_t http_curl_callback(char *buf, size_t len, size_t n, void *s) } /* }}} */ -/* {{{ static inline zval *http_curl_getopt(HashTable *, char *, int, ...) */ -static inline zval *_http_curl_getopt(HashTable *options, char *key TSRMLS_DC, int checks, ...) +/* {{{ static inline zval *http_curl_getopt(HashTable *, char *, int) */ +static inline zval *_http_curl_getopt(HashTable *options, char *key, int type TSRMLS_DC) { zval **zoption; - va_list types; - int i; if (SUCCESS != zend_hash_find(options, key, strlen(key) + 1, (void **) &zoption)) { return NULL; } - if (checks < 1) { - return *zoption; - } - va_start(types, checks); - for (i = 0; i < checks; ++i) { - if ((va_arg(types, int)) == (Z_TYPE_PP(zoption))) { - va_end(types); - return *zoption; + 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; } } - va_end(types); - return NULL; + + return *zoption; } /* }}} */ @@ -163,61 +162,57 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph HTTP_CURL_OPT(ERRORBUFFER, HTTP_G(curlerr)); #endif - if ((!options) || (1 > zend_hash_num_elements(options))) { - return; - } - /* proxy */ - if (zoption = http_curl_getopt1(options, "proxyhost", IS_STRING)) { + if (zoption = http_curl_getopt(options, "proxyhost", IS_STRING)) { HTTP_CURL_OPT(PROXY, http_curl_copystr(Z_STRVAL_P(zoption))); /* port */ - if (zoption = http_curl_getopt1(options, "proxyport", IS_LONG)) { + if (zoption = http_curl_getopt(options, "proxyport", IS_LONG)) { HTTP_CURL_OPT(PROXYPORT, Z_LVAL_P(zoption)); } /* user:pass */ - if (zoption = http_curl_getopt1(options, "proxyauth", IS_STRING)) { + if (zoption = http_curl_getopt(options, "proxyauth", IS_STRING)) { HTTP_CURL_OPT(PROXYUSERPWD, http_curl_copystr(Z_STRVAL_P(zoption))); } #if LIBCURL_VERSION_NUM >= 0x070a07 /* auth method */ - if (zoption = http_curl_getopt1(options, "proxyauthtype", IS_LONG)) { + if (zoption = http_curl_getopt(options, "proxyauthtype", IS_LONG)) { HTTP_CURL_OPT(PROXYAUTH, Z_LVAL_P(zoption)); } #endif } /* outgoing interface */ - if (zoption = http_curl_getopt1(options, "interface", IS_STRING)) { + if (zoption = http_curl_getopt(options, "interface", IS_STRING)) { HTTP_CURL_OPT(INTERFACE, http_curl_copystr(Z_STRVAL_P(zoption))); } /* another port */ - if (zoption = http_curl_getopt1(options, "port", IS_LONG)) { + if (zoption = http_curl_getopt(options, "port", IS_LONG)) { HTTP_CURL_OPT(PORT, Z_LVAL_P(zoption)); } /* auth */ - if (zoption = http_curl_getopt1(options, "httpauth", IS_STRING)) { + if (zoption = http_curl_getopt(options, "httpauth", IS_STRING)) { HTTP_CURL_OPT(USERPWD, http_curl_copystr(Z_STRVAL_P(zoption))); } #if LIBCURL_VERSION_NUM >= 0x070a06 - if (zoption = http_curl_getopt1(options, "httpauthtype", IS_LONG)) { + if (zoption = http_curl_getopt(options, "httpauthtype", IS_LONG)) { HTTP_CURL_OPT(HTTPAUTH, Z_LVAL_P(zoption)); } #endif /* compress, empty string enables deflate and gzip */ - if (zoption = http_curl_getopt2(options, "compress", IS_LONG, IS_BOOL)) { + if (zoption = http_curl_getopt(options, "compress", IS_BOOL)) { if (Z_LVAL_P(zoption)) { HTTP_CURL_OPT(ENCODING, ""); } } /* redirects, defaults to 0 */ - if (zoption = http_curl_getopt1(options, "redirect", IS_LONG)) { + if (zoption = http_curl_getopt(options, "redirect", IS_LONG)) { HTTP_CURL_OPT(FOLLOWLOCATION, Z_LVAL_P(zoption) ? 1 : 0); HTTP_CURL_OPT(MAXREDIRS, Z_LVAL_P(zoption)); - if (zoption = http_curl_getopt2(options, "unrestrictedauth", IS_LONG, IS_BOOL)) { + if (zoption = http_curl_getopt(options, "unrestrictedauth", IS_BOOL)) { HTTP_CURL_OPT(UNRESTRICTED_AUTH, Z_LVAL_P(zoption)); } } else { @@ -225,12 +220,12 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph } /* referer */ - if (zoption = http_curl_getopt1(options, "referer", IS_STRING)) { + if (zoption = http_curl_getopt(options, "referer", IS_STRING)) { HTTP_CURL_OPT(REFERER, http_curl_copystr(Z_STRVAL_P(zoption))); } /* useragent, default "PECL::HTTP/version (PHP/version)" */ - if (zoption = http_curl_getopt1(options, "useragent", IS_STRING)) { + if (zoption = http_curl_getopt(options, "useragent", IS_STRING)) { HTTP_CURL_OPT(USERAGENT, http_curl_copystr(Z_STRVAL_P(zoption))); } else { HTTP_CURL_OPT(USERAGENT, @@ -238,7 +233,7 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph } /* additional headers, array('name' => 'value') */ - if (zoption = http_curl_getopt1(options, "headers", IS_ARRAY)) { + if (zoption = http_curl_getopt(options, "headers", IS_ARRAY)) { char *header_key; long header_idx; struct curl_slist *headers = NULL; @@ -263,7 +258,7 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph } /* cookies, array('name' => 'value') */ - if (zoption = http_curl_getopt1(options, "cookies", IS_ARRAY)) { + if (zoption = http_curl_getopt(options, "cookies", IS_ARRAY)) { char *cookie_key = NULL; long cookie_idx = 0; phpstr *qstr = phpstr_new(); @@ -288,44 +283,42 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph } /* cookiestore */ - if (zoption = http_curl_getopt1(options, "cookiestore", IS_STRING)) { + if (zoption = http_curl_getopt(options, "cookiestore", IS_STRING)) { HTTP_CURL_OPT(COOKIEFILE, http_curl_copystr(Z_STRVAL_P(zoption))); HTTP_CURL_OPT(COOKIEJAR, http_curl_copystr(Z_STRVAL_P(zoption))); } /* resume */ - if (zoption = http_curl_getopt1(options, "resume", IS_LONG)) { + if (zoption = http_curl_getopt(options, "resume", IS_LONG)) { range_req = 1; HTTP_CURL_OPT(RESUME_FROM, Z_LVAL_P(zoption)); } /* maxfilesize */ - if (zoption = http_curl_getopt1(options, "maxfilesize", IS_LONG)) { + if (zoption = http_curl_getopt(options, "maxfilesize", IS_LONG)) { HTTP_CURL_OPT(MAXFILESIZE, Z_LVAL_P(zoption)); } /* lastmodified */ - if (zoption = http_curl_getopt1(options, "lastmodified", IS_LONG)) { + if (zoption = http_curl_getopt(options, "lastmodified", IS_LONG)) { HTTP_CURL_OPT(TIMECONDITION, range_req ? CURL_TIMECOND_IFUNMODSINCE : CURL_TIMECOND_IFMODSINCE); HTTP_CURL_OPT(TIMEVALUE, Z_LVAL_P(zoption)); } /* timeout */ - if (zoption = http_curl_getopt1(options, "timeout", IS_LONG)) { + if (zoption = http_curl_getopt(options, "timeout", IS_LONG)) { HTTP_CURL_OPT(TIMEOUT, Z_LVAL_P(zoption)); } - /* connecttimeout */ - if (zoption = http_curl_getopt1(options, "connecttimeout", IS_LONG)) { + /* connecttimeout, defaults to 1 */ + if (zoption = http_curl_getopt(options, "connecttimeout", IS_LONG)) { HTTP_CURL_OPT(CONNECTTIMEOUT, Z_LVAL_P(zoption)); + } else { + HTTP_CURL_OPT(CONNECTTIMEOUT, 1); } /* ssl */ - if (zoption = http_curl_getopt1(options, "ssl", IS_ARRAY)) { - long idx; - char *key = NULL; - zval **param; - + 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) @@ -347,8 +340,12 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph continue; \ } + long idx; + char *key = NULL; + zval **param; + FOREACH_KEYVAL(zoption, key, idx, param) { - if (key) { + if (key) {fprintf(stderr, "%s\n", key); HTTP_CURL_OPT_SSL_STRING(CERT); #if LIBCURL_VERSION_NUM >= 0x070903 HTTP_CURL_OPT_SSL_STRING(CERTTYPE); @@ -378,6 +375,10 @@ static void _http_curl_setopts(CURL *ch, const char *url, HashTable *options, ph key = NULL; } } + } else { + /* disable SSL verification by default */ + HTTP_CURL_OPT(SSL_VERIFYPEER, 0); + HTTP_CURL_OPT(SSL_VERIFYHOST, 0); } } /* }}} */ -- 2.30.2 From 909134d3309bdc12023c0fea5acf931041ea0f6b Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 15:14:35 +0000 Subject: [PATCH 15/16] * return modification length --- phpstr/phpstr.c | 9 ++++++--- phpstr/phpstr.h | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/phpstr/phpstr.c b/phpstr/phpstr.c index 286a190..8d8df3e 100644 --- a/phpstr/phpstr.c +++ b/phpstr/phpstr.c @@ -45,12 +45,13 @@ PHPSTR_API void phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size) } } -PHPSTR_API void phpstr_append(phpstr *buf, const char *append, size_t append_len) +PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len) { phpstr_resize(buf, append_len); memcpy(buf->data + buf->used, append, append_len); buf->used += append_len; buf->free -= append_len; + return append_len; } PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...) @@ -69,13 +70,14 @@ PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...) return append_len; } -PHPSTR_API void phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset) +PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset) { phpstr_resize(buf, insert_len); memmove(buf->data + offset + insert_len, buf->data + offset, insert_len); memcpy(buf->data + offset, insert, insert_len); buf->used += insert_len; buf->free -= insert_len; + return insert_len; } PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...) @@ -94,13 +96,14 @@ PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, return insert_len; } -PHPSTR_API void phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len) +PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len) { phpstr_resize(buf, prepend_len); memmove(buf->data + prepend_len, buf->data, buf->used); memcpy(buf->data, prepend, prepend_len); buf->used += prepend_len; buf->free -= prepend_len; + return prepend_len; } PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...) diff --git a/phpstr/phpstr.h b/phpstr/phpstr.h index 51c2b42..cb7d06a 100644 --- a/phpstr/phpstr.h +++ b/phpstr/phpstr.h @@ -79,19 +79,19 @@ PHPSTR_API void phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size); /* append data to the phpstr */ #define phpstr_appends(b, a) phpstr_append((b), (a), sizeof(a)-1) #define phpstr_appendl(b, a) phpstr_append((b), (a), strlen(a)) -PHPSTR_API void phpstr_append(phpstr *buf, const char *append, size_t append_len); +PHPSTR_API size_t phpstr_append(phpstr *buf, const char *append, size_t append_len); PHPSTR_API size_t phpstr_appendf(phpstr *buf, const char *format, ...); /* insert data at a specific position of the phpstr */ #define phpstr_inserts(b, i, o) phpstr_insert((b), (i), sizeof(i)-1, (o)) #define phpstr_insertl(b, i, o) phpstr_insert((b), (i), strlen(i), (o)) -PHPSTR_API void phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset); +PHPSTR_API size_t phpstr_insert(phpstr *buf, const char *insert, size_t insert_len, size_t offset); PHPSTR_API size_t phpstr_insertf(phpstr *buf, size_t offset, const char *format, ...); /* prepend data */ #define phpstr_prepends(b, p) phpstr_prepend((b), (p), sizeof(p)-1) #define phpstr_prependl(b, p) phpstr_prepend((b), (p), strlen(p)) -PHPSTR_API void phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len); +PHPSTR_API size_t phpstr_prepend(phpstr *buf, const char *prepend, size_t prepend_len); PHPSTR_API size_t phpstr_prependf(phpstr *buf, const char *format, ...); /* get a zero-terminated string */ -- 2.30.2 From 061bf1e96c7f3fa5d50374a7170b20d4c3e4d002 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 Apr 2005 15:15:46 +0000 Subject: [PATCH 16/16] * return length directly in curl cb --- http_curl_api.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http_curl_api.c b/http_curl_api.c index e94e5dc..1da840c 100644 --- a/http_curl_api.c +++ b/http_curl_api.c @@ -105,8 +105,7 @@ static inline char *_http_curl_copystr(const char *str TSRMLS_DC) /* {{{ static size_t http_curl_callback(char *, size_t, size_t, void *) */ static size_t http_curl_callback(char *buf, size_t len, size_t n, void *s) { - phpstr_append(PHPSTR(s), buf, len *= n); - return len; + return phpstr_append(PHPSTR(s), buf, len *= n); } /* }}} */ -- 2.30.2