@@ -58,7 +58,7 @@ static sdlParamPtr get_param(sdlFunctionPtr function, const char *param_name, ze
58
58
static sdlFunctionPtr get_function (sdlPtr sdl , const char * function_name , size_t function_name_length );
59
59
static sdlFunctionPtr get_doc_function (sdlPtr sdl , xmlNodePtr params );
60
60
61
- static sdlFunctionPtr deserialize_function_call (sdlPtr sdl , xmlDocPtr request , const char * actor , zval * function_name , uint32_t * num_params , zval * * parameters , int * version , soapHeader * * headers );
61
+ static sdlFunctionPtr deserialize_function_call (sdlPtr sdl , xmlDocPtr request , const char * actor , const char * soap_action , zval * function_name , uint32_t * num_params , zval * * parameters , int * version , soapHeader * * headers );
62
62
static xmlDocPtr serialize_response_call (sdlFunctionPtr function , const char * function_name , const char * uri ,zval * ret , soapHeader * headers , int version );
63
63
static xmlDocPtr serialize_function_call (zval * this_ptr , sdlFunctionPtr function , const char * function_name , const char * uri , zval * arguments , uint32_t arg_count , int version , HashTable * soap_headers );
64
64
static xmlNodePtr serialize_parameter (sdlParamPtr param ,zval * param_val , uint32_t index ,const char * name , int style , xmlNodePtr parent );
@@ -1273,6 +1273,7 @@ PHP_METHOD(SoapServer, handle)
1273
1273
HashTable * old_class_map , * old_typemap ;
1274
1274
int old_features ;
1275
1275
zval tmp_soap ;
1276
+ const char * soap_action = NULL ;
1276
1277
1277
1278
if (zend_parse_parameters (ZEND_NUM_ARGS (), "|s!" , & arg , & arg_len ) == FAILURE ) {
1278
1279
RETURN_THROWS ();
@@ -1341,7 +1342,7 @@ PHP_METHOD(SoapServer, handle)
1341
1342
1342
1343
if (!arg ) {
1343
1344
if (SG (request_info ).request_body && 0 == php_stream_rewind (SG (request_info ).request_body )) {
1344
- zval * server_vars , * encoding ;
1345
+ zval * server_vars , * encoding , * soap_action_z ;
1345
1346
php_stream_filter * zf = NULL ;
1346
1347
zend_string * server = ZSTR_KNOWN (ZEND_STR_AUTOGLOBAL_SERVER );
1347
1348
@@ -1375,6 +1376,10 @@ PHP_METHOD(SoapServer, handle)
1375
1376
}
1376
1377
}
1377
1378
1379
+ if ((soap_action_z = zend_hash_str_find (Z_ARRVAL_P (server_vars ), ZEND_STRL ("HTTP_SOAPACTION" ))) != NULL && Z_TYPE_P (soap_action_z ) == IS_STRING ) {
1380
+ soap_action = Z_STRVAL_P (soap_action_z );
1381
+ }
1382
+
1378
1383
doc_request = soap_xmlParseFile ("php://input" );
1379
1384
1380
1385
if (zf ) {
@@ -1418,7 +1423,7 @@ PHP_METHOD(SoapServer, handle)
1418
1423
old_soap_version = SOAP_GLOBAL (soap_version );
1419
1424
1420
1425
zend_try {
1421
- function = deserialize_function_call (service -> sdl , doc_request , service -> actor , & function_name , & num_params , & params , & soap_version , & soap_headers );
1426
+ function = deserialize_function_call (service -> sdl , doc_request , service -> actor , soap_action , & function_name , & num_params , & params , & soap_version , & soap_headers );
1422
1427
} zend_catch {
1423
1428
/* Avoid leaking persistent memory */
1424
1429
xmlFreeDoc (doc_request );
@@ -3090,6 +3095,37 @@ static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_
3090
3095
}
3091
3096
/* }}} */
3092
3097
3098
+ static sdlFunctionPtr find_function_using_soap_action (const sdl * sdl , const char * soap_action , zval * function_name )
3099
+ {
3100
+ if (!sdl ) {
3101
+ return NULL ;
3102
+ }
3103
+
3104
+ /* The soap action may be a http-quoted string, in which case we're removing the quotes here. */
3105
+ size_t soap_action_length = strlen (soap_action );
3106
+ if (soap_action [0 ] == '"' ) {
3107
+ if (soap_action_length < 2 || soap_action [soap_action_length - 1 ] != '"' ) {
3108
+ return NULL ;
3109
+ }
3110
+ soap_action ++ ;
3111
+ soap_action_length -= 2 ;
3112
+ }
3113
+
3114
+ /* TODO: This may depend on a particular target namespace, in which case this won't find a match when multiple different
3115
+ * target namespaces are used until #45282 is resolved. */
3116
+ sdlFunctionPtr function ;
3117
+ ZEND_HASH_FOREACH_PTR (& sdl -> functions , function ) {
3118
+ if (function -> binding && function -> binding -> bindingType == BINDING_SOAP ) {
3119
+ sdlSoapBindingFunctionPtr fnb = function -> bindingAttributes ;
3120
+ if (fnb && fnb -> soapAction && strncmp (fnb -> soapAction , soap_action , soap_action_length ) == 0 && fnb -> soapAction [soap_action_length ] == '\0' ) {
3121
+ ZVAL_STRING (function_name , function -> functionName );
3122
+ return function ;
3123
+ }
3124
+ }
3125
+ } ZEND_HASH_FOREACH_END ();
3126
+ return NULL ;
3127
+ }
3128
+
3093
3129
static xmlNodePtr get_envelope (xmlNodePtr trav , int * version , char * * envelope_ns ) {
3094
3130
while (trav != NULL ) {
3095
3131
if (trav -> type == XML_ELEMENT_NODE ) {
@@ -3115,12 +3151,12 @@ static xmlNodePtr get_envelope(xmlNodePtr trav, int *version, char **envelope_ns
3115
3151
return NULL ;
3116
3152
}
3117
3153
3118
- static sdlFunctionPtr deserialize_function_call (sdlPtr sdl , xmlDocPtr request , const char * actor , zval * function_name , uint32_t * num_params , zval * * parameters , int * version , soapHeader * * headers ) /* {{{ */
3154
+ static sdlFunctionPtr deserialize_function_call (sdlPtr sdl , xmlDocPtr request , const char * actor , const char * soap_action , zval * function_name , uint32_t * num_params , zval * * parameters , int * version , soapHeader * * headers ) /* {{{ */
3119
3155
{
3120
3156
char * envelope_ns = NULL ;
3121
3157
xmlNodePtr trav ,env ,head ,body ,func ;
3122
3158
xmlAttrPtr attr ;
3123
- sdlFunctionPtr function ;
3159
+ sdlFunctionPtr function = NULL ;
3124
3160
3125
3161
encode_reset_ns ();
3126
3162
@@ -3204,12 +3240,17 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
3204
3240
}
3205
3241
trav = trav -> next ;
3206
3242
}
3243
+ if (soap_action ) {
3244
+ function = find_function_using_soap_action (sdl , soap_action , function_name );
3245
+ }
3207
3246
if (func == NULL ) {
3208
- function = get_doc_function (sdl , NULL );
3209
- if (function != NULL ) {
3210
- ZVAL_STRING (function_name , (char * )function -> functionName );
3211
- } else {
3212
- soap_server_fault ("Client" , "looks like we got \"Body\" without function call" , NULL , NULL , NULL );
3247
+ if (!function ) {
3248
+ function = get_doc_function (sdl , NULL );
3249
+ if (function ) {
3250
+ ZVAL_STRING (function_name , (char * )function -> functionName );
3251
+ } else {
3252
+ soap_server_fault ("Client" , "looks like we got \"Body\" without function call" , NULL , NULL , NULL );
3253
+ }
3213
3254
}
3214
3255
} else {
3215
3256
if (* version == SOAP_1_1 ) {
@@ -3223,7 +3264,9 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
3223
3264
soap_server_fault ("DataEncodingUnknown" ,"Unknown Data Encoding Style" , NULL , NULL , NULL );
3224
3265
}
3225
3266
}
3226
- function = find_function (sdl , func , function_name );
3267
+ if (!function ) {
3268
+ function = find_function (sdl , func , function_name );
3269
+ }
3227
3270
if (sdl != NULL && function == NULL ) {
3228
3271
if (* version == SOAP_1_2 ) {
3229
3272
soap_server_fault ("rpc:ProcedureNotPresent" ,"Procedure not present" , NULL , NULL , NULL );
0 commit comments