From 78481a961e262e97e1592ff997e384031b6f6d2c Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 12 Apr 2012 14:10:25 +0000 Subject: [PATCH] add http\Client\AbstractClient#request(string method, string url[, array headers=null[, mixed body=null[, array options=null]]]) --- php_http_client.c | 49 ++++++++++++++++++++++++++++++++ php_http_client.h | 1 + php_http_message.c | 70 ++++++++++++++++++++++++++++++++++++++-------- php_http_message.h | 1 + 4 files changed, 109 insertions(+), 12 deletions(-) diff --git a/php_http_client.c b/php_http_client.c index 6f1c5fa..47c7ef4 100644 --- a/php_http_client.c +++ b/php_http_client.c @@ -197,6 +197,13 @@ PHP_HTTP_BEGIN_ARGS(getTransferInfo, 0) PHP_HTTP_ARG_VAL(name, 0) PHP_HTTP_END_ARGS; +PHP_HTTP_BEGIN_ARGS(request, 2) + PHP_HTTP_ARG_VAL(method, 0) + PHP_HTTP_ARG_VAL(url, 0) + PHP_HTTP_ARG_ARR(headers, 1, 0) + PHP_HTTP_ARG_VAL(body, 0) + PHP_HTTP_ARG_ARR(options, 1, 0) +PHP_HTTP_END_ARGS; static zend_class_entry *php_http_client_class_entry; @@ -239,6 +246,8 @@ static zend_function_entry php_http_client_method_entry[] = { PHP_HTTP_CLIENT_ME(getResponseMessageClass, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(setResponseMessageClass, ZEND_ACC_PUBLIC) + PHP_HTTP_CLIENT_ME(request, ZEND_ACC_PUBLIC) + EMPTY_FUNCTION_ENTRY }; @@ -889,6 +898,46 @@ PHP_METHOD(HttpClient, getRequest) } } +PHP_METHOD(HttpClient, request) +{ + char *meth_str, *url_str; + int meth_len, url_len; + zval *zheader, *zbody, *zoptions; + + with_error_handling(EH_THROW, php_http_exception_get_class_entry()) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a!z!a!/", &meth_str, &meth_len, &url_str, &url_len, &zheader, &zbody, &zoptions)) { + php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_message_object_t *msg_obj; + zend_object_value ov; + zval *req, *res = NULL; + + php_http_new(&ov, php_http_client_request_get_class_entry(), (php_http_new_t) php_http_message_object_new_ex, NULL, NULL, (void *) &msg_obj TSRMLS_CC); + MAKE_STD_ZVAL(req); + ZVAL_OBJVAL(req, ov, 0); + + msg_obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST TSRMLS_CC); + PHP_HTTP_INFO(msg_obj->message).request.url = estrndup(url_str, url_len); + PHP_HTTP_INFO(msg_obj->message).request.method = estrndup(meth_str, meth_len); + + if (zheader) { + array_copy(Z_ARRVAL_P(zheader), &msg_obj->message->hdrs); + } + + if (zbody) { + php_http_message_object_set_body(msg_obj, zbody TSRMLS_CC); + } + + if (zoptions) { + php_http_client_options_set(req, zoptions TSRMLS_CC); + } + + zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "send", &res, req); + RETVAL_ZVAL(res, 0, 1); + zval_ptr_dtor(&req); + } + } end_error_handling(); +} + PHP_METHOD(HttpClient, send) { zval *zreq = NULL; diff --git a/php_http_client.h b/php_http_client.h index b5aeb57..93a910c 100644 --- a/php_http_client.h +++ b/php_http_client.h @@ -202,6 +202,7 @@ PHP_METHOD(HttpClient, flushCookies); PHP_METHOD(HttpClient, setRequest); PHP_METHOD(HttpClient, getRequest); PHP_METHOD(HttpClient, send); +PHP_METHOD(HttpClient, request); PHP_METHOD(HttpClient, getResponseMessage); PHP_METHOD(HttpClient, getRequestMessage); PHP_METHOD(HttpClient, getHistory); diff --git a/php_http_message.c b/php_http_message.c index f8b3a4d..f1169d0 100644 --- a/php_http_message.c +++ b/php_http_message.c @@ -823,13 +823,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_get_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) { @@ -982,6 +976,62 @@ 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; + 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_message_body_object_new_ex, NULL, body, NULL TSRMLS_CC)) { + php_http_message_body_free(&body); + return FAILURE; + } + MAKE_STD_ZVAL(zbody); + ZVAL_OBJVAL(zbody, ov, 0); + 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); + 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); + + 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); @@ -1257,11 +1307,7 @@ PHP_METHOD(HttpMessage, setBody) if (!obj->message) { obj->message = php_http_message_init(NULL, 0 TSRMLS_CC); } - - 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); + php_http_message_object_prophandler_set_body(obj, zbody TSRMLS_CC); } RETVAL_ZVAL(getThis(), 1, 0); } diff --git a/php_http_message.h b/php_http_message.h index cd2615e..8ebcecf 100644 --- a/php_http_message.h +++ b/php_http_message.h @@ -84,6 +84,7 @@ PHP_MSHUTDOWN_FUNCTION(http_message); void php_http_message_object_prepend(zval *this_ptr, zval *prepend, zend_bool top /* = 1 */ TSRMLS_DC); void php_http_message_object_reverse(zval *this_ptr, zval *return_value TSRMLS_DC); +STATUS php_http_message_object_set_body(php_http_message_object_t *obj, zval *zbody TSRMLS_DC); 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); -- 2.30.2