%PDF- %PDF-
Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/webservice/classes/general/soap/ |
Current File : //proc/self/root/home/bitrix/www/bitrix/modules/webservice/classes/general/soap/soapserver.php |
<?php class CSOAPServerResponser { function OnBeforeRequest(&$cserver) { } /* $cserver->RawPostData */ function OnAfterResponse(&$cserver) { } /* * If function returns true, chain of ProcessRequest ends. * If function returns true, this means function already passed It's value to ShowResponse handler * If returns false, then next item in a chain will be called. * Result Value must be set to $cserver->ResponseValue */ function ProcessRequestHeader(&$cserver, $header) { } /* stub, never used */ function ProcessRequestBody(&$cserver, $body) { } } class CWSSOAPResponser extends CSOAPServerResponser { /* * typename => name => array() * funcname => parameters => array() * Array can contain: * serialize => class/assoc array. * varType, arrType * */ var $TypensVars; /// message => function var $MessageTags; /// Contains a list over registered functions var $FunctionList; function RegisterFunction($name, $params = array()) { $this->FunctionList[] = $name; $this->TypensVars[$name] = $params; if ($params["request"]) $this->MessageTags[$params["request"]] = $name; if ($params["response"]) $this->MessageTags[$params["response"]] = $name; } /* * $complex = array( "typename" => array( paraname => array(type desc, valType))) */ function RegisterComplexType($complex) { foreach ($complex as $complexTypeName => $declaration) { $this->TypensVars[$complexTypeName] = $declaration; } } function ProcessRequestBody(&$cserver, $body) { $functionName = $body->name(); $namespaceURI = $body->namespaceURI(); $requestNode = $body; // If this is request name in functionName, get functionName. if (!in_array($functionName, $this->FunctionList) and isset($this->MessageTags[$functionName]) ) { $functionName = $this->MessageTags[$functionName]; } if (!in_array($functionName, $this->FunctionList)) { CSOAPServer::ShowSOAPFault("Trying to access unregistered function: ".$functionName); return true; } $objectName = ""; $params = array(); $paramsDecoder = new CSOAPResponse($functionName, $namespaceURI); $paramsDecoder->setTypensVars($this->TypensVars); if (!isset($this->TypensVars[$functionName]) or !isset($this->TypensVars[$functionName]["myclassname"]) or !isset($this->TypensVars[$functionName]["input"]) ) { CSOAPServer::ShowSOAPFault("Requested function has no type specified: ".$functionName); return true; } $objectName = $this->TypensVars[$functionName]["myclassname"]; $inputParams = $this->TypensVars[$functionName]["input"]; $httpAuth = "N"; if (isset($this->TypensVars[$functionName]["httpauth"])) { $httpAuth = $this->TypensVars[$functionName]["httpauth"]; } if ($httpAuth == "Y" and !CWebService::MethodRequireHTTPAuth($objectName, $functionName)) { CSOAPServer::ShowSOAPFault("Requested function requires HTTP Basic Auth to be done before."); return true; } $requestParams = array(); // reorganize params foreach ($requestNode->children() as $parameterNode) { if (!$parameterNode->name()) continue; $requestParams[$parameterNode->name()] = $parameterNode; } // check parameters/decode // check strict params foreach ($inputParams as $pname => $param) { $decoded = null; if (isset($requestParams[$pname])) { $decoded = $paramsDecoder->decodeDataTypes($requestParams[$pname]); } if (is_object($decoded) and (get_class($decoded) == "CSOAPFault" or get_class($decoded) == "csoapfault")) { CSOAPServer::ShowSOAPFault($decoded); return true; } if ( !isset($decoded) and (!isset($param["strict"]) or (isset($param["strict"]) and $param["strict"] == "strict")) ) { CSOAPServer::ShowSOAPFault("Request has not enough params of strict type to be decoded. "); return true; } $params[] = $decoded; } unset($paramsDecoder); $object = null; if (class_exists($objectName)) $object = new $objectName; if (is_object($object) && method_exists($object, $functionName)) { $this->ShowResponse( $cserver, $functionName, $namespaceURI, call_user_func_array( array($object, $functionName), $params ) ); } else if (!class_exists($objectName)) { $this->ShowResponse( $cserver, $functionName, $namespaceURI, new CSOAPFault('Server Error', 'Object not found') ); } else { $this->ShowResponse( $cserver, $functionName, $namespaceURI, new CSOAPFault('Server Error', 'Method not found') ); } return true; } function ShowResponse(&$cserver, $functionName, $namespaceURI, &$value) { global $APPLICATION; // Convert input data to XML $response = new CSOAPResponse($functionName, $namespaceURI); $response->setTypensVars($this->TypensVars); $response->setValue($value); $payload = $response->payload(); header("SOAPServer: BITRIX SOAP"); header("Content-Type: text/xml; charset=\"UTF-8\""); Header("Content-Length: ".(defined('BX_UTF') && BX_UTF == 1 && function_exists('mb_strlen')? mb_strlen($payload, 'latin1'): strlen($payload))); $APPLICATION->RestartBuffer(); $cserver->RawPayloadData = $payload; echo $payload; } } class CSOAPServer { /// Contains the RAW HTTP post data information var $RawPostData; var $RawPayloadData; /// Consists of instances of CSOAPServerResponser var $OnRequestEvent = array(); function CSOAPServer() { $this->RawPostData = file_get_contents("php://input"); } function GetRequestData() { return $this->RawPostData; } function GetResponseData() { return $this->RawPayloadData; } function AddServerResponser(&$respobject) { if (is_subclass_of($respobject, "CSOAPServerResponser")) { $this->OnRequestEvent[count($this->OnRequestEvent)] =& $respobject; return true; } return false; } // $valueEncoded type of CXMLCreator function ShowRawResponse($valueEncoded, $wrapEnvelope = false) { global $APPLICATION; if ($wrapEnvelope) { // $valueEncoded class of CXMLCreator $root = new CXMLCreator("soap:Envelope"); $root->setAttribute("xmlns:soap", BX_SOAP_ENV); // add the body $body = new CXMLCreator("soap:Body"); $body->addChild($valueEncoded); $root->addChild($body); $valueEncoded = $root; } $payload = CXMLCreator::getXMLHeader().$valueEncoded->getXML(); header("SOAPServer: BITRIX SOAP"); header("Content-Type: text/xml; charset=\"UTF-8\""); Header("Content-Length: ".(defined('BX_UTF') && BX_UTF == 1 && function_exists('mb_strlen')? mb_strlen($payload, 'latin1'): strlen($payload))); $APPLICATION->RestartBuffer(); $this->RawPayloadData = $payload; echo $payload; } function ShowResponse($functionName, $namespaceURI, $valueName, &$value) { global $APPLICATION; // Convert input data to XML $response = new CSOAPResponse($functionName, $namespaceURI); $response->setValueName($valueName); $response->setValue($value); $payload = $response->payload(); header("SOAPServer: BITRIX SOAP"); header("Content-Type: text/xml; charset=\"UTF-8\""); Header("Content-Length: ".(defined('BX_UTF') && BX_UTF == 1 && function_exists('mb_strlen')? mb_strlen($payload, 'latin1'): strlen($payload))); $APPLICATION->RestartBuffer(); $this->RawPayloadData = $payload; echo $payload; } /* static */ function ShowSOAPFault($errorString) { global $APPLICATION; $response = new CSOAPResponse('unknown_function_name', 'unknown_namespace_uri'); if (is_object($errorString) and (get_class($errorString) == "CSOAPFault" or get_class($errorString) == "csoapfault")) $response->setValue($errorString /*CSOAPFault*/); else $response->setValue(new CSOAPFault('Server Error', $errorString)); $payload = $response->payload(); header("SOAPServer: BITRIX SOAP"); header("Content-Type: text/xml; charset=\"UTF-8\""); Header("Content-Length: ".(defined('BX_UTF') && BX_UTF == 1 && function_exists('mb_strlen')? mb_strlen($payload, 'latin1'): strlen($payload))); $APPLICATION->RestartBuffer(); echo $payload; die(); } /** Processes the SOAP request and prints out the propper response. */ function ProcessRequest() { global $APPLICATION; if ( $_SERVER["REQUEST_METHOD"] != "POST" ||!class_exists("CDataXML") ) { $this->ShowSOAPFault("Error: this web page does only understand POST methods. BitrixXMLParser. "); } for ($i = 0; $i < count($this->OnRequestEvent); $i++) { $this->OnRequestEvent[$i]->OnBeforeRequest($this); } //AddMessage2Log($this->RawPostData); $xmlData = $this->stripHTTPHeader($this->RawPostData); $xmlData = $APPLICATION->ConvertCharset($xmlData, "UTF-8", SITE_CHARSET); $xml = new CDataXML(); //AddMessage2Log($xmlData); if (!$xml->LoadString($xmlData)) { $this->ShowSOAPFault("Error: Can't parse request xml data. "); } $dom = $xml->GetTree(); // Check for non-parsing XML, to avoid call to non-object error. if (!is_object($dom)) { $this->ShowSOAPFault("Bad XML"); } // add namespace fetching on body // get the SOAP body $body = $dom->elementsByName("Body"); $children = $body[0]->children(); if (count($children) == 1) { $requestNode = $children[0]; $requestParsed = false; // get target namespace for request // it often function request message. in wsdl gen. = function+"request" $functionName = $requestNode->name(); $namespaceURI = $requestNode->namespaceURI(); for ($i = 0; $i < count($this->OnRequestEvent); $i++) { if ($this->OnRequestEvent[$i]->ProcessRequestBody($this, $requestNode)) { $requestParsed = true; break; } } for ($i = 0; $i < count($this->OnRequestEvent); $i++) $this->OnRequestEvent[$i]->OnAfterResponse($this); if (!$requestParsed) $this->ShowSOAPFault('Unknown operation requested.'); return $requestParsed; } else { $this->ShowSOAPFault('"Body" element in the request has wrong number of children'); } return false; } function stripHTTPHeader($data) { //$start = strpos( $data, "<"."?xml" ); $start = strpos($data, "\r\n\r\n"); return substr($data, $start, strlen($data) - $start); } }