/** * {@inheritdoc} */ public function serialize($method, array $params = []) { $toBeVisited = [&$params]; while (isset($toBeVisited[0]) && ($value =& $toBeVisited[0])) { $type = gettype($value); if ($type === 'array') { // Zend converts non-zero-indexed arrays to structs if (array_keys($value) !== range(0, count($value) - 1) && array_keys($value) == range(1, count($value))) { $value = array_values($value); } foreach ($value as &$child) { $toBeVisited[] =& $child; } } elseif ($type === 'object') { if ($value instanceof \DateTime) { $value = \Zend_XmlRpc_Value::getXmlRpcValue($value->format('Ymd\\TH:i:s'), \Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME); } elseif ($value instanceof Base64) { $value = \Zend_XmlRpc_Value::getXmlRpcValue($value->getDecoded(), \Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64); } else { $value = get_object_vars($value); } } elseif ($type === 'resource') { throw new InvalidTypeException($value); } array_shift($toBeVisited); } $request = new \Zend_XmlRpc_Request($method, $params); try { return $request->saveXml(); } catch (\Exception $e) { throw new SerializerException($e->getMessage(), $e->getCode(), $e); } }
/** * __toString() test */ public function test__toString() { $argv = array('string', true); $this->_request->setMethod('do.Something'); $this->_request->setParams($argv); $xml = $this->_request->__toString(); try { $sx = new SimpleXMLElement($xml); } catch (Exception $e) { $this->fail('Invalid XML returned'); } $result = $sx->xpath('//methodName'); $count = 0; while (list(, $node) = each($result)) { ++$count; } $this->assertEquals(1, $count, $xml); $result = $sx->xpath('//params'); $count = 0; while (list(, $node) = each($result)) { ++$count; } $this->assertEquals(1, $count, $xml); try { $methodName = (string) $sx->methodName; $params = array((string) $sx->params->param[0]->value->string, (bool) $sx->params->param[1]->value->boolean); } catch (Exception $e) { $this->fail('One or more inconsistencies parsing generated XML: ' . $e->getMessage()); } $this->assertEquals('do.Something', $methodName); $this->assertSame($argv, $params, $xml); }
/** * Test encoding settings */ public function testSetGetEncoding() { $this->assertEquals('UTF-8', $this->_request->getEncoding()); $this->assertEquals('UTF-8', Zend_XmlRpc_Value::getGenerator()->getEncoding()); $this->assertSame($this->_request, $this->_request->setEncoding('ISO-8859-1')); $this->assertEquals('ISO-8859-1', $this->_request->getEncoding()); $this->assertEquals('ISO-8859-1', Zend_XmlRpc_Value::getGenerator()->getEncoding()); }
/** * @group ZF-12293 */ public function testDoesNotAllowExternalEntities() { $payload = file_get_contents(dirname(__FILE__) . '/_files/ZF12293-request.xml'); $payload = sprintf($payload, 'file://' . realpath(dirname(__FILE__) . '/_files/ZF12293-payload.txt')); $this->_request->loadXml($payload); $method = $this->_request->getMethod(); $this->assertTrue(empty($method)); if (is_string($method)) { $this->assertNotContains('Local file inclusion', $method); } }
/** * */ public function saveXML() { $xml = ''; if (extension_loaded('WebServices')) { $xml = rpc_encode_request($this->_method, $this->_params, $this->_requestOptions); $xml = preg_replace("/>\n(\\s*)?(<?)/", '>$2', $xml); } else { $xml = parent::saveXML(); } return $xml; }
/** * Perform an XML-RPC request and return a response. * * @param Zend_XmlRpc_Request $request * @param null|Zend_XmlRpc_Response $response * @return void */ public function doRequest($request, $response = null) { $this->_lastRequest = $request; iconv_set_encoding('input_encoding', 'UTF-8'); iconv_set_encoding('output_encoding', 'UTF-8'); iconv_set_encoding('internal_encoding', 'UTF-8'); $http = $this->getHttpClient(); $http->setUri($this->_serverAddress); $http->setHeaders(array('Content-Type: text/xml; charset=utf-8', 'User-Agent: Zend_XmlRpc_Client')); $xml = $this->_lastRequest->__toString(); $http->setRawData($xml); $httpResponse = $http->request(Zend_Http_Client::POST); if (!$httpResponse->isSuccessful()) { throw new Zend_XmlRpc_Client_HttpException($httpResponse->getMessage(), $httpResponse->getStatus()); } if ($response === null) { $response = new Zend_XmlRpc_Response(); } $this->_lastResponse = $response; $this->_lastResponse->loadXml($httpResponse->getBody()); }
/** * Perform an XML-RPC request and return a response. * * @param Zend_XmlRpc_Request $request * @param null|Zend_XmlRpc_Response $response * @return void * @throws Zend_XmlRpc_Client_HttpException */ public function doRequest($request, $response = null) { $this->_lastRequest = $request; if (PHP_VERSION_ID < 50600) { iconv_set_encoding('input_encoding', 'UTF-8'); iconv_set_encoding('output_encoding', 'UTF-8'); iconv_set_encoding('internal_encoding', 'UTF-8'); } else { ini_set('input_encoding', 'UTF-8'); ini_set('output_encoding', 'UTF-8'); ini_set('default_charset', 'UTF-8'); } $http = $this->getHttpClient(); if ($http->getUri() === null) { $http->setUri($this->_serverAddress); } $http->setHeaders(array('Content-Type: text/xml; charset=utf-8', 'Accept: text/xml')); if ($http->getHeader('user-agent') === null) { $http->setHeaders(array('User-Agent: Zend_XmlRpc_Client')); } $xml = $this->_lastRequest->__toString(); $http->setRawData($xml); $httpResponse = $http->request(Zend_Http_Client::POST); if (!$httpResponse->isSuccessful()) { /** * Exception thrown when an HTTP error occurs * @see Zend_XmlRpc_Client_HttpException */ throw new Zend_XmlRpc_Client_HttpException($httpResponse->getMessage(), $httpResponse->getStatus()); } if ($response === null) { $response = new Zend_XmlRpc_Response(); } $this->_lastResponse = $response; $this->_lastResponse->loadXml(trim($httpResponse->getBody())); }
/** * Handle an xmlrpc call (actual work) * * @param Zend_XmlRpc_Request $request * @return Zend_XmlRpc_Response * @throws Zend_XmlRpcServer_Exception|Exception * Zend_XmlRpcServer_Exceptions are thrown for internal errors; otherwise, * any other exception may be thrown by the callback */ protected function _handle(Zend_XmlRpc_Request $request) { $method = $request->getMethod(); // Check for valid method if (!$this->_table->hasMethod($method)) { require_once 'Zend/XmlRpc/Server/Exception.php'; throw new Zend_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 620); } $info = $this->_table->getMethod($method); $params = $request->getParams(); $argv = $info->getInvokeArguments(); if (0 < count($argv) and $this->sendArgumentsToAllMethods()) { $params = array_merge($params, $argv); } // Check calling parameters against signatures $matched = false; $sigCalled = $request->getTypes(); $sigLength = count($sigCalled); $paramsLen = count($params); if ($sigLength < $paramsLen) { for ($i = $sigLength; $i < $paramsLen; ++$i) { $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($params[$i]); $sigCalled[] = $xmlRpcValue->getType(); } } $signatures = $info->getPrototypes(); foreach ($signatures as $signature) { $sigParams = $signature->getParameters(); if ($sigCalled === $sigParams) { $matched = true; break; } } if (!$matched) { require_once 'Zend/XmlRpc/Server/Exception.php'; throw new Zend_XmlRpc_Server_Exception('Calling parameters do not match signature', 623); } $return = $this->_dispatch($info, $params); $responseClass = $this->getResponseClass(); return new $responseClass($return); }
public function testHandleFunction() { $this->_server->addFunction('Zend_XmlRpc_Server_testFunction'); $request = new Zend_XmlRpc_Request(); $request->setMethod('Zend_XmlRpc_Server_testFunction'); $request->setParams(array(array('value1'), 'key')); $response = $this->_server->handle($request); $this->assertFalse($response instanceof Zend_XmlRpc_Fault); $this->assertEquals('key: value1', $response->getReturnValue()); }
/** * Multicall - boxcar feature of XML-RPC for calling multiple methods * in a single request. * * Expects a an array of structs representing method calls, each element * having the keys: * - methodName * - params * * Returns an array of responses, one for each method called, with the value * returned by the method. If an error occurs for a given method, returns a * struct with a fault response. * * @see http://www.xmlrpc.com/discuss/msgReader$1208 * @param array $methods * @return array */ public function multicall($methods) { $responses = array(); foreach ($methods as $method) { $fault = false; if (!is_array($method)) { $fault = $this->_server->fault('system.multicall expects each method to be a struct', 601); } elseif (!isset($method['methodName'])) { $fault = $this->_server->fault('Missing methodName: ' . var_export($methods, 1), 602); } elseif (!isset($method['params'])) { $fault = $this->_server->fault('Missing params', 603); } elseif (!is_array($method['params'])) { $fault = $this->_server->fault('Params must be an array', 604); } else { if ('system.multicall' == $method['methodName']) { // don't allow recursive calls to multicall $fault = $this->_server->fault('Recursive system.multicall forbidden', 605); } } if (!$fault) { try { $request = new Zend_XmlRpc_Request(); $request->setMethod($method['methodName']); $request->setParams($method['params']); $response = $this->_server->handle($request); if ($response instanceof Zend_XmlRpc_Fault || $response->isFault()) { $fault = $response; } else { $responses[] = $response->getReturnValue(); } } catch (Exception $e) { $fault = $this->_server->fault($e); } } if ($fault) { $responses[] = array('faultCode' => $fault->getCode(), 'faultString' => $fault->getMessage()); } } return $responses; }
/** * Test encoding settings */ public function testSetGetEncoding() { $this->assertEquals('UTF-8', $this->_request->getEncoding()); $this->_request->setEncoding('ISO-8859-1'); $this->assertEquals('ISO-8859-1', $this->_request->getEncoding()); }
/** * Perform an JSON-RPC request and return a response. * * @param Zend_Json_Server_Request $request * @param null|Zend_Json_Client_Response $response * @return void * @throws Zend_Json_Client_HttpException */ public function doRequest($request, $response = null) { $this->_lastRequest = $request; #iconv_set_encoding('input_encoding', 'UTF-8'); #iconv_set_encoding('output_encoding', 'UTF-8'); #iconv_set_encoding('internal_encoding', 'UTF-8'); $http = $this->getHttpClient(); $http->setUri($this->_serverAddress); $http->setHeaders(array('Content-Type: application/json-rpc; charset=utf-8', 'User-Agent: Zend_Json_Client/' . Zend_Version::VERSION, 'Accept: application/json-rpc')); $json = $this->_lastRequest->__toString(); $http->setRawData($json); $httpResponse = $http->request(Zend_Http_Client::POST); if (!$httpResponse->isSuccessful()) { /** * Exception thrown when an HTTP error occurs * @see Zend_XmlRpc_Client_HttpException */ require_once 'Zend/Json/Client/HttpException.php'; throw new Zend_Json_Client_HttpException($httpResponse->getMessage(), $httpResponse->getStatus()); } if ($response === null) { $response = new Zend_Json_Client_Response(); } $this->_lastResponse = $response; $this->_lastResponse->loadJson($httpResponse->getBody()); }
public function testShouldDisallowsDoctypeInRequestXmlAndReturnFalseOnLoading() { $payload = file_get_contents(dirname(__FILE__) . '/_files/ZF12293-request.xml'); $payload = sprintf($payload, 'file://' . realpath(dirname(__FILE__) . '/_files/ZF12293-payload.txt')); $this->assertFalse($this->_request->loadXml($payload)); }
} $r = null; $request = null; $serializer = null; $start = microtime(true); for ($a = 0; $a < $limit; ++$a) { $request = new Zend\XmlRpc\Request(); $request->setMethod('test'); $request->setParams($args); $r = $request->saveXml(); } $end = microtime(true); printf("Zend\\XmlRpc\\Request (ZF2): %s sec for %d passes\n", $end - $start, $limit); $start = microtime(true); for ($a = 0; $a < $limit; ++$a) { $request = new Zend_XmlRpc_Request(); $request->setMethod('test'); $request->setParams($args); $r = $request->saveXml(); } $end = microtime(true); printf("Zend_XmlRpc_Request (ZF1): %s sec for %d passes\n", $end - $start, $limit); $start = microtime(true); for ($a = 0; $a < $limit; ++$a) { $serializer = new fXmlRpc\Serializer\XmlWriterSerializer(); $r = $serializer->serialize('test', $args); } $end = microtime(true); printf("fXmlRpc\\Serializer\\XmlWriterSerializer: %s sec for %d passes\n", $end - $start, $limit); $start = microtime(true); for ($a = 0; $a < $limit; ++$a) {
/** * For XML-RPC - we want to check for enc / sigs * * @return $xml */ protected function modify_payload() { global $HTTP_RAW_POST_DATA; $xml = null; // check for encryption and signatures if ($this->authmethod == WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN) { // we need the token so that we can find the key if (!($dbtoken = get_record('external_tokens', 'token', $this->token, 'tokentype', EXTERNAL_TOKEN_PERMANENT))) { // log failed login attempts throw new WebserviceAccessException(get_string('invalidtoken', 'auth.webservice')); } // is WS-Security active ? if ($dbtoken->wssigenc) { $this->publickey = $dbtoken->publickey; } } else { if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { // get the user $user = get_record('usr', 'username', $this->username); if (empty($user)) { throw new WebserviceAccessException(get_string('wrongusernamepassword', 'auth.webservice')); } // get the institution from the external user $ext_user = get_record('external_services_users', 'userid', $user->id); if (empty($ext_user)) { throw new WebserviceAccessException(get_string('wrongusernamepassword', 'auth.webservice')); } // is WS-Security active ? if ($ext_user->wssigenc) { $this->publickey = $ext_user->publickey; } } } // only both if we can find a public key if (!empty($this->publickey)) { // A singleton provides our site's SSL info require_once get_config('docroot') . 'api/xmlrpc/lib.php'; $HTTP_RAW_POST_DATA = file_get_contents('php://input'); $openssl = OpenSslRepo::singleton(); $payload = $HTTP_RAW_POST_DATA; $this->payload_encrypted = false; $this->payload_signed = false; try { $xml = new SimpleXMLElement($payload); } catch (Exception $e) { throw new XmlrpcServerException('Payload is not a valid XML document', 6001); } // Cascading switch. Kinda. try { if ($xml->getName() == 'encryptedMessage') { $this->payload_encrypted = true; $payload = xmlenc_envelope_strip($xml); } if ($xml->getName() == 'signedMessage') { $this->payload_signed = true; $payload = xmldsig_envelope_strip($xml); } $xml = $payload; } catch (CryptException $e) { if ($e->getCode() == 7025) { // The key they used to contact us is old, respond with the new key correctly // This sucks. Error handling of our mnet code needs to improve ob_start(); xmlrpc_error($e->getMessage(), $e->getCode()); $response = ob_get_contents(); ob_end_clean(); // Sign and encrypt our response, even though we don't know if the // request was signed and encrypted $response = xmldsig_envelope($response); $response = xmlenc_envelope($response, $this->publickey); $xml = $response; } } } // if XML has been grabbed already then it must be turned into a request object if ($xml) { $request = new Zend_XmlRpc_Request(); $request->loadXML($xml); $xml = $request; } return $xml; }
/** * Send an XML-RPC request to the service (for a specific method) * * @param string $method Name of the method we want to call * @param array $params Array of parameters for the method * @param boolean $asResponseObject Return it as a response object instead of PHP native? * @throws Zend_Http_Client_FaultException */ public function call($method, $params = array(), $asResponseObject = false) { $request = new Zend_XmlRpc_Request(); $request->setMethod($method); $request->setParams($params); $this->doRequest($request); if ($asResponseObject) { return $this->_lastResponse; } else { if ($this->_lastResponse->isFault()) { $fault = $this->_lastResponse->getFault(); throw new Zend_XmlRpc_Client_FaultException($fault->getMessage(), $fault->getCode()); } return $this->_lastResponse->getReturnValue(); } }
/** * Perform an XML-RPC request and return a response. * * @param Zend_XmlRpc_Request $request * @param null|Zend_XmlRpc_Response $response * @return void * @throws Zend_XmlRpc_Client_HttpException */ public function doRequest($request, $response = null) { $this->_lastRequest = $request; Zend_EncodingProxy::setOutputEncoding('UTF-8'); Zend_EncodingProxy::setInputEncoding('UTF-8'); Zend_EncodingProxy::setInternalEncoding('UTF-8'); $http = $this->getHttpClient(); if ($http->getUri() === null) { $http->setUri($this->_serverAddress); } $http->setHeaders(array('Content-Type: text/xml; charset=utf-8', 'Accept: text/xml')); if ($http->getHeader('user-agent') === null) { $http->setHeaders(array('User-Agent: Zend_XmlRpc_Client')); } $xml = $this->_lastRequest->__toString(); $http->setRawData($xml); $httpResponse = $http->request(Zend_Http_Client::POST); if (!$httpResponse->isSuccessful()) { /** * Exception thrown when an HTTP error occurs * @see Zend_XmlRpc_Client_HttpException */ // require_once 'Zend/XmlRpc/Client/HttpException.php'; throw new Zend_XmlRpc_Client_HttpException($httpResponse->getMessage(), $httpResponse->getStatus()); } if ($response === null) { $response = new Zend_XmlRpc_Response(); } $this->_lastResponse = $response; $this->_lastResponse->loadXml(trim($httpResponse->getBody())); }
/** * multicall() test * * Call as method call * * Expects: * - methods: * * Returns: array */ public function testMulticall() { $struct = array(array('methodName' => 'system.listMethods', 'params' => array()), array('methodName' => 'system.methodHelp', 'params' => array('system.multicall'))); $request = new Zend_XmlRpc_Request(); $request->setMethod('system.multicall'); $request->addParam($struct); $response = $this->_server->handle($request); $this->assertTrue($response instanceof Zend_XmlRpc_Response, $response->__toString()); $returns = $response->getReturnValue(); $this->assertTrue(is_array($returns)); $this->assertEquals(2, count($returns)); $this->assertTrue(is_array($returns[0]), var_export($returns[0], 1)); $this->assertTrue(is_string($returns[1]), var_export($returns[1], 1)); }