@@ -58,7 +58,7 @@ static sdlParamPtr get_param(sdlFunctionPtr function, const char *param_name, ze
5858static sdlFunctionPtr get_function (sdlPtr sdl , const char * function_name , size_t function_name_length );
5959static sdlFunctionPtr get_doc_function (sdlPtr sdl , xmlNodePtr params );
6060
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 );
6262static xmlDocPtr serialize_response_call (sdlFunctionPtr function , const char * function_name , const char * uri ,zval * ret , soapHeader * headers , int version );
6363static 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 );
6464static 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)
12731273 HashTable * old_class_map , * old_typemap ;
12741274 int old_features ;
12751275 zval tmp_soap ;
1276+ const char * soap_action = NULL ;
12761277
12771278 if (zend_parse_parameters (ZEND_NUM_ARGS (), "|s!" , & arg , & arg_len ) == FAILURE ) {
12781279 RETURN_THROWS ();
@@ -1341,7 +1342,7 @@ PHP_METHOD(SoapServer, handle)
13411342
13421343 if (!arg ) {
13431344 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 ;
13451346 php_stream_filter * zf = NULL ;
13461347 zend_string * server = ZSTR_KNOWN (ZEND_STR_AUTOGLOBAL_SERVER );
13471348
@@ -1375,6 +1376,10 @@ PHP_METHOD(SoapServer, handle)
13751376 }
13761377 }
13771378
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+
13781383 doc_request = soap_xmlParseFile ("php://input" );
13791384
13801385 if (zf ) {
@@ -1418,7 +1423,7 @@ PHP_METHOD(SoapServer, handle)
14181423 old_soap_version = SOAP_GLOBAL (soap_version );
14191424
14201425 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 );
14221427 } zend_catch {
14231428 /* Avoid leaking persistent memory */
14241429 xmlFreeDoc (doc_request );
@@ -3090,6 +3095,37 @@ static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_
30903095}
30913096/* }}} */
30923097
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+
30933129static xmlNodePtr get_envelope (xmlNodePtr trav , int * version , char * * envelope_ns ) {
30943130 while (trav != NULL ) {
30953131 if (trav -> type == XML_ELEMENT_NODE ) {
@@ -3115,12 +3151,12 @@ static xmlNodePtr get_envelope(xmlNodePtr trav, int *version, char **envelope_ns
31153151 return NULL ;
31163152}
31173153
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 ) /* {{{ */
31193155{
31203156 char * envelope_ns = NULL ;
31213157 xmlNodePtr trav ,env ,head ,body ,func ;
31223158 xmlAttrPtr attr ;
3123- sdlFunctionPtr function ;
3159+ sdlFunctionPtr function = NULL ;
31243160
31253161 encode_reset_ns ();
31263162
@@ -3204,12 +3240,17 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
32043240 }
32053241 trav = trav -> next ;
32063242 }
3243+ if (soap_action ) {
3244+ function = find_function_using_soap_action (sdl , soap_action , function_name );
3245+ }
32073246 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+ }
32133254 }
32143255 } else {
32153256 if (* version == SOAP_1_1 ) {
@@ -3223,7 +3264,9 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
32233264 soap_server_fault ("DataEncodingUnknown" ,"Unknown Data Encoding Style" , NULL , NULL , NULL );
32243265 }
32253266 }
3226- function = find_function (sdl , func , function_name );
3267+ if (!function ) {
3268+ function = find_function (sdl , func , function_name );
3269+ }
32273270 if (sdl != NULL && function == NULL ) {
32283271 if (* version == SOAP_1_2 ) {
32293272 soap_server_fault ("rpc:ProcedureNotPresent" ,"Procedure not present" , NULL , NULL , NULL );
0 commit comments