mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-03 16:51:40 +09:00
Add XMLRPCParser class to parse XE-compatible XML requests
This commit is contained in:
parent
84b7e9f8eb
commit
9fdcd86f1d
2 changed files with 109 additions and 71 deletions
|
|
@ -1158,38 +1158,39 @@ class Context
|
|||
self::$_instance->request_method = $_SERVER['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
// Check POST data
|
||||
if(self::$_instance->request_method === 'POST')
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST')
|
||||
{
|
||||
// Set HTTP_RAW_POST_DATA for compatibility with XE third-party programs.
|
||||
if(!isset($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
// Set variables for XE compatibility.
|
||||
if (isset($_POST['_rx_ajax_compat']) && in_array($_POST['_rx_ajax_compat'], array('JSON', 'XMLRPC')))
|
||||
{
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input");
|
||||
}
|
||||
|
||||
// Pretend that this request is XMLRPC for compatibility with XE third-party.
|
||||
if(isset($_POST['_rx_ajax_compat']) && $_POST['_rx_ajax_compat'] === 'XMLRPC')
|
||||
{
|
||||
self::$_instance->request_method = 'XMLRPC';
|
||||
self::$_instance->request_method = $_POST['_rx_ajax_compat'];
|
||||
return;
|
||||
}
|
||||
|
||||
// Check JSON
|
||||
foreach(array($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_CONTENT_TYPE'], $_SERVER['CONTENT_TYPE']) as $header)
|
||||
else
|
||||
{
|
||||
if(strpos($header, 'json') !== false)
|
||||
// Set HTTP_RAW_POST_DATA for third-party apps that look for it.
|
||||
if (!$_POST && !isset($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = 'JSON';
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
// Check the Content-Type header for a hint of JSON.
|
||||
foreach (array('HTTP_ACCEPT', 'HTTP_CONTENT_TYPE', 'CONTENT_TYPE') as $header)
|
||||
{
|
||||
if (isset($_SERVER[$header]) && strpos($_SERVER[$header], 'json') !== false)
|
||||
{
|
||||
self::$_instance->request_method = 'JSON';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide whether it's JSON or XMLRPC by looking at the first character of the POST data.
|
||||
if (!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = substr($GLOBALS['HTTP_RAW_POST_DATA'], 0, 1) === '<' ? 'XMLRPC' : 'JSON';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check XMLRPC
|
||||
if(!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = 'XMLRPC';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1201,6 +1202,7 @@ class Context
|
|||
*/
|
||||
public static function setRequestArguments(array $router_args = [])
|
||||
{
|
||||
// Arguments detected by the router have precedence over GET/POST parameters.
|
||||
$request_args = $_SERVER['REQUEST_METHOD'] === 'GET' ? $_GET : $_POST;
|
||||
if (count($router_args))
|
||||
{
|
||||
|
|
@ -1210,72 +1212,53 @@ class Context
|
|||
}
|
||||
}
|
||||
|
||||
foreach($request_args as $key => $val)
|
||||
{
|
||||
if($val === '' || isset(self::$_reserved_keys[$key]) || self::get($key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
self::set($key, $val, true);
|
||||
}
|
||||
|
||||
// Set deprecated request parameters.
|
||||
// Set JSON and XMLRPC arguments.
|
||||
if($_SERVER['REQUEST_METHOD'] === 'POST' && !$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
if(self::getRequestMethod() === 'XMLRPC')
|
||||
$params = array();
|
||||
$request_method = self::getRequestMethod();
|
||||
if($request_method === 'XMLRPC')
|
||||
{
|
||||
if(!Rhymix\Framework\Security::checkXXE($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
header("HTTP/1.0 400 Bad Request");
|
||||
exit;
|
||||
}
|
||||
if(function_exists('libxml_disable_entity_loader'))
|
||||
{
|
||||
libxml_disable_entity_loader(true);
|
||||
}
|
||||
|
||||
$oXml = new XmlParser();
|
||||
$params = $oXml->parse($GLOBALS['HTTP_RAW_POST_DATA'])->methodcall->params;
|
||||
unset($params->node_name, $params->attrs, $params->body);
|
||||
|
||||
foreach((array)$params as $key => $val)
|
||||
{
|
||||
if (isset($request_args[$key]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$key = escape($key);
|
||||
$val = self::_filterXmlVars($key, $val);
|
||||
self::set($key, $val, true);
|
||||
self::$_instance->security_check = 'DENY ALL';
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = '';
|
||||
return;
|
||||
}
|
||||
libxml_disable_entity_loader(true);
|
||||
$params = Rhymix\Framework\Parsers\XMLRPCParser::parse($GLOBALS['HTTP_RAW_POST_DATA']);
|
||||
}
|
||||
elseif(self::getRequestMethod() === 'JSON')
|
||||
elseif($request_method === 'JSON')
|
||||
{
|
||||
if(substr($GLOBALS['HTTP_RAW_POST_DATA'], 0, 1) === '{' && substr($GLOBALS['HTTP_RAW_POST_DATA'], -1, 1) === '}')
|
||||
if(substr($GLOBALS['HTTP_RAW_POST_DATA'], 0, 1) === '{')
|
||||
{
|
||||
$params = json_decode($GLOBALS['HTTP_RAW_POST_DATA']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$params = array();
|
||||
parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
|
||||
}
|
||||
|
||||
foreach($params as $key => $val)
|
||||
}
|
||||
|
||||
foreach($params as $key => $val)
|
||||
{
|
||||
if ($val !== '' && !isset($request_args[$key]))
|
||||
{
|
||||
if (isset($request_args[$key]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
self::set($key, $val, true);
|
||||
$request_args[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter all arguments and set them to Context.
|
||||
foreach($request_args as $key => $val)
|
||||
{
|
||||
if($val !== '' && !isset(self::$_reserved_keys[$key]) && !self::get($key))
|
||||
{
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
self::set($key, $val, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1588,7 +1571,7 @@ class Context
|
|||
}
|
||||
}
|
||||
|
||||
if (in_array(Context::getRequestMethod(), array('XMLRPC', 'JSON', 'JS_CALLBACK')))
|
||||
if (in_array(self::getRequestMethod(), array('XMLRPC', 'JSON', 'JS_CALLBACK')))
|
||||
{
|
||||
$oMessageObject->setMessage(trim($title . "\n\n" . $message));
|
||||
}
|
||||
|
|
|
|||
55
common/framework/parsers/xmlrpcparser.php
Normal file
55
common/framework/parsers/xmlrpcparser.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers;
|
||||
|
||||
/**
|
||||
* XMLRPC request parser class for XE compatibility.
|
||||
*/
|
||||
class XMLRPCParser
|
||||
{
|
||||
/**
|
||||
* Load an XML file.
|
||||
*
|
||||
* @param string $content
|
||||
* @return object|false
|
||||
*/
|
||||
public static function parse(string $content)
|
||||
{
|
||||
// Load the XML content.
|
||||
$xml = simplexml_load_string($content);
|
||||
if ($xml === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop over the list of parameters.
|
||||
$result = self::_parseArray($xml->params);
|
||||
|
||||
// Return the complete result.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an array of parameters.
|
||||
*
|
||||
* @param \SimpleXMLElement $parent
|
||||
* @return array
|
||||
*/
|
||||
protected static function _parseArray(\SimpleXMLElement $parent): array
|
||||
{
|
||||
$result = array();
|
||||
foreach ($parent->children() ?: [] as $tag)
|
||||
{
|
||||
$key = $tag->getName();
|
||||
if (strval($tag['type']) === 'array')
|
||||
{
|
||||
$result[$key] = self::_parseArray($tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result[$key] = strval($tag);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue