@@ -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,33 @@ 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
+ /* The soap action may be a http-quoted string, in which case we're removing the quotes here. */
3101
+ size_t soap_action_length = strlen (soap_action );
3102
+ if (soap_action [0 ] == '"' ) {
3103
+ if (soap_action_length < 2 || soap_action [soap_action_length - 1 ] != '"' ) {
3104
+ return NULL ;
3105
+ }
3106
+ soap_action ++ ;
3107
+ soap_action_length -= 2 ;
3108
+ }
3109
+
3110
+ /* TODO: This may depend on a particular target namespace, in which case this won't find a match when multiple different
3111
+ * target namespaces are used until #45282 is resolved. */
3112
+ sdlFunctionPtr function ;
3113
+ ZEND_HASH_FOREACH_PTR (& sdl -> functions , function ) {
3114
+ if (function -> binding && function -> binding -> bindingType == BINDING_SOAP ) {
3115
+ sdlSoapBindingFunctionPtr fnb = function -> bindingAttributes ;
3116
+ if (fnb && fnb -> soapAction && strncmp (fnb -> soapAction , soap_action , soap_action_length ) == 0 && fnb -> soapAction [soap_action_length ] == '\0' ) {
3117
+ ZVAL_STRING (function_name , function -> functionName );
3118
+ return function ;
3119
+ }
3120
+ }
3121
+ } ZEND_HASH_FOREACH_END ();
3122
+ return NULL ;
3123
+ }
3124
+
3093
3125
static xmlNodePtr get_envelope (xmlNodePtr trav , int * version , char * * envelope_ns ) {
3094
3126
while (trav != NULL ) {
3095
3127
if (trav -> type == XML_ELEMENT_NODE ) {
@@ -3115,12 +3147,12 @@ static xmlNodePtr get_envelope(xmlNodePtr trav, int *version, char **envelope_ns
3115
3147
return NULL ;
3116
3148
}
3117
3149
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 ) /* {{{ */
3150
+ 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
3151
{
3120
3152
char * envelope_ns = NULL ;
3121
3153
xmlNodePtr trav ,env ,head ,body ,func ;
3122
3154
xmlAttrPtr attr ;
3123
- sdlFunctionPtr function ;
3155
+ sdlFunctionPtr function = NULL ;
3124
3156
3125
3157
encode_reset_ns ();
3126
3158
@@ -3204,12 +3236,17 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
3204
3236
}
3205
3237
trav = trav -> next ;
3206
3238
}
3239
+ if (soap_action ) {
3240
+ function = find_function_using_soap_action (sdl , soap_action , function_name );
3241
+ }
3207
3242
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 );
3243
+ if (!function ) {
3244
+ function = get_doc_function (sdl , NULL );
3245
+ if (function ) {
3246
+ ZVAL_STRING (function_name , (char * )function -> functionName );
3247
+ } else {
3248
+ soap_server_fault ("Client" , "looks like we got \"Body\" without function call" , NULL , NULL , NULL );
3249
+ }
3213
3250
}
3214
3251
} else {
3215
3252
if (* version == SOAP_1_1 ) {
@@ -3223,7 +3260,9 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
3223
3260
soap_server_fault ("DataEncodingUnknown" ,"Unknown Data Encoding Style" , NULL , NULL , NULL );
3224
3261
}
3225
3262
}
3226
- function = find_function (sdl , func , function_name );
3263
+ if (!function ) {
3264
+ function = find_function (sdl , func , function_name );
3265
+ }
3227
3266
if (sdl != NULL && function == NULL ) {
3228
3267
if (* version == SOAP_1_2 ) {
3229
3268
soap_server_fault ("rpc:ProcedureNotPresent" ,"Procedure not present" , NULL , NULL , NULL );
0 commit comments