/** * parses request and posts response * * @param string $data XML string * @return string XML response msg * @access private */ function parse_request($data = '') { $this->debug('entering parseRequest() on ' . date('H:i Y-m-d')); $dump = ''; // get headers if (function_exists('getallheaders')) { $this->headers = getallheaders(); foreach ($this->headers as $k => $v) { $dump .= "{$k}: {$v}\r\n"; $this->debug("{$k}: {$v}"); } // get SOAPAction header if (isset($this->headers['SOAPAction'])) { $this->SOAPAction = str_replace('"', '', $this->headers['SOAPAction']); } // get the character encoding of the incoming request if (strpos($this->headers['Content-Type'], '=')) { $enc = str_replace('"', '', substr(strstr($this->headers["Content-Type"], '='), 1)); if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { $this->xml_encoding = $enc; } else { $this->xml_encoding = 'us-ascii'; } } $this->debug('got encoding: ' . $this->charset_encoding); } elseif (is_array($_SERVER)) { $this->headers['User-Agent'] = $_SERVER['HTTP_USER_AGENT']; $this->SOAPAction = isset($_SERVER['SOAPAction']) ? $_SERVER['SOAPAction'] : ''; } $this->request = $dump . "\r\n\r\n" . $data; // parse response, get soap parser obj $parser = new soap_parser($data, $this->charset_encoding); // if fault occurred during message parsing if ($err = $parser->getError()) { // parser debug $this->debug("parser debug: \n" . $parser->debug_str); $this->result = 'fault: error in msg parsing: ' . $err; $this->fault('Server', "error in msg parsing:\n" . $err); // return soapresp return $this->fault->serialize(); // else successfully parsed request into soapval object } else { // get/set methodname $this->methodname = $parser->root_struct_name; $this->debug('method name: ' . $this->methodname); // does method exist? if (!function_exists($this->methodname)) { // "method not found" fault here $this->debug("method '{$this->methodname}' not found!"); $this->debug("parser debug: \n" . $parser->debug_str); $this->result = 'fault: method not found'; $this->fault('Server', "method '{$this->methodname}' not defined in service '{$this->service}'"); return $this->fault->serialize(); } if ($this->wsdl) { if (!($this->opData = $this->wsdl->getOperationData($this->methodname))) { //if( $this->fault('Server', "Operation '{$this->methodname}' is not defined in the WSDL for this service"); return $this->fault->serialize(); } } $this->debug("method '{$this->methodname}' exists"); // evaluate message, getting back parameters $this->debug('calling parser->get_response()'); $request_data = $parser->get_response(); // parser debug $this->debug("parser debug: \n" . $parser->debug_str); // verify that request parameters match the method's signature if ($this->verify_method($this->methodname, $request_data)) { // if there are parameters to pass $this->debug('params var dump ' . $this->varDump($request_data)); if ($request_data) { $this->debug("calling '{$this->methodname}' with params"); if (!function_exists('call_user_func_array')) { $this->debug('calling method using eval()'); $funcCall = $this->methodname . '('; foreach ($request_data as $param) { $funcCall .= "\"{$param}\","; } $funcCall = substr($funcCall, 0, -1) . ')'; $this->debug('function call:<br>' . $funcCall); @eval("\$method_response = {$funcCall};"); } else { $this->debug('calling method using call_user_func_array()'); $method_response = call_user_func_array("{$this->methodname}", $request_data); } $this->debug('response var dump' . $this->varDump($method_response)); } else { // call method w/ no parameters $this->debug("calling {$this->methodname} w/ no params"); $m = $this->methodname; $method_response = @$m(); } $this->debug("done calling method: {$this->methodname}, received {$method_response} of type" . gettype($method_response)); // if we got nothing back. this might be ok (echoVoid) if (isset($method_response) && $method_response != '' || is_bool($method_response)) { // if fault if (get_class($method_response) == 'soap_fault') { $this->debug('got a fault object from method'); $this->fault = $method_response; return $method_response->serialize(); // if return val is soapval object } elseif (get_class($method_response) == 'soapval') { $this->debug('got a soapval object from method'); $return_val = $method_response->serialize(); // returned other } else { $this->debug('got a(n) ' . gettype($method_response) . ' from method'); $this->debug('serializing return value'); if ($this->wsdl) { // weak attempt at supporting multiple output params if (sizeof($this->opData['output']['parts']) > 1) { $opParams = $method_response; } else { $opParams = array($method_response); } $return_val = $this->wsdl->serializeRPCParameters($this->methodname, 'output', $opParams); } else { $return_val = $this->serialize_val($method_response); } } $this->debug('return val:' . $this->varDump($return_val)); } else { $return_val = ''; $this->debug('got no response from method'); } $this->debug('serializing response'); $payload = '<' . $this->methodname . "Response>" . $return_val . '</' . $this->methodname . "Response>"; $this->result = 'successful'; if ($this->wsdl) { //if($this->debug_flag){ $this->debug("WSDL debug data:\n" . $this->wsdl->debug_str); // } // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. return $this->serializeEnvelope($payload, $this->responseHeaders, $this->wsdl->usedNamespaces, $this->opData['style']); } else { return $this->serializeEnvelope($payload, $this->responseHeaders); } } else { // debug $this->debug('ERROR: request not verified against method signature'); $this->result = 'fault: request failed validation against method signature'; // return fault $this->fault('Server', "Operation '{$this->methodname}' not defined in service."); return $this->fault->serialize(); } } }
/** * processes SOAP message received from client * * @param array $headers The HTTP headers * @param string $data unprocessed request data from client * @return mixed value of the message, decoded into a PHP type * @access private */ function parseRequest($headers, $data) { $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); if (!strstr($headers['content-type'], 'text/xml')) { $this->setError('Request not of type text/xml'); return false; } if (strpos($headers['content-type'], '=')) { $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); $this->debug('Got response encoding: ' . $enc); if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { $this->xml_encoding = strtoupper($enc); } else { $this->xml_encoding = 'US-ASCII'; } } else { // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 $this->xml_encoding = 'ISO-8859-1'; } $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); // parse response, get soap parser obj $parser = new soap_parser($data, $this->xml_encoding, '', $this->decode_utf8); // parser debug $this->debug("parser debug: \n" . $parser->getDebug()); // if fault occurred during message parsing if ($err = $parser->getError()) { $this->result = 'fault: error in msg parsing: ' . $err; $this->fault('Client', "error in msg parsing:\n" . $err); // else successfully parsed request into soapval object } else { // get/set methodname $this->methodURI = $parser->root_struct_namespace; $this->methodname = $parser->root_struct_name; $this->debug('methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); $this->debug('calling parser->get_response()'); $this->methodparams = $parser->get_response(); // get SOAP headers $this->requestHeaders = $parser->getHeaders(); // add document for doclit support $this->document = $parser->document; } }
/** * parses request and posts response * * @param string $data XML string * @return object SOAPx4 soapmsg object * @access private */ function parse_request($data = "") { $this->debug("entering parseRequest() on " . date("H:i Y-m-d")); // get headers if (function_exists("getallheaders")) { $this->headers = getallheaders(); foreach ($this->headers as $k => $v) { $dump .= "{$k}: {$v}\r\n"; $this->debug("{$k}: {$v}"); } // get SOAPAction header if ($this->headers['SOAPAction']) { $this->SOAPAction = str_replace('"', '', $this->headers['SOAPAction']); } // get the character encoding of the incoming request if (strpos($headers_array['Content-Type'], "=")) { $enc = str_replace("\"", "", substr(strstr($headers_array["Content-Type"], "="), 1)); if (preg_match("/^(ISO-8859-1|US-ASCII|UTF-8)\$/i", $enc)) { $this->xml_encoding = $enc; } else { $this->xml_encoding = 'us-ascii'; } } $this->debug("got encoding: {$this->xml_encoding}"); } elseif (is_array($_SERVER)) { $this->headers['User-Agent'] = $_SERVER['HTTP_USER_AGENT']; $this->SOAPAction = $_SERVER['SOAPAction']; } $this->request = $dump . "\r\n\r\n" . $data; // parse response, get soap parser obj $parser = new soap_parser($data, $this->xml_encoding); // if fault occurred during message parsing if ($err = $parser->getError()) { // parser debug $this->debug("parser debug: \n" . $parser->debug_str); $this->result = "fault: error in msg parsing or eval: {$err}"; $this->fault("Server", "error in msg parsing or eval:\n" . $err); // return soapresp return $this->fault->serialize(); // else successfully parsed request into soapval object } else { // get/set methodname $this->methodname = $parser->root_struct_name; $this->debug("method name: {$this->methodname}"); // does method exist? if (!function_exists($this->methodname)) { // "method not found" fault here $this->debug("method '{$this->methodname}' not found!"); $this->debug("parser debug: \n" . $parser->debug_str); $this->result = "fault: method not found"; $this->fault("Server", "method '{$this->methodname}' not defined in service '{$this->service}'"); return $this->fault->serialize(); } if ($this->wsdl) { if (!($this->opData = $this->wsdl->getOperationData($this->methodname))) { $this->fault('Server', "Operation '{$this->methodname}' is not defined in the WSDL for this service"); return $this->fault->serialize(); } } $this->debug("method '{$this->methodname}' exists"); // evaluate message, getting back parameters $this->debug("calling parser->get_response()"); $request_data = $parser->get_response(); $this->debug('Parsed response dump: $request_data'); // parser debug $this->debug("parser debug: \n" . $parser->debug_str); // verify that request parameters match the method's signature if ($this->verify_method($this->methodname, $request_data)) { // if there are parameters to pass if ($request_data) { $this->debug("calling '{$this->methodname}' with params"); if (!function_exists('call_user_func_array')) { $this->debug("calling method using eval()"); $funcCall = $this->methodname . "("; foreach ($request_data as $param) { $funcCall .= "\"{$param}\","; } $funcCall = substr($funcCall, 0, -1) . ')'; $this->debug("function call:<br>{$funcCall}"); eval("\$method_response = {$funcCall};"); } else { $this->debug("calling method using call_user_func_array()"); $method_response = call_user_func_array("{$this->methodname}", $request_data); } } else { // call method w/ no parameters $this->debug("calling {$this->methodname} w/ no params"); //$method_response = call_user_func($this->methodname); $m = $this->methodname; $method_response = $m(); } $this->debug("done calling method: {$this->methodname}, received {$method_response} of type" . gettype($method_response)); // if we got nothing back. this might be ok (echoVoid) if (isset($method_response) && $method_response != "" || is_bool($method_response)) { // if fault if (get_class($method_response) == 'soap_fault') { $this->debug('got a fault object from method'); $this->fault = $method_response; return $method_response->serialize(); // if return val is soapval object } elseif (get_class($method_response) == 'soapval') { $this->debug('got a soapval object from method'); $return_val = $method_response->serialize(); // returned other } else { $this->debug("got a " . gettype($method_response) . " from method"); $this->debug("serializing return value"); if ($this->wsdl) { if (sizeof($this->opData['output']['parts']) > 1) { $opParams = $method_response; } else { $opParams = array($method_response); } $return_val = $this->wsdl->serializeRPCParameters($this->methodname, 'output', $opParams); } else { $return_val = $this->serialize_val($method_response); } } } $this->debug("serializing response"); $payload = "<" . $this->methodname . "Response>\n" . $return_val . "</" . $this->methodname . "Response>\n"; $this->result = "successful"; if ($this->wsdl) { //$this->debug("WSDL debug data:\n".$this->wsdl->debug_str); } return $this->serializeEnvelope($payload, $this->responseHeaders); } else { // debug $this->debug("ERROR: request not verified against method signature"); $this->result = "fault: request failed validation against method signature"; // return fault $this->fault("Server", "Sorry, operation '{$this->methodname}' not defined in service."); return $this->fault->serialize(); } } }
/** * parses a request * * The following fields are set by this function (when successful) * * headers * request * xml_encoding * SOAPAction * request * requestSOAP * methodURI * methodname * methodparams * requestHeaders * document * * This sets the fault field on error * * @param string $data XML string * @access private */ function parse_request($data = '') { $this->debug('entering parse_request()'); $this->parse_http_headers(); $this->debug('got character encoding: ' . $this->xml_encoding); // uncompress if necessary if (isset($this->headers['Content-Encoding']) && $this->headers['Content-Encoding'] != '') { $this->debug('got content encoding: ' . $this->headers['Content-Encoding']); if ($this->headers['Content-Encoding'] == 'deflate' || $this->headers['Content-Encoding'] == 'gzip') { // if decoding works, use it. else assume data wasn't gzencoded if (function_exists('gzuncompress')) { if ($this->headers['Content-Encoding'] == 'deflate' && ($degzdata = @gzuncompress($data))) { $data = $degzdata; } elseif ($this->headers['Content-Encoding'] == 'gzip' && ($degzdata = gzinflate(substr($data, 10)))) { $data = $degzdata; } else { $this->fault('Client', 'Errors occurred when trying to decode the data'); return; } } else { $this->fault('Client', 'This Server does not support compressed data'); return; } } } $this->request .= "\r\n" . $data; $this->requestSOAP = $data; // parse response, get soap parser obj $parser = new soap_parser($data, $this->xml_encoding, '', $this->decode_utf8); // parser debug $this->debug("parser debug: \n" . $parser->getDebug()); // if fault occurred during message parsing if ($err = $parser->getError()) { $this->result = 'fault: error in msg parsing: ' . $err; $this->fault('Client', "error in msg parsing:\n" . $err); // else successfully parsed request into soapval object } else { // get/set methodname $this->methodURI = $parser->root_struct_namespace; $this->methodname = $parser->root_struct_name; $this->debug('methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); $this->debug('calling parser->get_response()'); $this->methodparams = $parser->get_response(); // get SOAP headers $this->requestHeaders = $parser->getHeaders(); // add document for doclit support $this->document = $parser->document; } $this->debug('leaving parse_request'); }
/** * parses request and posts response * * @param string $data XML string * @return string XML response msg * @access private */ function parse_request($data='') { global $HTTP_SERVER_VARS; $this->debug('entering parseRequest() on '.date('H:i Y-m-d')); $dump = ''; // get headers if(function_exists('getallheaders')){ $this->headers = getallheaders(); foreach($this->headers as $k=>$v){ $dump .= "$k: $v\r\n"; $this->debug("$k: $v"); } // get SOAPAction header if(isset($this->headers['SOAPAction'])){ $this->SOAPAction = str_replace('"','',$this->headers['SOAPAction']); } // get the character encoding of the incoming request if(strpos($this->headers['Content-Type'],'=')){ $enc = str_replace('"','',substr(strstr($this->headers["Content-Type"],'='),1)); if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ $this->xml_encoding = strtoupper($enc); } else { $this->xml_encoding = 'US-ASCII'; } } else { // should be US-ASCII, but for XML, let's be pragmatic and admit UTF-8 is most common $this->xml_encoding = 'UTF-8'; } } elseif(isset($_SERVER) && is_array($_SERVER)){ foreach ($_SERVER as $k => $v) { if (substr($k, 0, 5) == 'HTTP_') { $k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($k, 5))))); if ($k == 'Soapaction') { // get SOAPAction header $k = 'SOAPAction'; $v = str_replace('"', '', $v); $v = str_replace('\\', '', $v); } else if ($k == 'Content-Type') { // get the character encoding of the incoming request if (strpos($v, '=')) { $enc = substr(strstr($v, '='), 1); $enc = str_replace('"', '', $enc); $enc = str_replace('\\', '', $enc); if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { $this->xml_encoding = strtoupper($enc); } else { $this->xml_encoding = 'US-ASCII'; } } else { // should be US-ASCII, but for XML, let's be pragmatic and admit UTF-8 is most common $this->xml_encoding = 'UTF-8'; } } $this->headers[$k] = $v; $dump .= "$k: $v\r\n"; $this->debug("$k: $v"); } } } elseif (is_array($HTTP_SERVER_VARS)) { foreach ($HTTP_SERVER_VARS as $k => $v) { if (substr($k, 0, 5) == 'HTTP_') { $k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($k, 5))))); if ($k == 'Soapaction') { // get SOAPAction header $k = 'SOAPAction'; $v = str_replace('"', '', $v); $v = str_replace('\\', '', $v); } else if ($k == 'Content-Type') { // get the character encoding of the incoming request if (strpos($v, '=')) { $enc = substr(strstr($v, '='), 1); $enc = str_replace('"', '', $enc); $enc = str_replace('\\', '', $enc); if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { $this->xml_encoding = strtoupper($enc); } else { $this->xml_encoding = 'US-ASCII'; } } else { // should be US-ASCII, but for XML, let's be pragmatic and admit UTF-8 is most common $this->xml_encoding = 'UTF-8'; } } $this->headers[$k] = $v; $dump .= "$k: $v\r\n"; $this->debug("$k: $v"); } } } $this->debug('got character encoding: '.$this->xml_encoding); if (isset($this->headers['Content-Encoding']) && $this->headers['Content-Encoding'] != '') { $this->debug('got content encoding: ' . $this->headers['Content-Encoding']); if ($this->headers['Content-Encoding'] == 'deflate' || $this->headers['Content-Encoding'] == 'gzip') { // if decoding works, use it. else assume data wasn't gzencoded if (function_exists('gzuncompress')) { if ($this->headers['Content-Encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { $data = $degzdata; } elseif ($this->headers['Content-Encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { $data = $degzdata; } else { $this->fault('Server', 'Errors occurred when trying to decode the data'); return $this->fault->serialize(); } } else { $this->fault('Server', 'This Server does not support compressed data'); return $this->fault->serialize(); } } } $this->request = $dump."\r\n\r\n".$data; // parse response, get soap parser obj $parser = new soap_parser($data,$this->xml_encoding); // if fault occurred during message parsing if($err = $parser->getError()){ // parser debug $this->debug("parser debug: \n".$parser->debug_str); $this->result = 'fault: error in msg parsing: '.$err; $this->fault('Server',"error in msg parsing:\n".$err); // return soapresp return $this->fault->serialize(); // else successfully parsed request into soapval object } else { // get/set methodname $this->methodname = $parser->root_struct_name; $this->debug('method name: '.$this->methodname); // does method exist? if(!function_exists($this->methodname)){ // "method not found" fault here $this->debug("method '$this->methodname' not found!"); $this->debug("parser debug: \n".$parser->debug_str); $this->result = 'fault: method not found'; $this->fault('Server',"method '$this->methodname' not defined in service '$this->service'"); return $this->fault->serialize(); } if($this->wsdl){ if(!$this->opData = $this->wsdl->getOperationData($this->methodname)){ //if( $this->fault('Server',"Operation '$this->methodname' is not defined in the WSDL for this service"); return $this->fault->serialize(); } } $this->debug("method '$this->methodname' exists"); // evaluate message, getting back parameters $this->debug('calling parser->get_response()'); $request_data = $parser->get_response(); // parser debug $this->debug("parser debug: \n".$parser->debug_str); // verify that request parameters match the method's signature if($this->verify_method($this->methodname,$request_data)){ // if there are parameters to pass $this->debug('params var dump '.$this->varDump($request_data)); if($request_data){ $this->debug("calling '$this->methodname' with params"); if (! function_exists('call_user_func_array')) { $this->debug('calling method using eval()'); $funcCall = $this->methodname.'('; foreach($request_data as $param) { $funcCall .= "\"$param\","; } $funcCall = substr($funcCall, 0, -1).')'; $this->debug('function call:<br>'.$funcCall); @eval("\$method_response = $funcCall;"); } else { $this->debug('calling method using call_user_func_array()'); $method_response = call_user_func_array("$this->methodname",$request_data); } $this->debug('response var dump'.$this->varDump($method_response)); } else { // call method w/ no parameters $this->debug("calling $this->methodname w/ no params"); $m = $this->methodname; $method_response = @$m(); } $this->debug("done calling method: $this->methodname, received $method_response of type".gettype($method_response)); // if we got nothing back. this might be ok (echoVoid) if(isset($method_response) && $method_response != '' || is_bool($method_response)) { // if fault if(get_class($method_response) == 'soap_fault'){ $this->debug('got a fault object from method'); $this->fault = $method_response; return $method_response->serialize(); // if return val is soapval object } elseif(get_class($method_response) == 'soapval'){ $this->debug('got a soapval object from method'); $return_val = $method_response->serialize(); // returned other } else { $this->debug('got a(n) '.gettype($method_response).' from method'); $this->debug('serializing return value'); if($this->wsdl){ // weak attempt at supporting multiple output params if(sizeof($this->opData['output']['parts']) > 1){ $opParams = $method_response; } else { $opParams = array($method_response); } $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); } else { $return_val = $this->serialize_val($method_response); } } $this->debug('return val:'.$this->varDump($return_val)); } else { $return_val = ''; $this->debug('got no response from method'); } $this->debug('serializing response'); $payload = '<'.$this->methodname."Response>".$return_val.'</'.$this->methodname."Response>"; $this->result = 'successful'; if($this->wsdl){ //if($this->debug_flag){ $this->debug("WSDL debug data:\n".$this->wsdl->debug_str); // } // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. return $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style']); } else { return $this->serializeEnvelope($payload,$this->responseHeaders); } } else { // debug $this->debug('ERROR: request not verified against method signature'); $this->result = 'fault: request failed validation against method signature'; // return fault $this->fault('Server',"Operation '$this->methodname' not defined in service."); return $this->fault->serialize(); } } }