Skip to content

Commit b219c1a

Browse files
committed
ext/soap: Refactor SOAP call methods implementation
1 parent d7bcfcb commit b219c1a

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

22222222
static void do_soap_call(zend_execute_data *execute_data,
22232223
zval* this_ptr,
2224-
char* function,
2225-
size_t function_len,
2224+
const zend_string *function,
22262225
uint32_t arg_count,
22272226
zval* real_args,
22282227
zval* return_value,
2229-
char* location,
2230-
char* soap_action,
2231-
char* call_uri,
2228+
const zend_string* location,
2229+
const zend_string* soap_action,
2230+
const zend_string* call_uri,
22322231
HashTable* soap_headers,
22332232
zval* output_headers
22342233
) /* {{{ */
@@ -2264,7 +2263,7 @@ static void do_soap_call(zend_execute_data *execute_data,
22642263
if (location == NULL) {
22652264
tmp = Z_CLIENT_LOCATION_P(this_ptr);
22662265
if (Z_TYPE_P(tmp) == IS_STRING) {
2267-
location = Z_STRVAL_P(tmp);
2266+
location = Z_STR_P(tmp);
22682267
}
22692268
}
22702269

@@ -2312,7 +2311,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23122311

23132312
zend_try {
23142313
if (sdl != NULL) {
2315-
fn = get_function(sdl, function);
2314+
fn = get_function(sdl, ZSTR_VAL(function));
23162315
if (fn != NULL) {
23172316
sdlBindingPtr binding = fn->binding;
23182317
bool one_way = 0;
@@ -2323,17 +2322,20 @@ static void do_soap_call(zend_execute_data *execute_data,
23232322
one_way = 1;
23242323
}
23252324

2325+
const char *location_c_str;
23262326
if (location == NULL) {
2327-
location = binding->location;
2328-
ZEND_ASSERT(location);
2327+
location_c_str = binding->location;
2328+
ZEND_ASSERT(location_c_str);
2329+
} else {
2330+
location_c_str = ZSTR_VAL(location);
23292331
}
23302332
if (binding->bindingType == BINDING_SOAP) {
23312333
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
23322334
request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers);
2333-
ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response);
2335+
ret = do_request(this_ptr, request, location_c_str, fnb->soapAction, soap_version, one_way, &response);
23342336
} else {
23352337
request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers);
2336-
ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response);
2338+
ret = do_request(this_ptr, request, location_c_str, NULL, soap_version, one_way, &response);
23372339
}
23382340

23392341
xmlFreeDoc(request);
@@ -2350,7 +2352,7 @@ static void do_soap_call(zend_execute_data *execute_data,
23502352
} else {
23512353
smart_str error = {0};
23522354
smart_str_appends(&error,"Function (\"");
2353-
smart_str_appends(&error,function);
2355+
smart_str_append(&error,function);
23542356
smart_str_appends(&error,"\") is not a valid method for this service");
23552357
smart_str_0(&error);
23562358
add_soap_fault(this_ptr, "Client", ZSTR_VAL(error.s), NULL, NULL);
@@ -2364,28 +2366,28 @@ static void do_soap_call(zend_execute_data *execute_data,
23642366
add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL);
23652367
} else {
23662368
if (call_uri == NULL) {
2367-
call_uri = Z_STRVAL_P(uri);
2369+
call_uri = Z_STR_P(uri);
23682370
}
2369-
request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers);
2371+
request = serialize_function_call(this_ptr, NULL, ZSTR_VAL(function), ZSTR_VAL(call_uri), real_args, arg_count, soap_version, soap_headers);
23702372

23712373
if (soap_action == NULL) {
2372-
smart_str_appends(&action, call_uri);
2374+
smart_str_append(&action, call_uri);
23732375
smart_str_appendc(&action, '#');
2374-
smart_str_appends(&action, function);
2376+
smart_str_append(&action, function);
23752377
} else {
2376-
smart_str_appends(&action, soap_action);
2378+
smart_str_append(&action, soap_action);
23772379
}
23782380
smart_str_0(&action);
23792381

2380-
ret = do_request(this_ptr, request, location, ZSTR_VAL(action.s), soap_version, 0, &response);
2382+
ret = do_request(this_ptr, request, ZSTR_VAL(location), ZSTR_VAL(action.s), soap_version, 0, &response);
23812383

23822384
smart_str_free(&action);
23832385
xmlFreeDoc(request);
23842386
request = NULL;
23852387

23862388
if (ret && Z_TYPE(response) == IS_STRING) {
23872389
encode_reset_ns();
2388-
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers);
2390+
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers);
23892391
encode_finish();
23902392
}
23912393

@@ -2453,71 +2455,22 @@ static void verify_soap_headers_array(HashTable *ht) /* {{{ */
24532455
/* }}} */
24542456

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

2540-
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
2541-
2493+
uint32_t arg_count = zend_hash_num_elements(args);
2494+
zval *real_args = NULL;
25422495
if (arg_count > 0) {
2496+
zval *param;
2497+
int i = 0;
2498+
25432499
real_args = safe_emalloc(sizeof(zval), arg_count, 0);
2544-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), param) {
2500+
ZEND_HASH_FOREACH_VAL(args, param) {
25452501
/*zval_add_ref(param);*/
25462502
ZVAL_DEREF(param);
25472503
ZVAL_COPY_VALUE(&real_args[i], param);
25482504
i++;
25492505
} ZEND_HASH_FOREACH_END();
25502506
}
2551-
if (output_headers) {
2552-
output_headers = zend_try_array_init(output_headers);
2553-
if (!output_headers) {
2554-
goto cleanup;
2555-
}
2556-
}
25572507

2558-
do_soap_call(execute_data, this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
2508+
do_soap_call(execute_data, this_ptr, function, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
25592509

2560-
cleanup:
25612510
if (arg_count > 0) {
25622511
efree(real_args);
25632512
}
@@ -2570,12 +2519,95 @@ void soap_client_call_impl(INTERNAL_FUNCTION_PARAMETERS, bool is_soap_call)
25702519

25712520
PHP_METHOD(SoapClient, __call)
25722521
{
2573-
soap_client_call_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2522+
zend_string *function = NULL;
2523+
HashTable *args = NULL;
2524+
2525+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sh", &function, &args) == FAILURE) {
2526+
RETURN_THROWS();
2527+
}
2528+
soap_client_call_common(
2529+
ZEND_THIS,
2530+
function,
2531+
args,
2532+
/* location */ NULL,
2533+
/* soap_action */ NULL,
2534+
/* uri */ NULL,
2535+
/* soap_headers */ NULL,
2536+
/* free_soap_headers */ false,
2537+
/* output_headers */ NULL,
2538+
execute_data,
2539+
return_value
2540+
);
25742541
}
25752542

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

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

0 commit comments

Comments
 (0)