Skip to content

Commit b8cac1f

Browse files
committed
ext/soap: Refactor SOAP call methods implementation
1 parent 680e4b2 commit b8cac1f

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
@@ -2231,14 +2231,13 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co
22312231

22322232
static void do_soap_call(zend_execute_data *execute_data,
22332233
zval* this_ptr,
2234-
char* function,
2235-
size_t function_len,
2234+
const zend_string *function,
22362235
uint32_t arg_count,
22372236
zval* real_args,
22382237
zval* return_value,
2239-
char* location,
2240-
char* soap_action,
2241-
char* call_uri,
2238+
const zend_string* location,
2239+
const zend_string* soap_action,
2240+
const zend_string* call_uri,
22422241
HashTable* soap_headers,
22432242
zval* output_headers
22442243
) /* {{{ */
@@ -2274,7 +2273,7 @@ static void do_soap_call(zend_execute_data *execute_data,
22742273
if (location == NULL) {
22752274
tmp = Z_CLIENT_LOCATION_P(this_ptr);
22762275
if (Z_TYPE_P(tmp) == IS_STRING) {
2277-
location = Z_STRVAL_P(tmp);
2276+
location = Z_STR_P(tmp);
22782277
}
22792278
}
22802279

@@ -2322,7 +2321,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23222321

23232322
zend_try {
23242323
if (sdl != NULL) {
2325-
fn = get_function(sdl, function);
2324+
fn = get_function(sdl, ZSTR_VAL(function));
23262325
if (fn != NULL) {
23272326
sdlBindingPtr binding = fn->binding;
23282327
bool one_way = 0;
@@ -2333,17 +2332,20 @@ static void do_soap_call(zend_execute_data *execute_data,
23332332
one_way = 1;
23342333
}
23352334

2335+
const char *location_c_str;
23362336
if (location == NULL) {
2337-
location = binding->location;
2338-
ZEND_ASSERT(location);
2337+
location_c_str = binding->location;
2338+
ZEND_ASSERT(location_c_str);
2339+
} else {
2340+
location_c_str = ZSTR_VAL(location);
23392341
}
23402342
if (binding->bindingType == BINDING_SOAP) {
23412343
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
23422344
request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers);
2343-
ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response);
2345+
ret = do_request(this_ptr, request, location_c_str, fnb->soapAction, soap_version, one_way, &response);
23442346
} else {
23452347
request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers);
2346-
ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response);
2348+
ret = do_request(this_ptr, request, location_c_str, NULL, soap_version, one_way, &response);
23472349
}
23482350

23492351
xmlFreeDoc(request);
@@ -2360,7 +2362,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23602362
} else {
23612363
smart_str error = {0};
23622364
smart_str_appends(&error,"Function (\"");
2363-
smart_str_appends(&error,function);
2365+
smart_str_append(&error,function);
23642366
smart_str_appends(&error,"\") is not a valid method for this service");
23652367
smart_str_0(&error);
23662368
add_soap_fault(this_ptr, "Client", ZSTR_VAL(error.s), NULL, NULL);
@@ -2374,28 +2376,28 @@ static void do_soap_call(zend_execute_data *execute_data,
23742376
add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL);
23752377
} else {
23762378
if (call_uri == NULL) {
2377-
call_uri = Z_STRVAL_P(uri);
2379+
call_uri = Z_STR_P(uri);
23782380
}
2379-
request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers);
2381+
request = serialize_function_call(this_ptr, NULL, ZSTR_VAL(function), ZSTR_VAL(call_uri), real_args, arg_count, soap_version, soap_headers);
23802382

23812383
if (soap_action == NULL) {
2382-
smart_str_appends(&action, call_uri);
2384+
smart_str_append(&action, call_uri);
23832385
smart_str_appendc(&action, '#');
2384-
smart_str_appends(&action, function);
2386+
smart_str_append(&action, function);
23852387
} else {
2386-
smart_str_appends(&action, soap_action);
2388+
smart_str_append(&action, soap_action);
23872389
}
23882390
smart_str_0(&action);
23892391

2390-
ret = do_request(this_ptr, request, location, ZSTR_VAL(action.s), soap_version, 0, &response);
2392+
ret = do_request(this_ptr, request, ZSTR_VAL(location), ZSTR_VAL(action.s), soap_version, 0, &response);
23912393

23922394
smart_str_free(&action);
23932395
xmlFreeDoc(request);
23942396
request = NULL;
23952397

23962398
if (ret && Z_TYPE(response) == IS_STRING) {
23972399
encode_reset_ns();
2398-
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers);
2400+
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers);
23992401
encode_finish();
24002402
}
24012403

@@ -2463,71 +2465,22 @@ static void verify_soap_headers_array(HashTable *ht) /* {{{ */
24632465
/* }}} */
24642466

24652467
/* {{{ Calls a SOAP function */
2466-
void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
2467-
{
2468-
char *function, *location=NULL, *soap_action = NULL, *uri = NULL;
2469-
size_t function_len;
2470-
int i = 0;
2471-
HashTable* soap_headers = NULL;
2472-
zval *options = NULL;
2473-
zval *headers = NULL;
2474-
zval *output_headers = NULL;
2475-
zval *args;
2476-
zval *real_args = NULL;
2477-
zval *param;
2478-
uint32_t arg_count;
2479-
zval *tmp;
2480-
bool free_soap_headers = 0;
2481-
zval *this_ptr;
2482-
2483-
if (is_soap_call) {
2484-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|a!zz",
2485-
&function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) {
2486-
RETURN_THROWS();
2487-
}
2488-
} else {
2489-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &function, &function_len, &args) == FAILURE) {
2490-
RETURN_THROWS();
2491-
}
2492-
}
2493-
2494-
if (options) {
2495-
HashTable *hto = Z_ARRVAL_P(options);
2496-
if ((tmp = zend_hash_str_find(hto, "location", sizeof("location")-1)) != NULL &&
2497-
Z_TYPE_P(tmp) == IS_STRING) {
2498-
location = Z_STRVAL_P(tmp);
2499-
}
2500-
2501-
if ((tmp = zend_hash_str_find(hto, "soapaction", sizeof("soapaction")-1)) != NULL &&
2502-
Z_TYPE_P(tmp) == IS_STRING) {
2503-
soap_action = Z_STRVAL_P(tmp);
2504-
}
2505-
2506-
if ((tmp = zend_hash_str_find(hto, "uri", sizeof("uri")-1)) != NULL &&
2507-
Z_TYPE_P(tmp) == IS_STRING) {
2508-
uri = Z_STRVAL_P(tmp);
2509-
}
2510-
}
2511-
2512-
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
2513-
} else if (Z_TYPE_P(headers) == IS_ARRAY) {
2514-
soap_headers = Z_ARRVAL_P(headers);
2515-
verify_soap_headers_array(soap_headers);
2516-
free_soap_headers = 0;
2517-
} else if (Z_TYPE_P(headers) == IS_OBJECT &&
2518-
instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
2519-
soap_headers = zend_new_array(0);
2520-
zend_hash_next_index_insert(soap_headers, headers);
2521-
Z_ADDREF_P(headers);
2522-
free_soap_headers = 1;
2523-
} else {
2524-
zend_argument_type_error(4, "must be of type SoapHeader|array|null, %s given", zend_zval_value_name(headers));
2525-
RETURN_THROWS();
2526-
}
2527-
2468+
static void soap_client_call_common(
2469+
zval *this_ptr,
2470+
const zend_string *function,
2471+
HashTable *args,
2472+
const zend_string *location,
2473+
const zend_string *soap_action,
2474+
const zend_string *uri,
2475+
HashTable* soap_headers,
2476+
bool free_soap_headers,
2477+
zval *output_headers,
2478+
zend_execute_data *execute_data,
2479+
zval *return_value
2480+
) {
25282481
/* Add default headers */
25292482
this_ptr = ZEND_THIS;
2530-
tmp = Z_CLIENT_DEFAULT_HEADERS_P(this_ptr);
2483+
zval *tmp = Z_CLIENT_DEFAULT_HEADERS_P(this_ptr);
25312484
if (Z_TYPE_P(tmp) == IS_ARRAY) {
25322485
HashTable *default_headers = Z_ARRVAL_P(tmp);
25332486
if (soap_headers) {
@@ -2547,27 +2500,23 @@ void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
25472500
}
25482501
}
25492502

2550-
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
2551-
2503+
uint32_t arg_count = zend_hash_num_elements(args);
2504+
zval *real_args = NULL;
25522505
if (arg_count > 0) {
2506+
zval *param;
2507+
int i = 0;
2508+
25532509
real_args = safe_emalloc(sizeof(zval), arg_count, 0);
2554-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), param) {
2510+
ZEND_HASH_FOREACH_VAL(args, param) {
25552511
/*zval_add_ref(param);*/
25562512
ZVAL_DEREF(param);
25572513
ZVAL_COPY_VALUE(&real_args[i], param);
25582514
i++;
25592515
} ZEND_HASH_FOREACH_END();
25602516
}
2561-
if (output_headers) {
2562-
output_headers = zend_try_array_init(output_headers);
2563-
if (!output_headers) {
2564-
goto cleanup;
2565-
}
2566-
}
25672517

2568-
do_soap_call(execute_data, this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
2518+
do_soap_call(execute_data, this_ptr, function, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
25692519

2570-
cleanup:
25712520
if (arg_count > 0) {
25722521
efree(real_args);
25732522
}
@@ -2580,12 +2529,95 @@ void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
25802529

25812530
PHP_METHOD(SoapClient, __call)
25822531
{
2583-
soap_client_call_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2532+
zend_string *function = NULL;
2533+
HashTable *args = NULL;
2534+
2535+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sh", &function, &args) == FAILURE) {
2536+
RETURN_THROWS();
2537+
}
2538+
soap_client_call_common(
2539+
ZEND_THIS,
2540+
function,
2541+
args,
2542+
/* location */ NULL,
2543+
/* soap_action */ NULL,
2544+
/* uri */ NULL,
2545+
/* soap_headers */ NULL,
2546+
/* free_soap_headers */ false,
2547+
/* output_headers */ NULL,
2548+
execute_data,
2549+
return_value
2550+
);
25842551
}
25852552

25862553
PHP_METHOD(SoapClient, __soapCall)
25872554
{
2588-
soap_client_call_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2555+
zend_string *function = NULL;
2556+
HashTable *args = NULL;
2557+
HashTable *options = NULL;
2558+
zval *headers = NULL;
2559+
zval *output_headers = NULL;
2560+
2561+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sh|h!zz", &function, &args, &options, &headers, &output_headers) == FAILURE) {
2562+
RETURN_THROWS();
2563+
}
2564+
2565+
2566+
zend_string *location = NULL;
2567+
zend_string *soap_action = NULL;
2568+
zend_string *uri = NULL;
2569+
if (options) {
2570+
zval *tmp;
2571+
if ((tmp = zend_hash_str_find(options, "location", sizeof("location")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2572+
location = Z_STR_P(tmp);
2573+
}
2574+
2575+
if ((tmp = zend_hash_str_find(options, "soapaction", sizeof("soapaction")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2576+
soap_action = Z_STR_P(tmp);
2577+
}
2578+
2579+
if ((tmp = zend_hash_str_find(options, "uri", sizeof("uri")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
2580+
uri = Z_STR_P(tmp);
2581+
}
2582+
}
2583+
2584+
if (output_headers) {
2585+
output_headers = zend_try_array_init(output_headers);
2586+
if (output_headers == NULL) {
2587+
RETURN_THROWS();
2588+
}
2589+
}
2590+
2591+
HashTable* soap_headers = NULL;
2592+
bool free_soap_headers = false;
2593+
if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
2594+
} else if (Z_TYPE_P(headers) == IS_ARRAY) {
2595+
soap_headers = Z_ARRVAL_P(headers);
2596+
verify_soap_headers_array(soap_headers);
2597+
free_soap_headers = false;
2598+
} else if (Z_TYPE_P(headers) == IS_OBJECT && instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
2599+
soap_headers = zend_new_array(0);
2600+
zend_hash_next_index_insert(soap_headers, headers);
2601+
Z_ADDREF_P(headers);
2602+
free_soap_headers = true;
2603+
} else {
2604+
zend_argument_type_error(4, "must be of type SoapHeader|array|null, %s given", zend_zval_value_name(headers));
2605+
RETURN_THROWS();
2606+
}
2607+
2608+
soap_client_call_common(
2609+
ZEND_THIS,
2610+
function,
2611+
args,
2612+
location,
2613+
soap_action,
2614+
uri,
2615+
soap_headers,
2616+
free_soap_headers,
2617+
output_headers,
2618+
execute_data,
2619+
return_value
2620+
);
25892621
}
25902622

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

0 commit comments

Comments
 (0)