X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=php_http_client.c;h=9c4589b922de9ad3dedcf5869d17b9e0caefba92;hb=5c2aacdbafcaad2ddae8ce80db86b59bd00208ec;hp=5d77693fafd0b6196945ae94fa4c35b3011171f2;hpb=6cc24086f57aa1e8f4d6a2c12361635e7c24f60f;p=m6w6%2Fext-http diff --git a/php_http_client.c b/php_http_client.c index 5d77693..9c4589b 100644 --- a/php_http_client.c +++ b/php_http_client.c @@ -132,27 +132,22 @@ PHP_HTTP_API STATUS php_http_client_getopt(php_http_client_t *h, php_http_client #define PHP_HTTP_CLIENT_ALIAS(method, func) PHP_HTTP_STATIC_ME_ALIAS(method, func, PHP_HTTP_ARGS(HttpClient, method)) #define PHP_HTTP_CLIENT_MALIAS(me, al, vis) ZEND_FENTRY(me, ZEND_MN(HttpClient_##al), PHP_HTTP_ARGS(HttpClient, al), vis) +PHP_HTTP_BEGIN_ARGS(__construct, 0) + PHP_HTTP_ARG_ARR(options, 1, 0) +PHP_HTTP_END_ARGS; + PHP_HTTP_EMPTY_ARGS(getOptions); PHP_HTTP_BEGIN_ARGS(setOptions, 0) - PHP_HTTP_ARG_VAL(options, 0) + PHP_HTTP_ARG_ARR(options, 1, 0) PHP_HTTP_END_ARGS; PHP_HTTP_EMPTY_ARGS(getSslOptions); PHP_HTTP_BEGIN_ARGS(setSslOptions, 0) - PHP_HTTP_ARG_VAL(ssl_options, 0) + PHP_HTTP_ARG_ARR(ssl_options, 1, 0) PHP_HTTP_END_ARGS; PHP_HTTP_BEGIN_ARGS(addSslOptions, 0) - PHP_HTTP_ARG_VAL(ssl_optins, 0) -PHP_HTTP_END_ARGS; - -PHP_HTTP_EMPTY_ARGS(getHeaders); -PHP_HTTP_BEGIN_ARGS(setHeaders, 0) - PHP_HTTP_ARG_VAL(headers, 0) -PHP_HTTP_END_ARGS; - -PHP_HTTP_BEGIN_ARGS(addHeaders, 1) - PHP_HTTP_ARG_VAL(headers, 0) + PHP_HTTP_ARG_ARR(ssl_options, 1, 0) PHP_HTTP_END_ARGS; PHP_HTTP_EMPTY_ARGS(getCookies); @@ -170,8 +165,8 @@ PHP_HTTP_BEGIN_ARGS(resetCookies, 0) PHP_HTTP_END_ARGS; PHP_HTTP_EMPTY_ARGS(flushCookies); -PHP_HTTP_EMPTY_ARGS(getMessageClass); -PHP_HTTP_BEGIN_ARGS(setMessageClass, 1) +PHP_HTTP_EMPTY_ARGS(getResponseMessageClass); +PHP_HTTP_BEGIN_ARGS(setResponseMessageClass, 1) PHP_HTTP_ARG_VAL(message_class_name, 0) PHP_HTTP_END_ARGS; @@ -179,6 +174,12 @@ PHP_HTTP_EMPTY_ARGS(getResponseMessage); PHP_HTTP_EMPTY_ARGS(getRequestMessage); PHP_HTTP_EMPTY_ARGS(getHistory); PHP_HTTP_EMPTY_ARGS(clearHistory); + +PHP_HTTP_BEGIN_ARGS(setRequest, 1) + PHP_HTTP_ARG_OBJ(http\\Client\\Request, request, 1) +PHP_HTTP_END_ARGS; +PHP_HTTP_EMPTY_ARGS(getRequest); + PHP_HTTP_BEGIN_ARGS(send, 1) PHP_HTTP_ARG_VAL(request, 0) PHP_HTTP_END_ARGS; @@ -199,6 +200,7 @@ PHP_HTTP_END_ARGS; zend_class_entry *php_http_client_class_entry; zend_function_entry php_http_client_method_entry[] = { + PHP_HTTP_CLIENT_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_HTTP_CLIENT_ME(getObservers, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(notify, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(attach, ZEND_ACC_PUBLIC) @@ -220,6 +222,8 @@ zend_function_entry php_http_client_method_entry[] = { PHP_HTTP_CLIENT_ME(resetCookies, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(flushCookies, ZEND_ACC_PUBLIC) + PHP_HTTP_CLIENT_ME(setRequest, ZEND_ACC_PUBLIC) + PHP_HTTP_CLIENT_ME(getRequest, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(send, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(getResponseMessage, ZEND_ACC_PUBLIC) @@ -227,8 +231,8 @@ zend_function_entry php_http_client_method_entry[] = { PHP_HTTP_CLIENT_ME(getHistory, ZEND_ACC_PUBLIC) PHP_HTTP_CLIENT_ME(clearHistory, ZEND_ACC_PUBLIC) - PHP_HTTP_CLIENT_ME(getMessageClass, ZEND_ACC_PUBLIC) - PHP_HTTP_CLIENT_ME(setMessageClass, ZEND_ACC_PUBLIC) + PHP_HTTP_CLIENT_ME(getResponseMessageClass, ZEND_ACC_PUBLIC) + PHP_HTTP_CLIENT_ME(setResponseMessageClass, ZEND_ACC_PUBLIC) EMPTY_FUNCTION_ENTRY }; @@ -336,7 +340,7 @@ static inline void php_http_client_object_check_request_content_type(zval *this_ static inline zend_object_value php_http_client_object_message(zval *this_ptr, php_http_message_t *msg TSRMLS_DC) { zend_object_value ov; - zval *zcn = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("messageClass"), 0 TSRMLS_CC); + zval *zcn = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("responseMessageClass"), 0 TSRMLS_CC); zend_class_entry *class_entry; if (Z_STRLEN_P(zcn) @@ -348,12 +352,26 @@ static inline zend_object_value php_http_client_object_message(zval *this_ptr, p } } -STATUS php_http_client_object_handle_request(zval *zclient, zval *zreq TSRMLS_DC) +STATUS php_http_client_object_handle_request(zval *zclient, zval **zreq TSRMLS_DC) { php_http_client_object_t *obj = zend_object_store_get_object(zclient TSRMLS_CC); php_http_client_progress_t *progress; zval *zoptions; + /* do we have a valid request? */ + if (*zreq) { + /* remember the request */ + zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("request"), *zreq TSRMLS_CC); + } else { + /* maybe a request is already set */ + *zreq = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("request"), 0 TSRMLS_CC); + + if (Z_TYPE_PP(zreq) != IS_OBJECT || !instanceof_function(Z_OBJCE_PP(zreq), php_http_client_request_class_entry TSRMLS_CC)) { + php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, "The client does not have a valid request set"); + return FAILURE; + } + } + /* reset request handle */ php_http_client_reset(obj->client); @@ -513,7 +531,7 @@ STATUS php_http_client_object_handle_response(zval *zclient TSRMLS_DC) /* update the actual request message */ MAKE_STD_ZVAL(message); - ZVAL_OBJVAL(message, php_http_client_object_message(zclient, php_http_message_copy_ex(msg, NULL, 0) TSRMLS_CC), 0); + ZVAL_OBJVAL(message, php_http_message_object_new_ex(php_http_message_class_entry, php_http_message_copy_ex(msg, NULL, 0), NULL TSRMLS_CC), 0); zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("requestMessage"), message TSRMLS_CC); zval_ptr_dtor(&message); } @@ -614,6 +632,62 @@ static int apply_pretty_key(void *pDest TSRMLS_DC, int num_args, va_list args, z return ZEND_HASH_APPLY_KEEP; } +static void php_http_client_object_set_options(INTERNAL_FUNCTION_PARAMETERS) +{ + php_http_array_hashkey_t key = php_http_array_hashkey_init(0); + HashPosition pos; + zval *opts = NULL, *old_opts, *new_opts, *add_opts, **opt; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { + RETURN_FALSE; + } + + MAKE_STD_ZVAL(new_opts); + array_init(new_opts); + + if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) { + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); + zval_ptr_dtor(&new_opts); + } else { + MAKE_STD_ZVAL(add_opts); + array_init(add_opts); + /* some options need extra attention -- thus cannot use array_merge() directly */ + FOREACH_KEYVAL(pos, opts, key, opt) { + if (key.type == HASH_KEY_IS_STRING) { +#define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s)) + if (KEYMATCH(key, "ssl")) { + zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addssloptions", NULL, *opt); + } else if (KEYMATCH(key, "cookies")) { + zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addcookies", NULL, *opt); + } else if (KEYMATCH(key, "recordHistory")) { + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("recordHistory"), *opt TSRMLS_CC); + } else if (KEYMATCH(key, "responseMessageClass")) { + zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setmessageclass", NULL, *opt); + } else if (Z_TYPE_PP(opt) == IS_NULL) { + old_opts = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + if (Z_TYPE_P(old_opts) == IS_ARRAY) { + zend_symtable_del(Z_ARRVAL_P(old_opts), key.str, key.len); + } + } else { + Z_ADDREF_P(*opt); + add_assoc_zval_ex(add_opts, key.str, key.len, *opt); + } + } + } + + old_opts = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + if (Z_TYPE_P(old_opts) == IS_ARRAY) { + array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts)); + } + array_join(Z_ARRVAL_P(add_opts), Z_ARRVAL_P(new_opts), 0, 0); + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); + zval_ptr_dtor(&new_opts); + zval_ptr_dtor(&add_opts); + } + + RETVAL_ZVAL(getThis(), 1, 0); +} + static inline void php_http_client_object_set_options_subr(INTERNAL_FUNCTION_PARAMETERS, char *key, size_t len, int overwrite, int prettify_keys) { zval *old_opts, *new_opts, *opts = NULL, **entry = NULL; @@ -673,6 +747,19 @@ static inline void php_http_client_object_get_options_subr(INTERNAL_FUNCTION_PAR } } +PHP_METHOD(HttpClient, __construct) +{ + with_error_handling(EH_THROW, php_http_exception_class_entry) { + zval *os; + + MAKE_STD_ZVAL(os); + object_init_ex(os, spl_ce_SplObjectStorage); + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), os TSRMLS_CC); + zval_ptr_dtor(&os); + + php_http_client_object_set_options(INTERNAL_FUNCTION_PARAM_PASSTHRU); + } end_error_handling(); +} PHP_METHOD(HttpClient, getObservers) { @@ -796,58 +883,7 @@ PHP_METHOD(HttpClient, getTransferInfo) PHP_METHOD(HttpClient, setOptions) { - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - HashPosition pos; - zval *opts = NULL, *old_opts, *new_opts, *add_opts, **opt; - - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) { - RETURN_FALSE; - } - - MAKE_STD_ZVAL(new_opts); - array_init(new_opts); - - if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) { - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); - zval_ptr_dtor(&new_opts); - } else { - MAKE_STD_ZVAL(add_opts); - array_init(add_opts); - /* some options need extra attention -- thus cannot use array_merge() directly */ - FOREACH_KEYVAL(pos, opts, key, opt) { - if (key.type == HASH_KEY_IS_STRING) { -#define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s)) - if (KEYMATCH(key, "ssl")) { - zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addssloptions", NULL, *opt); - } else if (KEYMATCH(key, "cookies")) { - zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "addcookies", NULL, *opt); - } else if (KEYMATCH(key, "recordHistory")) { - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("recordHistory"), *opt TSRMLS_CC); - } else if (KEYMATCH(key, "messageClass")) { - zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "setmessageclass", NULL, *opt); - } else if (Z_TYPE_PP(opt) == IS_NULL) { - old_opts = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); - if (Z_TYPE_P(old_opts) == IS_ARRAY) { - zend_symtable_del(Z_ARRVAL_P(old_opts), key.str, key.len); - } - } else { - Z_ADDREF_P(*opt); - add_assoc_zval_ex(add_opts, key.str, key.len, *opt); - } - } - } - - old_opts = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); - if (Z_TYPE_P(old_opts) == IS_ARRAY) { - array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts)); - } - array_join(Z_ARRVAL_P(add_opts), Z_ARRVAL_P(new_opts), 0, 0); - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); - zval_ptr_dtor(&new_opts); - zval_ptr_dtor(&add_opts); - } - - RETVAL_ZVAL(getThis(), 1, 0); + php_http_client_object_set_options(INTERNAL_FUNCTION_PARAM_PASSTHRU); } PHP_METHOD(HttpClient, getOptions) @@ -976,38 +1012,54 @@ PHP_METHOD(HttpClient, clearHistory) RETVAL_ZVAL(getThis(), 1, 0); } -PHP_METHOD(HttpClient, getMessageClass) +PHP_METHOD(HttpClient, getResponseMessageClass) { if (SUCCESS == zend_parse_parameters_none()) { - RETURN_PROP(php_http_client_class_entry, "messageClass"); + RETURN_PROP(php_http_client_class_entry, "responseMessageClass"); } RETURN_FALSE; } -PHP_METHOD(HttpClient, setMessageClass) +PHP_METHOD(HttpClient, setResponseMessageClass) { char *cn; int cl; if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cn, &cl)) { - zend_update_property_stringl(php_http_client_class_entry, getThis(), ZEND_STRL("messageClass"), cn, cl TSRMLS_CC); + zend_update_property_stringl(php_http_client_class_entry, getThis(), ZEND_STRL("responseMessageClass"), cn, cl TSRMLS_CC); } RETVAL_ZVAL(getThis(), 1, 0); } +PHP_METHOD(HttpClient, setRequest) +{ + zval *zreq = NULL; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zreq, php_http_client_request_class_entry)) { + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("request"), zreq TSRMLS_CC); + } + RETURN_ZVAL(getThis(), 1, 0); +} + +PHP_METHOD(HttpClient, getRequest) +{ + if (SUCCESS == zend_parse_parameters_none()) { + RETURN_PROP(php_http_client_class_entry, "request"); + } +} + PHP_METHOD(HttpClient, send) { - zval *zreq; + zval *zreq = NULL; RETVAL_FALSE; with_error_handling(EH_THROW, php_http_exception_class_entry) { - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zreq, php_http_client_request_class_entry)) { - if (SUCCESS == php_http_client_object_handle_request(getThis(), zreq TSRMLS_CC)) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!", &zreq, php_http_client_request_class_entry)) { + if (SUCCESS == php_http_client_object_handle_request(getThis(), &zreq TSRMLS_CC)) { php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); php_http_message_object_t *req = zend_object_store_get_object(zreq TSRMLS_CC); - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("request"), zreq TSRMLS_CC); php_http_client_exec(obj->client, req->message); if (SUCCESS == php_http_client_object_handle_response(getThis() TSRMLS_CC)) { @@ -1031,7 +1083,7 @@ PHP_MINIT_FUNCTION(http_client) zend_class_implements(php_http_client_class_entry TSRMLS_CC, 2, spl_ce_SplSubject, php_http_client_interface_class_entry); - zend_declare_property_string(php_http_client_class_entry, ZEND_STRL("messageClass"), "", ZEND_ACC_PRIVATE TSRMLS_CC); + zend_declare_property_string(php_http_client_class_entry, ZEND_STRL("responseMessageClass"), "", ZEND_ACC_PRIVATE TSRMLS_CC); zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("observers"), ZEND_ACC_PRIVATE TSRMLS_CC); zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("options"), ZEND_ACC_PRIVATE TSRMLS_CC); zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("transferInfo"), ZEND_ACC_PRIVATE TSRMLS_CC);