- use a more iterative approach in inflate code (instead of a retry-style)
[m6w6/ext-http] / http_message_object.c
index 4cb201a2e6f21093403b525301c5d36fbc675a2e..8af5805076f966d5f4e34429f32176ed7f8b982a 100644 (file)
@@ -278,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);
                
@@ -596,7 +596,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);
 
@@ -651,6 +651,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);
 }
@@ -1125,22 +1133,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();
 }
 /* }}} */
 
@@ -1402,11 +1412,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)
 {
@@ -1414,6 +1426,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);
        }
 }