Skip to content

Commit 3771eec

Browse files
committed
ext/soap: Refactor SOAP call methods implementation
1 parent 5472ce3 commit 3771eec

File tree

1 file changed

+127
-95
lines changed

1 file changed

+127
-95
lines changed

ext/soap/soap.c

Lines changed: 127 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,14 +2217,13 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co
22172217

22182218
static void do_soap_call(zend_execute_data *execute_data,
22192219
zval* this_ptr,
2220-
char* function,
2221-
size_t function_len,
2220+
const zend_string *function,
22222221
uint32_t arg_count,
22232222
zval* real_args,
22242223
zval* return_value,
2225-
char* location,
2226-
char* soap_action,
2227-
char* call_uri,
2224+
const zend_string* location,
2225+
const zend_string* soap_action,
2226+
const zend_string* call_uri,
22282227
HashTable* soap_headers,
22292228
zval* output_headers
22302229
) /* {{{ */
@@ -2260,7 +2259,7 @@ static void do_soap_call(zend_execute_data *execute_data,
22602259
if (location == NULL) {
22612260
tmp = Z_CLIENT_LOCATION_P(this_ptr);
22622261
if (Z_TYPE_P(tmp) == IS_STRING) {
2263-
location = Z_STRVAL_P(tmp);
2262+
location = Z_STR_P(tmp);
22642263
}
22652264
}
22662265

@@ -2308,7 +2307,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23082307

23092308
zend_try {
23102309
if (sdl != NULL) {
2311-
fn = get_function(sdl, function);
2310+
fn = get_function(sdl, ZSTR_VAL(function));
23122311
if (fn != NULL) {
23132312
sdlBindingPtr binding = fn->binding;
23142313
bool one_way = 0;
@@ -2319,17 +2318,20 @@ static void do_soap_call(zend_execute_data *execute_data,
23192318
one_way = 1;
23202319
}
23212320

2321+
const char *location_c_str;
23222322
if (location == NULL) {
2323-
location = binding->location;
2324-
ZEND_ASSERT(location);
2323+
location_c_str = binding->location;
2324+
ZEND_ASSERT(location_c_str);
2325+
} else {
2326+
location_c_str = ZSTR_VAL(location);
23252327
}
23262328
if (binding->bindingType == BINDING_SOAP) {
23272329
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
23282330
request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers);
2329-
ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response);
2331+
ret = do_request(this_ptr, request, location_c_str, fnb->soapAction, soap_version, one_way, &response);
23302332
} else {
23312333
request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers);
2332-
ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response);
2334+
ret = do_request(this_ptr, request, location_c_str, NULL, soap_version, one_way, &response);
23332335
}
23342336

23352337
xmlFreeDoc(request);
@@ -2346,7 +2348,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23462348
} else {
23472349
smart_str error = {0};
23482350
smart_str_appends(&error,"Function (\"");
2349-
smart_str_appends(&error,function);
2351+
smart_str_append(&error,function);
23502352
smart_str_appends(&error,"\") is not a valid method for this service");
23512353
smart_str_0(&error);
23522354
add_soap_fault(this_ptr, "Client", ZSTR_VAL(error.s), NULL, NULL);
@@ -2360,28 +2362,28 @@ static void do_soap_call(zend_execute_data *execute_data,
23602362
add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL);
23612363
} else {
23622364
if (call_uri == NULL) {
2363-
call_uri = Z_STRVAL_P(uri);
2365+
call_uri = Z_STR_P(uri);
23642366
}
2365-
request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers);
2367+
request = serialize_function_call(this_ptr, NULL, ZSTR_VAL(function), ZSTR_VAL(call_uri), real_args, arg_count, soap_version, soap_headers);
23662368

23672369
if (soap_action == NULL) {
2368-
smart_str_appends(&action, call_uri);
2370+
smart_str_append(&action, call_uri);
23692371
smart_str_appendc(&action, '#');
2370-
smart_str_appends(&action, function);
2372+
smart_str_append(&action, function);
23712373
} else {
2372-
smart_str_appends(&action, soap_action);
2374+
smart_str_append(&action, soap_action);
23732375
}
23742376
smart_str_0(&action);
23752377

2376-
ret = do_request(this_ptr, request, location, ZSTR_VAL(action.s), soap_version, 0, &response);
2378+
ret = do_request(this_ptr, request, ZSTR_VAL(location), ZSTR_VAL(action.s), soap_version, 0, &response);
23772379

23782380
smart_str_free(&action);
23792381
xmlFreeDoc(request);
23802382
request = NULL;
23812383

23822384
if (ret && Z_TYPE(response) == IS_STRING) {
23832385
encode_reset_ns();
2384-
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers);
2386+
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers);
23852387
encode_finish();
23862388
}
23872389

@@ -2449,71 +2451,22 @@ static void verify_soap_headers_array(HashTable *ht) /* {{{ */
24492451
/* }}} */
24502452

24512453
/* {{{ Calls a SOAP function */
2452-
void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
2453-
{
2454-
char *function, *location=NULL, *soap_action = NULL, *uri = NULL;
2455-
size_t function_len;
2456-
int i = 0;
2457-
HashTable* soap_headers = NULL;
2458-
zval *options = NULL;
2459-
zval *headers = NULL;
2460-
zval *output_headers = NULL;
2461-
zval *args;
2462-
zval *real_args = NULL;
2463-
zval *param;
2464-
uint32_t arg_count;
2465-
zval *tmp;
2466-
bool free_soap_headers = 0;
2467-
zval *this_ptr;
2468-
2469-
if (is_soap_call) {
2470-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|a!zz",
2471-
&function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) {
2472-
RETURN_THROWS();
2473-
}
2474-
} else {
2475-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &function, &function_len, &args) == FAILURE) {
2476-
RETURN_THROWS();
2477-
}
2478-
}
2479-
2480-
if (options) {
2481-
HashTable *hto = Z_ARRVAL_P(options);
2482-
if ((tmp = zend_hash_str_find(hto, "location", sizeof("location")-1)) != NULL &&
2483-
Z_TYPE_P(tmp) == IS_STRING) {
2484-
location = Z_STRVAL_P(tmp);
2485-
}
2486-
2487-
if ((tmp = zend_hash_str_find(hto, "soapaction", sizeof("soapaction")-1)) != NULL &&
2488-
Z_TYPE_P(tmp) == IS_STRING) {
2489-
soap_action = Z_STRVAL_P(tmp);
2490-
}
2491-
2492-
if ((tmp = zend_hash_str_find(hto, "uri", sizeof("uri")-1)) != NULL &&
2493-
Z_TYPE_P(tmp) == IS_STRING) {
2494-
uri = Z_STRVAL_P(tmp);
2495-
}
2496-
}
2497-
2498-
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
2499-
} else if (Z_TYPE_P(headers) == IS_ARRAY) {
2500-
soap_headers = Z_ARRVAL_P(headers);
2501-
verify_soap_headers_array(soap_headers);
2502-
free_soap_headers = 0;
2503-
} else if (Z_TYPE_P(headers) == IS_OBJECT &&
2504-
instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
2505-
soap_headers = zend_new_array(0);
2506-
zend_hash_next_index_insert(soap_headers, headers);
2507-
Z_ADDREF_P(headers);
2508-
free_soap_headers = 1;
2509-
} else {
2510-
zend_argument_type_error(4, "must be of type SoapHeader|array|null, %s given", zend_zval_value_name(headers));
2511-
RETURN_THROWS();
2512-
}
2513-
2454+
static void soap_client_call_common(
2455+
zval *this_ptr,
2456+
const zend_string *function,
2457+
HashTable *args,
2458+
const zend_string *location,
2459+
const zend_string *soap_action,
2460+
const zend_string *uri,
2461+
HashTable* soap_headers,
2462+
bool free_soap_headers,
2463+
zval *output_headers,
2464+
zend_execute_data *execute_data,
2465+
zval *return_value
2466+
) {
25142467
/* Add default headers */
25152468
this_ptr = ZEND_THIS;
2516-
tmp = Z_CLIENT_DEFAULT_HEADERS_P(this_ptr);
2469+
zval *tmp = Z_CLIENT_DEFAULT_HEADERS_P(this_ptr);
25172470
if (Z_TYPE_P(tmp) == IS_ARRAY) {
25182471
HashTable *default_headers = Z_ARRVAL_P(tmp);
25192472
if (soap_headers) {
@@ -2533,27 +2486,23 @@ void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
25332486
}
25342487
}
25352488

2536-
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
2537-
2489+
uint32_t arg_count = zend_hash_num_elements(args);
2490+
zval *real_args = NULL;
25382491
if (arg_count > 0) {
2492+
zval *param;
2493+
int i = 0;
2494+
25392495
real_args = safe_emalloc(sizeof(zval), arg_count, 0);
2540-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), param) {
2496+
ZEND_HASH_FOREACH_VAL(args, param) {
25412497
/*zval_add_ref(param);*/
25422498
ZVAL_DEREF(param);
25432499
ZVAL_COPY_VALUE(&real_args[i], param);
25442500
i++;
25452501
} ZEND_HASH_FOREACH_END();
25462502
}
2547-
if (output_headers) {
2548-
output_headers = zend_try_array_init(output_headers);
2549-
if (!output_headers) {
2550-
goto cleanup;
2551-
}
2552-
}
25532503

2554-
do_soap_call(execute_data, this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
2504+
do_soap_call(execute_data, this_ptr, function, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
25552505

2556-
cleanup:
25572506
if (arg_count > 0) {
25582507
efree(real_args);
25592508
}
@@ -2566,12 +2515,95 @@ void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
25662515

25672516
PHP_METHOD(SoapClient, __call)
25682517
{
2569-
soap_client_call_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2518+
zend_string *function = NULL;
2519+
HashTable *args = NULL;
2520+
2521+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sh", &function, &args) == FAILURE) {
2522+
RETURN_THROWS();
2523+
}
2524+
soap_client_call_common(
2525+
ZEND_THIS,
2526+
function,
2527+
args,
2528+
/* location */ NULL,
2529+
/* soap_action */ NULL,
2530+
/* uri */ NULL,
2531+
/* soap_headers */ NULL,
2532+
/* free_soap_headers */ false,
2533+
/* output_headers */ NULL,
2534+
execute_data,
2535+
return_value
2536+
);
25702537
}
25712538

25722539
PHP_METHOD(SoapClient, __soapCall)
25732540
{
2574-
soap_client_call_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2541+
zend_string *function = NULL;
2542+
HashTable *args = NULL;
2543+
HashTable *options = NULL;
2544+
zval *headers = NULL;
2545+
zval *output_headers = NULL;
2546+
2547+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sh|h!zz", &function, &args, &options, &headers, &output_headers) == FAILURE) {
2548+
RETURN_THROWS();
2549+
}
2550+
2551+
2552+
zend_string *location = NULL;
2553+
zend_string *soap_action = NULL;
2554+
zend_string *uri = NULL;
2555+
if (options) {
2556+
zval *tmp;
2557+
if ((tmp = zend_hash_str_find(options, "location", sizeof("location")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2558+
location = Z_STR_P(tmp);
2559+
}
2560+
2561+
if ((tmp = zend_hash_str_find(options, "soapaction", sizeof("soapaction")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2562+
soap_action = Z_STR_P(tmp);
2563+
}
2564+
2565+
if ((tmp = zend_hash_str_find(options, "uri", sizeof("uri")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2566+
uri = Z_STR_P(tmp);
2567+
}
2568+
}
2569+
2570+
if (output_headers) {
2571+
output_headers = zend_try_array_init(output_headers);
2572+
if (output_headers == NULL) {
2573+
RETURN_THROWS();
2574+
}
2575+
}
2576+
2577+
HashTable* soap_headers = NULL;
2578+
bool free_soap_headers = false;
2579+
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
2580+
} else if (Z_TYPE_P(headers) == IS_ARRAY) {
2581+
soap_headers = Z_ARRVAL_P(headers);
2582+
verify_soap_headers_array(soap_headers);
2583+
free_soap_headers = false;
2584+
} else if (Z_TYPE_P(headers) == IS_OBJECT && instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
2585+
soap_headers = zend_new_array(0);
2586+
zend_hash_next_index_insert(soap_headers, headers);
2587+
Z_ADDREF_P(headers);
2588+
free_soap_headers = true;
2589+
} else {
2590+
zend_argument_type_error(4, "must be of type SoapHeader|array|null, %s given", zend_zval_value_name(headers));
2591+
RETURN_THROWS();
2592+
}
2593+
2594+
soap_client_call_common(
2595+
ZEND_THIS,
2596+
function,
2597+
args,
2598+
location,
2599+
soap_action,
2600+
uri,
2601+
soap_headers,
2602+
free_soap_headers,
2603+
output_headers,
2604+
execute_data,
2605+
return_value
2606+
);
25752607
}
25762608

25772609
/* {{{ Returns list of SOAP functions */

0 commit comments

Comments
 (0)