X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_message_object.c;h=5e03e1e07c79ea2b751ae9ef9dfed5356400ed29;hp=c642754c73641b81bf4182bee3a71d25ebc7f658;hb=dbc4ec02cd319000b5c8589910047cfe6d5738be;hpb=d650022122969644c33bd03a552af1a631429e16 diff --git a/http_message_object.c b/http_message_object.c index c642754..5e03e1e 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -123,8 +123,6 @@ HTTP_BEGIN_ARGS(prepend, 1) HTTP_END_ARGS; HTTP_EMPTY_ARGS(reverse); -#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 static zval *_http_message_object_read_prop(zval *object, zval *member, int type TSRMLS_DC); #define http_message_object_write_prop _http_message_object_write_prop @@ -132,6 +130,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va #define http_message_object_get_props _http_message_object_get_props static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC); +#define OBJ_PROP_CE http_message_object_ce zend_class_entry *http_message_object_ce; zend_function_entry http_message_object_fe[] = { HTTP_MESSAGE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) @@ -186,6 +185,7 @@ static zend_object_handlers http_message_object_handlers; PHP_MINIT_FUNCTION(http_message_object) { HTTP_REGISTER_CLASS_EX(HttpMessage, http_message_object, NULL, 0); + #ifndef WONKY # ifdef HAVE_SPL zend_class_implements(http_message_object_ce TSRMLS_CC, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator); @@ -195,17 +195,33 @@ PHP_MINIT_FUNCTION(http_message_object) #else zend_class_implements(http_message_object_ce TSRMLS_CC, 1, zend_ce_iterator); #endif - - 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.clone_obj = _http_message_object_clone_obj; 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; http_message_object_handlers.get_property_ptr_ptr = NULL; + DCL_PROP(PROTECTED, long, type, HTTP_MSG_NONE); + DCL_PROP(PROTECTED, string, body, ""); + DCL_PROP(PROTECTED, string, requestMethod, ""); + DCL_PROP(PROTECTED, string, requestUrl, ""); + DCL_PROP(PROTECTED, string, responseStatus, ""); + DCL_PROP(PROTECTED, long, responseCode, 0); + DCL_PROP_N(PROTECTED, httpVersion); + DCL_PROP_N(PROTECTED, headers); + DCL_PROP_N(PROTECTED, parentMessage); + +#ifndef WONKY + DCL_CONST(long, "TYPE_NONE", HTTP_MSG_NONE); + DCL_CONST(long, "TYPE_REQUEST", HTTP_MSG_REQUEST); + DCL_CONST(long, "TYPE_RESPONSE", HTTP_MSG_RESPONSE); +#endif + + 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); + return SUCCESS; } @@ -262,8 +278,8 @@ void _http_message_object_reverse(zval *this_ptr, zval *return_value TSRMLS_DC) void _http_message_object_prepend_ex(zval *this_ptr, zval *prepend, zend_bool top TSRMLS_DC) { zval m; - http_message *save_parent_msg; - zend_object_value save_parent_obj; + http_message *save_parent_msg = NULL; + zend_object_value save_parent_obj = {0, NULL}; getObject(http_message_object, obj); getObjectEx(http_message_object, prepend_obj, prepend); @@ -338,27 +354,6 @@ zend_object_value _http_message_object_clone_obj(zval *this_ptr TSRMLS_DC) return http_message_object_new_ex(Z_OBJCE_P(this_ptr), http_message_dup(obj->message), NULL); } -static inline void _http_message_object_declare_default_properties(TSRMLS_D) -{ - zend_class_entry *ce = http_message_object_ce; - -#ifndef WONKY - DCL_CONST(long, "TYPE_NONE", HTTP_MSG_NONE); - DCL_CONST(long, "TYPE_REQUEST", HTTP_MSG_REQUEST); - DCL_CONST(long, "TYPE_RESPONSE", HTTP_MSG_RESPONSE); -#endif - - DCL_PROP(PROTECTED, long, type, HTTP_MSG_NONE); - DCL_PROP(PROTECTED, string, body, ""); - DCL_PROP(PROTECTED, string, requestMethod, ""); - DCL_PROP(PROTECTED, string, requestUrl, ""); - DCL_PROP(PROTECTED, string, responseStatus, ""); - DCL_PROP(PROTECTED, long, responseCode, 0); - DCL_PROP_N(PROTECTED, httpVersion); - DCL_PROP_N(PROTECTED, headers); - DCL_PROP_N(PROTECTED, parentMessage); -} - void _http_message_object_free(zend_object *object TSRMLS_DC) { http_message_object *o = (http_message_object *) object; @@ -415,24 +410,24 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type case HTTP_MSG_PROPHASH_TYPE: case HTTP_MSG_CHILD_PROPHASH_TYPE: RETVAL_LONG(msg->type); - break; + break; case HTTP_MSG_PROPHASH_HTTP_VERSION: case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION: RETVAL_DOUBLE(msg->http.version); - break; + break; case HTTP_MSG_PROPHASH_BODY: case HTTP_MSG_CHILD_PROPHASH_BODY: phpstr_fix(PHPSTR(msg)); RETVAL_PHPSTR(PHPSTR(msg), 0, 1); - break; + break; case HTTP_MSG_PROPHASH_HEADERS: case HTTP_MSG_CHILD_PROPHASH_HEADERS: array_init(return_value); zend_hash_copy(Z_ARRVAL_P(return_value), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); - break; + break; case HTTP_MSG_PROPHASH_PARENT_MESSAGE: case HTTP_MSG_CHILD_PROPHASH_PARENT_MESSAGE: @@ -441,7 +436,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } else { RETVAL_NULL(); } - break; + break; case HTTP_MSG_PROPHASH_REQUEST_METHOD: case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD: @@ -450,7 +445,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } else { RETVAL_NULL(); } - break; + break; case HTTP_MSG_PROPHASH_REQUEST_URL: case HTTP_MSG_CHILD_PROPHASH_REQUEST_URL: @@ -459,7 +454,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } else { RETVAL_NULL(); } - break; + break; case HTTP_MSG_PROPHASH_RESPONSE_CODE: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE: @@ -468,7 +463,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } else { RETVAL_NULL(); } - break; + break; case HTTP_MSG_PROPHASH_RESPONSE_STATUS: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS: @@ -477,7 +472,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type } else { RETVAL_NULL(); } - break; + break; default: #ifdef WONKY @@ -485,7 +480,6 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type #else RETVAL_NULL(); #endif - break; } return return_value; @@ -519,27 +513,27 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_CHILD_PROPHASH_TYPE: convert_to_long(cpy); http_message_set_type(msg, Z_LVAL_P(cpy)); - break; + break; case HTTP_MSG_PROPHASH_HTTP_VERSION: case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION: convert_to_double(cpy); msg->http.version = Z_DVAL_P(cpy); - break; + break; case HTTP_MSG_PROPHASH_BODY: case HTTP_MSG_CHILD_PROPHASH_BODY: convert_to_string(cpy); phpstr_dtor(PHPSTR(msg)); phpstr_from_string_ex(PHPSTR(msg), Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)); - break; + break; case HTTP_MSG_PROPHASH_HEADERS: case HTTP_MSG_CHILD_PROPHASH_HEADERS: convert_to_array(cpy); zend_hash_clean(&msg->hdrs); zend_hash_copy(&msg->hdrs, Z_ARRVAL_P(cpy), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); - break; + break; case HTTP_MSG_PROPHASH_PARENT_MESSAGE: case HTTP_MSG_CHILD_PROPHASH_PARENT_MESSAGE: @@ -552,7 +546,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va Z_OBJ_ADDREF_P(value); obj->parent = value->value.obj; } - break; + break; case HTTP_MSG_PROPHASH_REQUEST_METHOD: case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD: @@ -560,7 +554,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va convert_to_string(cpy); STR_SET(msg->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } - break; + break; case HTTP_MSG_PROPHASH_REQUEST_URL: case HTTP_MSG_CHILD_PROPHASH_REQUEST_URL: @@ -568,7 +562,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va convert_to_string(cpy); STR_SET(msg->http.info.request.url, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } - break; + break; case HTTP_MSG_PROPHASH_RESPONSE_CODE: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE: @@ -576,7 +570,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va convert_to_long(cpy); msg->http.info.response.code = Z_LVAL_P(cpy); } - break; + break; case HTTP_MSG_PROPHASH_RESPONSE_STATUS: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS: @@ -584,13 +578,13 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va convert_to_string(cpy); STR_SET(msg->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } - break; + break; default: #ifdef WONKY zend_get_std_object_handlers()->write_property(object, member, value TSRMLS_CC); #endif - break; + break; } zval_free(&cpy); } @@ -601,7 +595,7 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) getObjectEx(http_message_object, obj, object); http_message *msg = obj->message; HashTable *props = OBJ_PROP(obj); - zval array; + zval array, *parent; INIT_ZARR(array, props); @@ -626,21 +620,20 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) ASSOC_PROP(array, long, "type", msg->type); ASSOC_PROP(array, double, "httpVersion", msg->http.version); - switch (msg->type) - { + switch (msg->type) { case HTTP_MSG_REQUEST: ASSOC_PROP(array, long, "responseCode", 0); ASSOC_STRINGL(array, "responseStatus", "", 0); ASSOC_STRING(array, "requestMethod", msg->http.info.request.method); ASSOC_STRING(array, "requestUrl", msg->http.info.request.url); - break; + break; case HTTP_MSG_RESPONSE: ASSOC_PROP(array, long, "responseCode", msg->http.info.response.code); ASSOC_STRING(array, "responseStatus", msg->http.info.response.status); ASSOC_STRINGL(array, "requestMethod", "", 0); ASSOC_STRINGL(array, "requestUrl", "", 0); - break; + break; case HTTP_MSG_NONE: default: @@ -648,7 +641,7 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) ASSOC_STRINGL(array, "responseStatus", "", 0); ASSOC_STRINGL(array, "requestMethod", "", 0); ASSOC_STRINGL(array, "requestUrl", "", 0); - break; + break; } MAKE_STD_ZVAL(headers); @@ -656,6 +649,14 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); ASSOC_PROP(array, zval, "headers", headers); ASSOC_STRINGL(array, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg)); + + MAKE_STD_ZVAL(parent); + if (msg->parent) { + ZVAL_OBJVAL(parent, obj->parent, 1); + } else { + ZVAL_NULL(parent); + } + ASSOC_PROP(array, zval, "parentMessage", parent); return OBJ_PROP(obj); } @@ -750,7 +751,7 @@ PHP_METHOD(HttpMessage, getBody) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); RETURN_PHPSTR(&obj->message->body, PHPSTR_FREE_NOT, 1); } @@ -787,7 +788,7 @@ PHP_METHOD(HttpMessage, getHeaders) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { zval headers; getObject(http_message_object, obj); @@ -859,7 +860,7 @@ PHP_METHOD(HttpMessage, getType) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); RETURN_LONG(obj->message->type); } @@ -895,7 +896,7 @@ PHP_METHOD(HttpMessage, getResponseCode) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE); RETURN_LONG(obj->message->http.info.response.code); @@ -943,7 +944,7 @@ PHP_METHOD(HttpMessage, getResponseStatus) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); HTTP_CHECK_MESSAGE_TYPE_RESPONSE(obj->message, RETURN_FALSE); RETURN_STRING(obj->message->http.info.response.status, 1); @@ -987,7 +988,7 @@ PHP_METHOD(HttpMessage, getRequestMethod) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE); RETURN_STRING(obj->message->http.info.request.method, 1); @@ -1019,8 +1020,8 @@ PHP_METHOD(HttpMessage, setRequestMethod) http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Cannot set HttpMessage::requestMethod to an empty string"); RETURN_FALSE; } - if (SUCCESS != http_check_method(method)) { - http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unkown request method: %s", method); + if (!http_request_method_exists(1, 0, method)) { + http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Unknown request method: %s", method); RETURN_FALSE; } @@ -1040,7 +1041,7 @@ PHP_METHOD(HttpMessage, getRequestUrl) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); HTTP_CHECK_MESSAGE_TYPE_REQUEST(obj->message, RETURN_FALSE); RETURN_STRING(obj->message->http.info.request.url, 1); @@ -1087,7 +1088,7 @@ PHP_METHOD(HttpMessage, getHttpVersion) { NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { char ver[4] = {0}; getObject(http_message_object, obj); @@ -1130,22 +1131,24 @@ PHP_METHOD(HttpMessage, setHttpVersion) /* {{{ proto HttpMessage HttpMessage::getParentMessage() * * Get parent Message. - * + * * Returns the parent HttpMessage on success, or NULL if there's none. + * + * Throws HttpRuntimeException. */ PHP_METHOD(HttpMessage, getParentMessage) { - NO_ARGS; - - IF_RETVAL_USED { + SET_EH_THROW_HTTP(); + NO_ARGS { getObject(http_message_object, obj); if (obj->message->parent) { RETVAL_OBJVAL(obj->parent, 1); } else { - RETVAL_NULL(); + http_error(HE_WARNING, HTTP_E_RUNTIME, "HttpMessage does not have a parent message"); } } + SET_EH_NORMAL(); } /* }}} */ @@ -1177,7 +1180,7 @@ PHP_METHOD(HttpMessage, send) */ PHP_METHOD(HttpMessage, toString) { - IF_RETVAL_USED { + if (return_value_used) { char *string; size_t length; zend_bool include_parent = 0; @@ -1211,11 +1214,10 @@ PHP_METHOD(HttpMessage, toMessageTypeObject) NO_ARGS; - IF_RETVAL_USED { + if (return_value_used) { getObject(http_message_object, obj); - switch (obj->message->type) - { + switch (obj->message->type) { case HTTP_MSG_REQUEST: { #ifdef HTTP_HAVE_CURL @@ -1258,8 +1260,8 @@ PHP_METHOD(HttpMessage, toMessageTypeObject) #else http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot transform HttpMessage to HttpRequest (missing curl support)"); #endif + break; } - break; case HTTP_MSG_RESPONSE: { @@ -1283,8 +1285,7 @@ PHP_METHOD(HttpMessage, toMessageTypeObject) INIT_PZVAL(&zkey); ZVAL_STRINGL(&zkey, key, key_len, 0); - switch (Z_TYPE_PP(header)) - { + switch (Z_TYPE_PP(header)) { case IS_ARRAY: case IS_OBJECT: FOREACH_HASH_VAL(pos2, HASH_OF(*header), h) { @@ -1292,13 +1293,13 @@ PHP_METHOD(HttpMessage, toMessageTypeObject) zend_call_method_with_2_params(&return_value, http_response_object_ce, NULL, "setheader", NULL, &zkey, *h); zval_ptr_dtor(h); } - break; + break; default: ZVAL_ADDREF(*header); zend_call_method_with_2_params(&return_value, http_response_object_ce, NULL, "setheader", NULL, &zkey, *header); zval_ptr_dtor(header); - break; + break; } key = NULL; } @@ -1311,12 +1312,12 @@ PHP_METHOD(HttpMessage, toMessageTypeObject) #else http_error(HE_WARNING, HTTP_E_RUNTIME, "Cannot transform HttpMessage to HttpResponse (need PHP 5.1+)"); #endif + break; } - break; default: http_error(HE_WARNING, HTTP_E_MESSAGE_TYPE, "HttpMessage is neither of type HttpMessage::TYPE_REQUEST nor HttpMessage::TYPE_RESPONSE"); - break; + break; } } SET_EH_NORMAL(); @@ -1407,11 +1408,13 @@ PHP_METHOD(HttpMessage, detach) } /* }}} */ -/* {{{ proto void HttpMessage::prepend(HttpMessage message) +/* {{{ proto void HttpMessage::prepend(HttpMessage message[, bool top = true]) * * Prepends message(s) to the HTTP message. * * Expects an HttpMessage object as parameter. + * + * Throws HttpInvalidParamException if the message is located within the same message chain. */ PHP_METHOD(HttpMessage, prepend) { @@ -1419,6 +1422,20 @@ PHP_METHOD(HttpMessage, prepend) zend_bool top = 1; if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, http_message_object_ce, &top)) { + http_message *msg[2]; + getObject(http_message_object, obj); + getObjectEx(http_message_object, prepend_obj, prepend); + + /* safety check */ + for (msg[0] = obj->message; msg[0]; msg[0] = msg[0]->parent) { + for (msg[1] = prepend_obj->message; msg[1]; msg[1] = msg[1]->parent) { + if (msg[0] == msg[1]) { + http_error(HE_THROW, HTTP_E_INVALID_PARAM, "Cannot prepend a message located within the same message chain"); + return; + } + } + } + http_message_object_prepend_ex(getThis(), prepend, top); } }