X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=php_http_message.c;h=e4b4660d7d3de54259c4d6600f24f66b9d3cfc15;hp=176a27b56a2f489b288a4733725f700ae42b5841;hb=d5de4f9eae86ae1dab0f8a906bf9543710ae124d;hpb=16273970757b5f5bf733f8e0765b0526af7f071f diff --git a/php_http_message.c b/php_http_message.c index 176a27b..e4b4660 100644 --- a/php_http_message.c +++ b/php_http_message.c @@ -12,6 +12,9 @@ #include "php_http_api.h" +static zval *message_header_strval(zval **header TSRMLS_DC); +static void message_headers(php_http_message_t *msg, php_http_buffer_t *str); + PHP_HTTP_API zend_bool php_http_message_info_callback(php_http_message_t **message, HashTable **headers, php_http_info_t *info TSRMLS_DC) { php_http_message_t *old = *message; @@ -41,6 +44,8 @@ PHP_HTTP_API php_http_message_t *php_http_message_init(php_http_message_t *messa TSRMLS_SET_CTX(message->ts); php_http_message_set_type(message, type); + message->http.version.major = 1; + message->http.version.minor = 1; zend_hash_init(&message->hdrs, 0, NULL, ZVAL_PTR_DTOR, 0); php_http_message_body_init(&message->body, NULL TSRMLS_CC); @@ -59,9 +64,6 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m case PHP_HTTP_REQUEST: if ((sval = php_http_env_get_server_var(ZEND_STRL("SERVER_PROTOCOL"), 1 TSRMLS_CC)) && !strncmp(Z_STRVAL_P(sval), "HTTP/", lenof("HTTP/"))) { php_http_version_parse(&message->http.version, Z_STRVAL_P(sval) TSRMLS_CC); - } else { - message->http.version.major = 1; - message->http.version.minor = 1; } if ((sval = php_http_env_get_server_var(ZEND_STRL("REQUEST_METHOD"), 1 TSRMLS_CC))) { message->http.info.request.method = estrdup(Z_STRVAL_P(sval)); @@ -80,8 +82,6 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m case PHP_HTTP_RESPONSE: if (!SG(sapi_headers).http_status_line || !php_http_info_parse((php_http_info_t *) &message->http, SG(sapi_headers).http_status_line TSRMLS_CC)) { - message->http.version.major = 1; - message->http.version.minor = 1; if (!(message->http.info.response.code = SG(sapi_headers).http_response_code)) { message->http.info.response.code = 200; } @@ -89,7 +89,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m } php_http_env_get_response_headers(&message->hdrs TSRMLS_CC); - +#if PHP_VERSION_ID >= 50400 if (php_output_get_level(TSRMLS_C)) { if (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT) { php_http_error(HE_WARNING, PHP_HTTP_E_RUNTIME, "Could not fetch response body, output has already been sent at %s:%d", php_output_get_start_filename(TSRMLS_C), php_output_get_start_lineno(TSRMLS_C)); @@ -102,6 +102,7 @@ PHP_HTTP_API php_http_message_t *php_http_message_init_env(php_http_message_t *m zval_dtor(&tval); } } +#endif break; default: @@ -150,21 +151,9 @@ PHP_HTTP_API zval *php_http_message_header(php_http_message_t *msg, char *key_st if (SUCCESS == zend_symtable_find(&msg->hdrs, key, key_len + 1, (void *) &header)) { if (join && Z_TYPE_PP(header) == IS_ARRAY) { - zval *header_str, **val; - HashPosition pos; - php_http_buffer_t str; TSRMLS_FETCH_FROM_CTX(msg->ts); - php_http_buffer_init(&str); - MAKE_STD_ZVAL(header_str); - FOREACH_VAL(pos, *header, val) { - zval *strval = php_http_ztyp(IS_STRING, *val); - php_http_buffer_appendf(&str, PHP_HTTP_BUFFER_LEN(&str) ? ", %s":"%s", Z_STRVAL_P(strval)); - zval_ptr_dtor(&strval); - } - php_http_buffer_fix(&str); - ZVAL_STRINGL(header_str, PHP_HTTP_BUFFER_VAL(&str), PHP_HTTP_BUFFER_LEN(&str), 0); - ret = header_str; + ret = message_header_strval(header TSRMLS_CC); } else { Z_ADDREF_PP(header); ret = *header; @@ -280,27 +269,12 @@ PHP_HTTP_API void php_http_message_set_info(php_http_message_t *message, php_htt } } -static inline void message_headers(php_http_message_t *msg, php_http_buffer_t *str) +PHP_HTTP_API void php_http_message_update_headers(php_http_message_t *msg) { - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - HashPosition pos1; - zval **header, *h; + zval *h; size_t size; TSRMLS_FETCH_FROM_CTX(msg->ts); - switch (msg->type) { - case PHP_HTTP_REQUEST: - php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, PHP_HTTP_CRLF)); - break; - - case PHP_HTTP_RESPONSE: - php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, PHP_HTTP_CRLF)); - break; - - default: - break; - } - if ((size = php_http_message_body_size(&msg->body))) { MAKE_STD_ZVAL(h); ZVAL_LONG(h, size); @@ -324,51 +298,90 @@ static inline void message_headers(php_http_message_t *msg, php_http_buffer_t *s } } } +} + +static zval *message_header_strval(zval **header TSRMLS_DC) +{ + zval *ret; + + if (Z_TYPE_PP(header) == IS_BOOL) { + MAKE_STD_ZVAL(ret); + ZVAL_STRING(ret, Z_BVAL_PP(header) ? "true" : "false", 1); + } else if (Z_TYPE_PP(header) == IS_ARRAY) { + zval **val; + HashPosition pos; + php_http_buffer_t str; + + php_http_buffer_init(&str); + MAKE_STD_ZVAL(ret); + FOREACH_VAL(pos, *header, val) { + zval *strval = message_header_strval(val TSRMLS_CC); + + php_http_buffer_appendf(&str, PHP_HTTP_BUFFER_LEN(&str) ? ", %s":"%s", Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); + } + php_http_buffer_fix(&str); + ZVAL_STRINGL(ret, PHP_HTTP_BUFFER_VAL(&str), PHP_HTTP_BUFFER_LEN(&str), 0); + } else { + ret = php_http_zsep(1, IS_STRING, *header); + } + + return ret; +} + +static void message_headers(php_http_message_t *msg, php_http_buffer_t *str) +{ + php_http_array_hashkey_t key = php_http_array_hashkey_init(0); + HashPosition pos1; + zval **header; + TSRMLS_FETCH_FROM_CTX(msg->ts); + + switch (msg->type) { + case PHP_HTTP_REQUEST: + php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, PHP_HTTP_CRLF)); + break; + + case PHP_HTTP_RESPONSE: + php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, PHP_HTTP_CRLF)); + break; + + default: + break; + } + + php_http_message_update_headers(msg); FOREACH_HASH_KEYVAL(pos1, &msg->hdrs, key, header) { if (key.type == HASH_KEY_IS_STRING) { - HashPosition pos2; - zval **single_header; - - switch (Z_TYPE_PP(header)) { - case IS_BOOL: - php_http_buffer_appendf(str, "%s: %s" PHP_HTTP_CRLF, key.str, Z_BVAL_PP(header)?"true":"false"); - break; - - case IS_LONG: - php_http_buffer_appendf(str, "%s: %ld" PHP_HTTP_CRLF, key.str, Z_LVAL_PP(header)); - break; - - case IS_DOUBLE: - php_http_buffer_appendf(str, "%s: %F" PHP_HTTP_CRLF, key.str, Z_DVAL_PP(header)); - break; - - case IS_STRING: - if (Z_STRVAL_PP(header)[Z_STRLEN_PP(header)-1] == '\r') fprintf(stderr, "DOH!\n"); - php_http_buffer_appendf(str, "%s: %s" PHP_HTTP_CRLF, key.str, Z_STRVAL_PP(header)); - break; - - case IS_ARRAY: - FOREACH_VAL(pos2, *header, single_header) { - switch (Z_TYPE_PP(single_header)) { - case IS_BOOL: - php_http_buffer_appendf(str, "%s: %s" PHP_HTTP_CRLF, key.str, Z_BVAL_PP(single_header)?"true":"false"); - break; - - case IS_LONG: - php_http_buffer_appendf(str, "%s: %ld" PHP_HTTP_CRLF, key.str, Z_LVAL_PP(single_header)); - break; - - case IS_DOUBLE: - php_http_buffer_appendf(str, "%s: %F" PHP_HTTP_CRLF, key.str, Z_DVAL_PP(single_header)); - break; - - case IS_STRING: - php_http_buffer_appendf(str, "%s: %s" PHP_HTTP_CRLF, key.str, Z_STRVAL_PP(single_header)); - break; + if (key.len == sizeof("Set-Cookie") && !strcasecmp(key.str, "Set-Cookie") && Z_TYPE_PP(header) == IS_ARRAY) { + HashPosition pos2; + zval **single_header; + + FOREACH_VAL(pos2, *header, single_header) { + if (Z_TYPE_PP(single_header) == IS_ARRAY) { + php_http_cookie_list_t *cookie = php_http_cookie_list_from_struct(NULL, *single_header TSRMLS_CC); + + if (cookie) { + char *buf; + size_t len; + + php_http_cookie_list_to_string(cookie, &buf, &len); + php_http_buffer_appendf(str, "Set-Cookie: %s" PHP_HTTP_CRLF, buf); + php_http_cookie_list_free(&cookie); + efree(buf); } + } else { + zval *strval = message_header_strval(single_header TSRMLS_CC); + + php_http_buffer_appendf(str, "Set-Cookie: %s" PHP_HTTP_CRLF, Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); } - break; + } + } else { + zval *strval = message_header_strval(header TSRMLS_CC); + + php_http_buffer_appendf(str, "%s: %s" PHP_HTTP_CRLF, key.str, Z_STRVAL_P(strval)); + zval_ptr_dtor(&strval); } } } @@ -458,6 +471,24 @@ PHP_HTTP_API php_http_message_t *php_http_message_reverse(php_http_message_t *ms return msg; } +PHP_HTTP_API php_http_message_t *php_http_message_zip(php_http_message_t *one, php_http_message_t *two) +{ + php_http_message_t *dst = php_http_message_copy(one, NULL), *src = php_http_message_copy(two, NULL), *tmp_dst, *tmp_src, *ret = dst; + + while(dst && src) { + tmp_dst = dst->parent; + tmp_src = src->parent; + dst->parent = src; + if (tmp_dst) { + src->parent = tmp_dst; + } + src = tmp_src; + dst = tmp_dst; + } + + return ret; +} + PHP_HTTP_API php_http_message_t *php_http_message_copy_ex(php_http_message_t *from, php_http_message_t *to, zend_bool parents) { php_http_message_t *temp, *copy = NULL; @@ -542,6 +573,10 @@ PHP_HTTP_BEGIN_ARGS(setBody, 1) PHP_HTTP_ARG_VAL(body, 0) PHP_HTTP_END_ARGS; +PHP_HTTP_BEGIN_ARGS(addBody, 1) + PHP_HTTP_ARG_VAL(body, 0) +PHP_HTTP_END_ARGS; + PHP_HTTP_BEGIN_ARGS(getHeader, 1) PHP_HTTP_ARG_VAL(header, 0) PHP_HTTP_END_ARGS; @@ -606,6 +641,12 @@ PHP_HTTP_EMPTY_ARGS(__toString); PHP_HTTP_BEGIN_ARGS(toString, 0) PHP_HTTP_ARG_VAL(include_parent, 0) PHP_HTTP_END_ARGS; +PHP_HTTP_BEGIN_ARGS(toCallback, 1) + PHP_HTTP_ARG_VAL(callback, 0) +PHP_HTTP_END_ARGS; +PHP_HTTP_BEGIN_ARGS(toStream, 1) + PHP_HTTP_ARG_VAL(stream, 0) +PHP_HTTP_END_ARGS; PHP_HTTP_EMPTY_ARGS(count); @@ -631,16 +672,23 @@ PHP_HTTP_BEGIN_ARGS(isMultipart, 0) PHP_HTTP_END_ARGS; PHP_HTTP_EMPTY_ARGS(splitMultipartBody); -static zval *php_http_message_object_read_prop(zval *object, zval *member, int type, const zend_literal *literal_key TSRMLS_DC); -static void php_http_message_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC); -static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member, const zend_literal *literal_key TSRMLS_DC); +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); -zend_class_entry *php_http_message_class_entry; -zend_function_entry php_http_message_method_entry[] = { +static zend_class_entry *php_http_message_class_entry; + +zend_class_entry *php_http_message_get_class_entry(void) +{ + return php_http_message_class_entry; +} + +static zend_function_entry php_http_message_method_entry[] = { PHP_HTTP_MESSAGE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_HTTP_MESSAGE_ME(getBody, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(setBody, ZEND_ACC_PUBLIC) + PHP_HTTP_MESSAGE_ME(addBody, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(getHeader, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(setHeader, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(addHeader, ZEND_ACC_PUBLIC) @@ -663,6 +711,8 @@ zend_function_entry php_http_message_method_entry[] = { PHP_HTTP_MESSAGE_ME(setHttpVersion, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(getParentMessage, ZEND_ACC_PUBLIC) PHP_HTTP_MESSAGE_ME(toString, ZEND_ACC_PUBLIC) + PHP_HTTP_MESSAGE_ME(toCallback, ZEND_ACC_PUBLIC) + PHP_HTTP_MESSAGE_ME(toStream, ZEND_ACC_PUBLIC) /* implements Countable */ PHP_HTTP_MESSAGE_ME(count, ZEND_ACC_PUBLIC) @@ -807,13 +857,7 @@ static void php_http_message_object_prophandler_get_body(php_http_message_object } } static void php_http_message_object_prophandler_set_body(php_http_message_object_t *obj, zval *value TSRMLS_DC) { - if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_message_body_class_entry TSRMLS_CC)) { - if (obj->body.handle) { - zend_objects_store_del_ref_by_handle(obj->body.handle TSRMLS_CC); - } - Z_OBJ_ADDREF_P(value); - obj->body = Z_OBJVAL_P(value); - } + php_http_message_object_set_body(obj, value TSRMLS_CC); } static void php_http_message_object_prophandler_get_parent_message(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) { if (obj->message->parent) { @@ -834,7 +878,7 @@ static void php_http_message_object_prophandler_set_parent_message(php_http_mess PHP_MINIT_FUNCTION(http_message) { - PHP_HTTP_REGISTER_CLASS(http, Message, http_message, php_http_object_class_entry, 0); + PHP_HTTP_REGISTER_CLASS(http, Message, http_message, php_http_object_get_class_entry(), 0); php_http_message_class_entry->create_object = php_http_message_object_new; memcpy(&php_http_message_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_http_message_object_handlers.clone_obj = php_http_message_object_clone; @@ -966,6 +1010,68 @@ void php_http_message_object_prepend(zval *this_ptr, zval *prepend, zend_bool to } } +STATUS php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval *zbody TSRMLS_DC) +{ + zval *tmp = NULL; + php_stream *s; + zend_object_value ov; + php_http_message_body_t *body; + php_http_message_body_object_t *body_obj; + + switch (Z_TYPE_P(zbody)) { + case IS_RESOURCE: + php_stream_from_zval_no_verify(s, &zbody); + if (!s) { + php_http_error(HE_THROW, PHP_HTTP_E_CLIENT, "not a valid stream resource"); + return FAILURE; + } + + is_resource: + + body = php_http_message_body_init(NULL, s TSRMLS_CC); + if (SUCCESS != php_http_new(&ov, php_http_message_body_get_class_entry(), (php_http_new_t) php_http_message_body_object_new_ex, NULL, body, NULL TSRMLS_CC)) { + php_http_message_body_free(&body); + return FAILURE; + } + MAKE_STD_ZVAL(tmp); + ZVAL_OBJVAL(tmp, ov, 0); + zbody = tmp; + break; + + case IS_OBJECT: + if (instanceof_function(Z_OBJCE_P(zbody), php_http_message_body_get_class_entry() TSRMLS_CC)) { + Z_OBJ_ADDREF_P(zbody); + break; + } + /* no break */ + + default: + tmp = php_http_ztyp(IS_STRING, zbody); + s = php_stream_temp_new(); + php_stream_write(s, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + zval_ptr_dtor(&tmp); + tmp = NULL; + goto is_resource; + + } + + body_obj = zend_object_store_get_object(zbody TSRMLS_CC); + + if (msg_obj->body.handle) { + zend_objects_store_del_ref_by_handle(msg_obj->body.handle TSRMLS_CC); + php_http_message_body_dtor(&msg_obj->message->body); + } + + php_http_message_body_copy(body_obj->body, &msg_obj->message->body, 0); + msg_obj->body = Z_OBJVAL_P(zbody); + + if (tmp) { + zval_ptr_dtor(&tmp); + } + + return SUCCESS; +} + zend_object_value php_http_message_object_new(zend_class_entry *ce TSRMLS_DC) { return php_http_message_object_new_ex(ce, NULL, NULL TSRMLS_CC); @@ -989,7 +1095,7 @@ zend_object_value php_http_message_object_new_ex(zend_class_entry *ce, php_http_ if (msg->parent) { o->parent = php_http_message_object_new_ex(ce, msg->parent, NULL TSRMLS_CC); } - o->body = php_http_message_body_object_new_ex(php_http_message_body_class_entry, php_http_message_body_copy(&msg->body, NULL, 0), NULL TSRMLS_CC); + o->body = php_http_message_body_object_new_ex(php_http_message_body_get_class_entry(), php_http_message_body_copy(&msg->body, NULL, 0), NULL TSRMLS_CC); } ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_http_message_object_free, NULL TSRMLS_CC); @@ -1035,7 +1141,7 @@ void php_http_message_object_free(void *object TSRMLS_DC) } -static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member, const zend_literal *literal_key TSRMLS_DC) +static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC) { php_http_message_object_prophandler_t *handler; zval *copy = php_http_ztyp(IS_STRING, member); @@ -1046,10 +1152,10 @@ static zval **php_http_message_object_get_prop_ptr(zval *object, zval *member, c } zval_ptr_dtor(©); - return zend_get_std_object_handlers()->get_property_ptr_ptr(object, member, literal_key TSRMLS_CC); + 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, const zend_literal *literal_key TSRMLS_DC) +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); php_http_message_object_prophandler_t *handler; @@ -1067,7 +1173,7 @@ static zval *php_http_message_object_read_prop(zval *object, zval *member, int t return_value = NULL; } } else { - return_value = zend_get_std_object_handlers()->read_property(object, member, type, literal_key TSRMLS_CC); + return_value = zend_get_std_object_handlers()->read_property(object, member, type PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC); } zval_ptr_dtor(©); @@ -1075,7 +1181,7 @@ static zval *php_http_message_object_read_prop(zval *object, zval *member, int t return return_value; } -static void php_http_message_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC) +static void php_http_message_object_write_prop(zval *object, zval *member, zval *value PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC) { php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC); php_http_message_object_prophandler_t *handler; @@ -1084,7 +1190,7 @@ static void php_http_message_object_write_prop(zval *object, zval *member, zval if (SUCCESS == php_http_message_object_get_prophandler(Z_STRVAL_P(copy), Z_STRLEN_P(copy), &handler)) { handler->write(obj, value TSRMLS_CC); } else { - zend_get_std_object_handlers()->write_property(object, member, value, literal_key TSRMLS_CC); + zend_get_std_object_handlers()->write_property(object, member, value PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC); } zval_ptr_dtor(©); @@ -1155,7 +1261,7 @@ static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC) MAKE_STD_ZVAL(body); if (!obj->body.handle) { - php_http_new(&obj->body, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, (void *) php_http_message_body_copy(&obj->message->body, NULL, 0), NULL TSRMLS_CC); + php_http_new(&obj->body, php_http_message_body_get_class_entry(), (php_http_new_t) php_http_message_body_object_new_ex, NULL, (void *) php_http_message_body_copy(&obj->message->body, NULL, 0), NULL TSRMLS_CC); } ZVAL_OBJVAL(body, obj->body, 1); ASSOC_PROP(array, zval, "body", body); @@ -1179,7 +1285,7 @@ PHP_METHOD(HttpMessage, __construct) php_http_message_t *msg = NULL; php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - with_error_handling(EH_THROW, php_http_exception_class_entry) { + with_error_handling(EH_THROW, php_http_exception_get_class_entry()) { if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &zmessage) && zmessage) { if (Z_TYPE_P(zmessage) == IS_RESOURCE) { php_stream *s; @@ -1215,7 +1321,7 @@ PHP_METHOD(HttpMessage, __construct) PHP_METHOD(HttpMessage, getBody) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { + with_error_handling(EH_THROW, php_http_exception_get_class_entry()) { if (SUCCESS == zend_parse_parameters_none()) { php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); @@ -1223,7 +1329,7 @@ PHP_METHOD(HttpMessage, getBody) obj->message = php_http_message_init(NULL, 0 TSRMLS_CC); } - if (obj->body.handle || SUCCESS == php_http_new(&obj->body, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, (void *) php_http_message_body_copy(&obj->message->body, NULL, 0), NULL TSRMLS_CC)) { + if (obj->body.handle || SUCCESS == php_http_new(&obj->body, php_http_message_body_get_class_entry(), (php_http_new_t) php_http_message_body_object_new_ex, NULL, (void *) php_http_message_body_copy(&obj->message->body, NULL, 0), NULL TSRMLS_CC)) { RETVAL_OBJVAL(obj->body, 1); } } @@ -1234,22 +1340,32 @@ PHP_METHOD(HttpMessage, setBody) { zval *zbody; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zbody, php_http_message_body_class_entry)) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zbody, php_http_message_body_get_class_entry())) { php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); php_http_message_body_object_t *body_obj = zend_object_store_get_object(zbody TSRMLS_CC); if (!obj->message) { obj->message = php_http_message_init(NULL, 0 TSRMLS_CC); } + php_http_message_object_prophandler_set_body(obj, zbody TSRMLS_CC); + } + RETVAL_ZVAL(getThis(), 1, 0); +} + +PHP_METHOD(HttpMessage, addBody) +{ + zval *new_body; - php_http_message_body_dtor(&obj->message->body); - php_http_message_body_copy(body_obj->body, &obj->message->body, 0); - Z_OBJ_ADDREF_P(zbody); - obj->body = Z_OBJVAL_P(zbody); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &new_body, php_http_message_body_get_class_entry())) { + php_http_message_body_object_t *old_obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_body_object_t *new_obj = zend_object_store_get_object(new_body TSRMLS_CC); + + php_http_message_body_to_callback(old_obj->body, (php_http_pass_callback_t) php_http_message_body_append, new_obj->body, 0, 0); } RETVAL_ZVAL(getThis(), 1, 0); } + PHP_METHOD(HttpMessage, getHeader) { char *header_str; @@ -1650,7 +1766,7 @@ PHP_METHOD(HttpMessage, setRequestUrl) PHP_METHOD(HttpMessage, getParentMessage) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { + with_error_handling(EH_THROW, php_http_exception_get_class_entry()) { if (SUCCESS == zend_parse_parameters_none()) { php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); @@ -1692,6 +1808,44 @@ PHP_METHOD(HttpMessage, toString) RETURN_EMPTY_STRING(); } +PHP_METHOD(HttpMessage, toStream) +{ + zval *zstream; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream)) { + php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_stream *s; + + php_stream_from_zval(s, &zstream); + + if (!obj->message) { + obj->message = php_http_message_init(NULL, 0 TSRMLS_CC); + } + + php_http_message_to_callback(obj->message, (php_http_pass_callback_t) _php_stream_write, s); + } +} + +PHP_METHOD(HttpMessage, toCallback) +{ + php_http_pass_fcall_arg_t fcd; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fcd.fci, &fcd.fcc)) { + php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + fcd.fcz = getThis(); + Z_ADDREF_P(fcd.fcz); + TSRMLS_SET_CTX(fcd.ts); + + php_http_message_to_callback(obj->message, php_http_pass_fcall_callback, &fcd); + zend_fcall_info_args_clear(&fcd.fci, 1); + + zval_ptr_dtor(&fcd.fcz); + RETURN_TRUE; + } + RETURN_FALSE; +} + PHP_METHOD(HttpMessage, serialize) { if (SUCCESS == zend_parse_parameters_none()) { @@ -1733,7 +1887,7 @@ PHP_METHOD(HttpMessage, unserialize) PHP_METHOD(HttpMessage, detach) { - with_error_handling(EH_THROW, php_http_exception_class_entry) { + with_error_handling(EH_THROW, php_http_exception_get_class_entry()) { if (SUCCESS == zend_parse_parameters_none()) { php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);