aboutsummaryrefslogtreecommitdiffstats
path: root/src/XmlRpcMethod.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/XmlRpcMethod.php')
-rw-r--r--src/XmlRpcMethod.php63
1 files changed, 43 insertions, 20 deletions
diff --git a/src/XmlRpcMethod.php b/src/XmlRpcMethod.php
index 2167e53..001169b 100644
--- a/src/XmlRpcMethod.php
+++ b/src/XmlRpcMethod.php
@@ -7,6 +7,8 @@
namespace VolseNet\Webtrap;
+use XMLReader;
+
/**
* A representation of an XML-RPC method call.
*
@@ -24,34 +26,41 @@ class XmlRpcMethod
*
* @param string $payload The raw XML representation of the method call.
*
- * @return XmlRpcMethod
+ * @return XmlRpcMethod|null
*/
- public static function parse(string $payload): self
+ public static function parse(string $payload): self|null
{
- $parser = xml_parser_create();
- xml_parse_into_struct($parser, $payload, $elements, $index);
- xml_parser_free($parser);
+ $errorflag = libxml_use_internal_errors(true);
- $in_param = false;
- $method_name = null;
+ $xml = XMLReader::XML($payload);
- foreach ($elements as $e) {
- switch ($e['tag']) {
- case 'METHODNAME':
- $method_name = $e['value'];
- break;
+ $method_name = null;
+ $params = [];
+ $expect = null;
- case 'PARAM':
- if ($e['type'] === 'open') {
- $in_param = true;
+ while ($xml->read()) {
+ $tag = strtolower($xml->name);
+ switch ($tag) {
+ case 'methodname':
+ case 'value':
+ if ($xml->nodeType === XMLReader::ELEMENT) {
+ $expect = $tag;
} else {
- $in_param = false;
+ $expect = null;
}
break;
- case 'VALUE':
- if ($in_param) {
- $params[] = $e['value'];
+ case '#text':
+ if ($xml->hasValue) {
+ switch ($expect) {
+ case 'methodname':
+ $method_name = $xml->value;
+ break;
+
+ case 'value':
+ $params[] = $xml->value;
+ break;
+ }
}
break;
@@ -60,7 +69,21 @@ class XmlRpcMethod
}
}
- return new XmlRpcMethod($method_name, $params);
+ $errors = libxml_get_errors();
+ libxml_use_internal_errors($errorflag);
+
+ if (! empty($errors)) {
+ throw new \RuntimeException(
+ 'errors while parsing XML',
+ $errors[0]->code
+ );
+ }
+
+ if (! empty($method_name)) {
+ return new XmlRpcMethod($method_name, $params);
+ }
+
+ return null;
}
/**