Skip to content

Commit cf1b4cf

Browse files
committed
Introduce SoapClient::__setSoapHeaders()
1 parent e8b0573 commit cf1b4cf

File tree

1 file changed

+96
-17
lines changed

1 file changed

+96
-17
lines changed

ext/soap/soap.c

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ PHP_METHOD(SoapClient, __getTypes);
260260
PHP_METHOD(SoapClient, __doRequest);
261261
PHP_METHOD(SoapClient, __setCookie);
262262
PHP_METHOD(SoapClient, __setLocation);
263+
PHP_METHOD(SoapClient, __setSoapHeaders);
263264

264265
/* SoapVar Functions */
265266
PHP_METHOD(SoapVar, SoapVar);
@@ -348,6 +349,7 @@ static zend_function_entry soap_client_functions[] = {
348349
PHP_ME(SoapClient, __doRequest, NULL, 0)
349350
PHP_ME(SoapClient, __setCookie, NULL, 0)
350351
PHP_ME(SoapClient, __setLocation, NULL, 0)
352+
PHP_ME(SoapClient, __setSoapHeaders, NULL, 0)
351353
{NULL, NULL, NULL}
352354
};
353355

@@ -2457,6 +2459,20 @@ static void do_soap_call(zval* this_ptr,
24572459
SOAP_CLIENT_END_CODE();
24582460
}
24592461

2462+
static void verify_soap_headers_array(HashTable *ht)
2463+
{
2464+
zval **tmp;
2465+
2466+
zend_hash_internal_pointer_reset(ht);
2467+
while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
2468+
if (Z_TYPE_PP(tmp) != IS_OBJECT ||
2469+
Z_OBJCE_PP(tmp) != soap_header_class_entry) {
2470+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
2471+
}
2472+
zend_hash_move_forward(ht);
2473+
}
2474+
}
2475+
24602476

24612477
/* {{{ proto mixed SoapClient::__call ( string function_name [, array arguments [, array options [, array input_headers [, array output_headers]]]])
24622478
Calls a SOAP function */
@@ -2472,6 +2488,8 @@ PHP_METHOD(SoapClient, __call)
24722488
zval **real_args = NULL;
24732489
zval **param;
24742490
int arg_count;
2491+
zval **tmp;
2492+
zend_bool free_soap_headers;
24752493

24762494
HashPosition pos;
24772495

@@ -2483,8 +2501,6 @@ PHP_METHOD(SoapClient, __call)
24832501
if (options) {
24842502
if (Z_TYPE_P(options) == IS_ARRAY) {
24852503
HashTable *ht = Z_ARRVAL_P(options);
2486-
zval **tmp;
2487-
24882504
if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
24892505
Z_TYPE_PP(tmp) == IS_STRING) {
24902506
location = Z_STRVAL_PP(tmp);
@@ -2506,27 +2522,43 @@ PHP_METHOD(SoapClient, __call)
25062522

25072523
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
25082524
} else if (Z_TYPE_P(headers) == IS_ARRAY) {
2509-
zval** tmp;
2510-
25112525
soap_headers = Z_ARRVAL_P(headers);
2512-
zend_hash_internal_pointer_reset(soap_headers);
2513-
while (zend_hash_get_current_data(soap_headers, (void**)&tmp) == SUCCESS) {
2514-
if (Z_TYPE_PP(tmp) != IS_OBJECT ||
2515-
Z_OBJCE_PP(tmp) != soap_header_class_entry) {
2516-
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
2517-
}
2518-
zend_hash_move_forward(soap_headers);
2519-
}
2526+
verify_soap_headers_array(soap_headers);
2527+
free_soap_headers = 0;
25202528
} else if (Z_TYPE_P(headers) == IS_OBJECT &&
25212529
Z_OBJCE_P(headers) == soap_header_class_entry) {
2522-
soap_headers = emalloc(sizeof(HashTable));
2523-
zend_hash_init(soap_headers, 0, NULL, NULL/*ZVAL_PTR_DTOR*/, 0);
2530+
soap_headers = emalloc(sizeof(HashTable));
2531+
zend_hash_init(soap_headers, 0, NULL, ZVAL_PTR_DTOR, 0);
25242532
zend_hash_next_index_insert(soap_headers, &headers, sizeof(zval*), NULL);
2525-
headers = NULL;
2533+
ZVAL_ADDREF(headers);
2534+
free_soap_headers = 1;
25262535
} else{
25272536
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
25282537
}
25292538

2539+
/* Add default headers */
2540+
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &tmp)==SUCCESS) {
2541+
HashTable *default_headers = Z_ARRVAL_P(*tmp);
2542+
if (soap_headers) {
2543+
if (!free_soap_headers) {
2544+
HashTable *tmp = emalloc(sizeof(HashTable));
2545+
zend_hash_init(tmp, 0, NULL, ZVAL_PTR_DTOR, 0);
2546+
zend_hash_copy(tmp, soap_headers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
2547+
soap_headers = tmp;
2548+
free_soap_headers = 1;
2549+
}
2550+
zend_hash_internal_pointer_reset(default_headers);
2551+
while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) {
2552+
ZVAL_ADDREF(*tmp);
2553+
zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
2554+
zend_hash_move_forward(default_headers);
2555+
}
2556+
} else {
2557+
soap_headers = Z_ARRVAL_P(*tmp);
2558+
free_soap_headers = 0;
2559+
}
2560+
}
2561+
25302562
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
25312563

25322564
if (arg_count > 0) {
@@ -2546,7 +2578,7 @@ PHP_METHOD(SoapClient, __call)
25462578
efree(real_args);
25472579
}
25482580

2549-
if (soap_headers && ! headers) {
2581+
if (soap_headers && free_soap_headers) {
25502582
zend_hash_destroy(soap_headers);
25512583
efree(soap_headers);
25522584
}
@@ -2728,6 +2760,44 @@ PHP_METHOD(SoapClient, __setCookie)
27282760
}
27292761
/* }}} */
27302762

2763+
/* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders)
2764+
Sets SOAP headers for subsequent calls (replaces any previous
2765+
values).
2766+
If no value is specified, all of the headers are removed. */
2767+
PHP_METHOD(SoapClient, __setSoapHeaders)
2768+
{
2769+
zval *headers;
2770+
2771+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &headers) == FAILURE) {
2772+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
2773+
RETURN_NULL();
2774+
}
2775+
2776+
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
2777+
zend_hash_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"));
2778+
} else if (Z_TYPE_P(headers) == IS_ARRAY || Z_TYPE_P(headers) == IS_OBJECT) {
2779+
zval *default_headers;
2780+
2781+
verify_soap_headers_array(Z_ARRVAL_P(headers));
2782+
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &default_headers)==FAILURE) {
2783+
add_property_zval(this_ptr, "__default_headers", headers);
2784+
}
2785+
} else if (Z_TYPE_P(headers) == IS_OBJECT &&
2786+
Z_OBJCE_P(headers) == soap_header_class_entry) {
2787+
zval *default_headers;
2788+
ALLOC_INIT_ZVAL(default_headers);
2789+
array_init(default_headers);
2790+
add_next_index_zval(default_headers, headers);
2791+
add_property_zval(this_ptr, "__default_headers", default_headers);
2792+
} else{
2793+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
2794+
}
2795+
RETURN_TRUE;
2796+
}
2797+
/* }}} */
2798+
2799+
2800+
27312801
/* {{{ proto string SoapClient::__setLocation([string new_location])
27322802
Sets the location option (the endpoint URL that will be touched by the
27332803
following SOAP requests).
@@ -2776,9 +2846,18 @@ static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper
27762846
} else {
27772847
int arg_count = ZEND_NUM_ARGS();
27782848
zval **arguments = (zval **) safe_emalloc(sizeof(zval *), arg_count, 0);
2849+
zval **soap_headers_p
2850+
HashTable *soap_headers;
27792851

27802852
zend_get_parameters_array(ht, arg_count, arguments);
2781-
do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value, NULL, NULL, NULL, NULL, NULL TSRMLS_CC);
2853+
2854+
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_properties"), (void **) soap_headers_p)==SUCCESS
2855+
&& Z_TYPE_P(soap_headers_p)==IS_ARRAY) {
2856+
soap_headers = Z_ARRVAL_P(soap_headers_p);
2857+
} else {
2858+
soap_headers = NULL;
2859+
}
2860+
do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value, NULL, NULL, NULL, soap_headers, NULL TSRMLS_CC);
27822861
efree(arguments);
27832862
}
27842863
zval_dtor(&function_name->element);

0 commit comments

Comments
 (0)