From d5930114b227ce9c9ce71d3930291f333750c192 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 19 Jan 2006 18:07:29 +0000 Subject: [PATCH] - add internal http_message_set_info() - add HttpMessage::detach(), HttpMessage::prepend() and tests --- http_functions.c | 4 +- http_message_api.c | 37 ++++++++------- http_message_object.c | 95 +++++++++++++++++++++++++++++++++++++++ php_http_message_api.h | 3 ++ php_http_message_object.h | 3 ++ 5 files changed, 124 insertions(+), 18 deletions(-) diff --git a/http_functions.c b/http_functions.c index d9acab9..cdddb81 100644 --- a/http_functions.c +++ b/http_functions.c @@ -41,8 +41,8 @@ * Compose a valid HTTP date regarding RFC 822/1123 * looking like: "Wed, 22 Dec 2004 11:34:47 GMT" * - * Takes an optional unix timestamp as parameter. - * + * Accepts an optional unix timestamp as parameter. + * * Returns the HTTP date as string. */ PHP_FUNCTION(http_date) diff --git a/http_message_api.c b/http_message_api.c index 93c4bf1..27f3d78 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -37,22 +37,7 @@ static void _http_message_info_callback(http_message **message, HashTable **head (*headers) = &((*message)->hdrs); } - (*message)->http.version = info->http.version; - - switch (info->type) - { - case IS_HTTP_REQUEST: - (*message)->type = HTTP_MSG_REQUEST; - HTTP_INFO(*message).request.url = estrdup(HTTP_INFO(info).request.url); - HTTP_INFO(*message).request.method = estrdup(HTTP_INFO(info).request.method); - break; - - case IS_HTTP_RESPONSE: - (*message)->type = HTTP_MSG_RESPONSE; - HTTP_INFO(*message).response.code = HTTP_INFO(info).response.code; - HTTP_INFO(*message).response.status = estrdup(HTTP_INFO(info).response.status); - break; - } + http_message_set_info(*message, info); } #define http_message_init_type _http_message_init_type @@ -119,6 +104,26 @@ PHP_HTTP_API void _http_message_set_type(http_message *message, http_message_typ } } +PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info) +{ + message->http.version = info->http.version; + + switch (info->type) + { + case IS_HTTP_REQUEST: + message->type = HTTP_MSG_REQUEST; + HTTP_INFO(message).request.url = estrdup(HTTP_INFO(info).request.url); + STR_SET(HTTP_INFO(message).request.method, estrdup(HTTP_INFO(info).request.method)); + break; + + case IS_HTTP_RESPONSE: + message->type = HTTP_MSG_RESPONSE; + HTTP_INFO(message).response.code = HTTP_INFO(info).response.code; + STR_SET(HTTP_INFO(message).response.status, estrdup(HTTP_INFO(info).response.status)); + break; + } +} + PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t message_length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC) { const char *body = NULL; diff --git a/http_message_object.c b/http_message_object.c index 4634cab..8a4b4c6 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -94,6 +94,12 @@ HTTP_BEGIN_ARGS(unserialize, 0, 1) HTTP_ARG_VAL(serialized, 0) HTTP_END_ARGS; +HTTP_EMPTY_ARGS(detach, 0); + +HTTP_BEGIN_ARGS(prepend, 0, 1) + HTTP_ARG_OBJ(HttpMessage, message, 0) +HTTP_END_ARGS; + #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 @@ -136,6 +142,10 @@ zend_function_entry http_message_object_fe[] = { HTTP_MESSAGE_ME(fromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + HTTP_MESSAGE_ME(detach, ZEND_ACC_PUBLIC) + + HTTP_MESSAGE_ME(prepend, ZEND_ACC_PUBLIC) + EMPTY_FUNCTION_ENTRY }; static zend_object_handlers http_message_object_handlers; @@ -235,6 +245,14 @@ void _http_message_object_free(zend_object *object TSRMLS_DC) http_message_dtor(o->message); efree(o->message); } + if (o->parent.handle) { + zval p; + + INIT_PZVAL(&p); + p.type = IS_OBJECT; + p.value.obj = o->parent; + zend_objects_store_del_ref(&p TSRMLS_CC); + } efree(o); } @@ -1058,6 +1076,83 @@ PHP_METHOD(HttpMessage, unserialize) } /* }}} */ +/* {{{ proto HttpMessage HttpMessage::detach(void) + * + * Returns a clone of an HttpMessage object detached from any parent messages. + */ +PHP_METHOD(HttpMessage, detach) +{ + http_info info; + http_message *msg; + getObject(http_message_object, obj); + + NO_ARGS; + + info.type = obj->message->type; + memcpy(&HTTP_INFO(&info), &HTTP_INFO(obj->message), sizeof(struct http_info)); + + msg = http_message_new(); + http_message_set_info(msg, &info); + + zend_hash_copy(&msg->hdrs, &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + phpstr_append(&msg->body, PHPSTR_VAL(obj->message), PHPSTR_LEN(obj->message)); + + RETURN_OBJVAL(http_message_object_new_ex(http_message_object_ce, msg, NULL)); +} +/* }}} */ + +/* {{{ proto void HttpMessage::prepend(HttpMessage message) + * + * Prepends message(s) to the HTTP message. + * + * Expects an HttpMessage object as parameter. + */ +PHP_METHOD(HttpMessage, prepend) +{ + zval *prepend; + zend_bool top = 1; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, http_message_object_ce, &top)) { + zval m; + http_message *save_parent_msg; + zend_object_value save_parent_obj; + getObject(http_message_object, obj); + getObjectEx(http_message_object, prepend_obj, prepend); + + INIT_PZVAL(&m); + m.type = IS_OBJECT; + + if (!top) { + save_parent_obj = obj->parent; + save_parent_msg = obj->message->parent; + } else { + /* iterate to the most parent object */ + while (obj->parent.handle) { + m.value.obj = obj->parent; + obj = zend_object_store_get_object(&m TSRMLS_CC); + } + } + + /* prepend */ + obj->parent = prepend->value.obj; + obj->message->parent = prepend_obj->message; + + /* add ref */ + zend_objects_store_add_ref(prepend TSRMLS_CC); + while (prepend_obj->parent.handle) { + m.value.obj = prepend_obj->parent; + zend_objects_store_add_ref(&m TSRMLS_CC); + prepend_obj = zend_object_store_get_object(&m TSRMLS_CC); + } + + if (!top) { + prepend_obj->parent = save_parent_obj; + prepend_obj->message->parent = save_parent_msg; + } + } +} +/* }}} */ + #endif /* ZEND_ENGINE_2 */ /* diff --git a/php_http_message_api.h b/php_http_message_api.h index 37ccb2c..cf94256 100644 --- a/php_http_message_api.h +++ b/php_http_message_api.h @@ -48,6 +48,9 @@ PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_t #define http_message_set_type(m, t) _http_message_set_type((m), (t)) PHP_HTTP_API void _http_message_set_type(http_message *m, http_message_type t); +#define http_message_set_info(m, i) _http_message_set_info((m), (i)) +PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info); + #define http_message_header(m, h) _http_message_header_ex((m), (h), sizeof(h)) #define http_message_header_ex _http_message_header_ex static inline zval *_http_message_header_ex(http_message *msg, char *key_str, size_t key_len) diff --git a/php_http_message_object.h b/php_http_message_object.h index 6bc06f2..8b28b15 100644 --- a/php_http_message_object.h +++ b/php_http_message_object.h @@ -95,6 +95,9 @@ PHP_METHOD(HttpMessage, unserialize); PHP_METHOD(HttpMessage, fromString); +PHP_METHOD(HttpMessage, detach); +PHP_METHOD(HttpMessage, prepend); + #endif #endif -- 2.30.2