allow retrieval of header as http\Header
[m6w6/ext-http] / php_http_message.c
index 3ac96550b5ac20bf8d819775c635d879b034ed66..57b66b3f5437866292db1cbeea9ad1b608c4f2ef 100644 (file)
@@ -515,6 +515,7 @@ PHP_HTTP_END_ARGS;
 
 PHP_HTTP_BEGIN_ARGS(getHeader, 1)
        PHP_HTTP_ARG_VAL(header, 0)
+       PHP_HTTP_ARG_VAL(into_class, 0)
 PHP_HTTP_END_ARGS;
 
 PHP_HTTP_BEGIN_ARGS(setHeader, 1)
@@ -610,7 +611,6 @@ PHP_HTTP_EMPTY_ARGS(splitMultipartBody);
 
 static zval *php_http_message_object_read_prop(zval *object, zval *member, int type PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC);
 static void php_http_message_object_write_prop(zval *object, zval *member, zval *value PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC);
-static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC);
 static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC);
 
 static zend_class_entry *php_http_message_class_entry;
@@ -689,9 +689,6 @@ static STATUS php_http_message_object_add_prophandler(const char *prop_str, size
        php_http_message_object_prophandler_t h = { read, write };
        return zend_hash_add(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) &h, sizeof(h), NULL);
 }
-static int php_http_message_object_has_prophandler(const char *prop_str, size_t prop_len) {
-       return zend_hash_exists(&php_http_message_object_prophandlers, prop_str, prop_len + 1);
-}
 static STATUS php_http_message_object_get_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_t **handler) {
        return zend_hash_find(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) handler);
 }
@@ -822,7 +819,7 @@ PHP_MINIT_FUNCTION(http_message)
        php_http_message_object_handlers.read_property = php_http_message_object_read_prop;
        php_http_message_object_handlers.write_property = php_http_message_object_write_prop;
        php_http_message_object_handlers.get_properties = php_http_message_object_get_props;
-       php_http_message_object_handlers.get_property_ptr_ptr = php_http_message_object_get_prop_ptr;
+       php_http_message_object_handlers.get_property_ptr_ptr = NULL;
 
        zend_class_implements(php_http_message_class_entry TSRMLS_CC, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator);
 
@@ -1025,7 +1022,6 @@ zend_object_value php_http_message_object_new(zend_class_entry *ce TSRMLS_DC)
 
 zend_object_value php_http_message_object_new_ex(zend_class_entry *ce, php_http_message_t *msg, php_http_message_object_t **ptr TSRMLS_DC)
 {
-       zend_object_value ov;
        php_http_message_object_t *o;
 
        o = ecalloc(1, sizeof(php_http_message_object_t));
@@ -1044,10 +1040,10 @@ zend_object_value php_http_message_object_new_ex(zend_class_entry *ce, php_http_
                o->body = php_http_message_body_object_new_ex(php_http_message_body_get_class_entry(), php_http_message_body_init(&msg->body, NULL TSRMLS_CC), NULL TSRMLS_CC);
        }
 
-       ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_http_message_object_free, NULL TSRMLS_CC);
-       ov.handlers = &php_http_message_object_handlers;
+       o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_http_message_object_free, NULL TSRMLS_CC);
+       o->zv.handlers = &php_http_message_object_handlers;
 
-       return ov;
+       return o->zv;
 }
 
 zend_object_value php_http_message_object_clone(zval *this_ptr TSRMLS_DC)
@@ -1086,20 +1082,6 @@ void php_http_message_object_free(void *object TSRMLS_DC)
        efree(o);
 }
 
-
-static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC)
-{
-       zval *copy = php_http_ztyp(IS_STRING, member);
-
-       if (php_http_message_object_has_prophandler(Z_STRVAL_P(copy), Z_STRLEN_P(copy))) {
-               zval_ptr_dtor(&copy);
-               return &php_http_property_proxy_init(NULL, object, member, NULL TSRMLS_CC)->myself;
-       }
-       zval_ptr_dtor(&copy);
-
-       return zend_get_std_object_handlers()->get_property_ptr_ptr(object, member PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC);
-}
-
 static zval *php_http_message_object_read_prop(zval *object, zval *member, int type PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC)
 {
        php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
@@ -1109,15 +1091,15 @@ static zval *php_http_message_object_read_prop(zval *object, zval *member, int t
        PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
 
        if (SUCCESS == php_http_message_object_get_prophandler(Z_STRVAL_P(copy), Z_STRLEN_P(copy), &handler)) {
-               if (type == BP_VAR_R) {
-                       ALLOC_ZVAL(return_value);
-                       Z_SET_REFCOUNT_P(return_value, 0);
-                       Z_UNSET_ISREF_P(return_value);
+               ALLOC_ZVAL(return_value);
+               Z_SET_REFCOUNT_P(return_value, 0);
+               Z_UNSET_ISREF_P(return_value);
 
+               if (type == BP_VAR_R) {
                        handler->read(obj, return_value TSRMLS_CC);
                } else {
-                       zend_error(E_ERROR, "Cannot access HttpMessage properties by reference or array key/index");
-                       return_value = NULL;
+                       php_property_proxy_t *proxy = php_property_proxy_init(object, Z_STRVAL_P(copy), Z_STRLEN_P(copy) TSRMLS_CC);
+                       RETVAL_OBJVAL(php_property_proxy_object_new_ex(php_property_proxy_get_class_entry(), proxy, NULL TSRMLS_CC), 0);
                }
        } else {
                return_value = zend_get_std_object_handlers()->read_property(object, member, type PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC);
@@ -1319,20 +1301,41 @@ PHP_METHOD(HttpMessage, addBody)
        RETVAL_ZVAL(getThis(), 1, 0);
 }
 
-
 PHP_METHOD(HttpMessage, getHeader)
 {
        char *header_str;
        int header_len;
+       zend_class_entry *header_ce = NULL;
 
-       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &header_str, &header_len)) {
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C!", &header_str, &header_len, &header_ce)) {
                php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
                zval *header;
 
                PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
 
                if ((header = php_http_message_header(obj->message, header_str, header_len, 0))) {
-                       RETURN_ZVAL(header, 1, 1);
+                       if (!header_ce) {
+                               RETURN_ZVAL(header, 1, 1);
+                       } else if (instanceof_function(header_ce, php_http_header_get_class_entry() TSRMLS_CC)) {
+                               zval *header_name, **argv[2];
+
+                               MAKE_STD_ZVAL(header_name);
+                               ZVAL_STRINGL(header_name, header_str, header_len, 1);
+                               Z_ADDREF_P(header);
+
+                               argv[0] = &header_name;
+                               argv[1] = &header;
+
+                               object_init_ex(return_value, header_ce);
+                               php_http_method_call(return_value, ZEND_STRL("__construct"), 2, argv, NULL TSRMLS_CC);
+
+                               zval_ptr_dtor(&header_name);
+                               zval_ptr_dtor(&header);
+
+                               return;
+                       } else {
+                               php_http_error(HE_WARNING, PHP_HTTP_E_INVALID_PARAM, "Class '%s' is not as descendant of http\\Header", header_ce->name);
+                       }
                }
        }
        RETURN_FALSE;