From 40497185bbd9be8c371581e0c25b4da71ad00741 Mon Sep 17 00:00:00 2001 From: gggeek Date: Wed, 18 Jan 2023 08:21:39 +0000 Subject: [PATCH] refactoring --- src/Client.php | 11 +++-------- src/Helper/Charset.php | 17 +++++++++++++++++ src/Helper/Http.php | 25 ++++++++++++++++++++++++- src/Server.php | 29 ++++++----------------------- 4 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/Client.php b/src/Client.php index bfeefe22..24b4deb0 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,6 +2,7 @@ namespace PhpXmlRpc; +use PhpXmlRpc\Helper\Charset; use PhpXmlRpc\Helper\Logger; use PhpXmlRpc\Helper\XMLParser; @@ -235,15 +236,9 @@ class Client // by default the xml parser can support these 3 charset encodings $this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII'); - // Add all charsets which mbstring can handle, but remove junk not found in IANA registry at - // http://www.iana.org/assignments/character-sets/character-sets.xhtml // NB: this is disabled to avoid making all the requests sent huge... mbstring supports more than 80 charsets! - /*if (function_exists('mb_list_encodings')) { - - $encodings = array_diff(mb_list_encodings(), array('pass', 'auto', 'wchar', 'BASE64', 'UUENCODE', 'ASCII', - 'HTML-ENTITIES', 'Quoted-Printable', '7bit','8bit', 'byte2be', 'byte2le', 'byte4be', 'byte4le')); - $this->accepted_charset_encodings = array_unique(array_merge($this->accepted_charset_encodings, $encodings)); - }*/ + //$ch = Charset::instance(); + //$this->accepted_charset_encodings = $ch->knownCharsets(); // initialize user_agent string $this->user_agent = PhpXmlRpc::$xmlrpcName . ' ' . PhpXmlRpc::$xmlrpcVersion; diff --git a/src/Helper/Charset.php b/src/Helper/Charset.php index 41d30840..c4bbdf33 100644 --- a/src/Helper/Charset.php +++ b/src/Helper/Charset.php @@ -329,6 +329,23 @@ class Charset return $escapedData; } + /** + * @return string[] + */ + public function knownCharsets() + { + $knownCharsets = array('UTF-8', 'ISO-8859-1', 'US-ASCII'); + // Add all charsets which mbstring can handle, but remove junk not found in IANA registry at + // http://www.iana.org/assignments/character-sets/character-sets.xhtml + if (function_exists('mb_list_encodings')) { + $knownCharsets = array_unique(array_merge($knownCharsets, array_diff(mb_list_encodings(), array( + 'pass', 'auto', 'wchar', 'BASE64', 'UUENCODE', 'ASCII', 'HTML-ENTITIES', 'Quoted-Printable', + '7bit','8bit', 'byte2be', 'byte2le', 'byte4be', 'byte4le' + )))); + } + return $knownCharsets; + } + /** * Checks if a given charset encoding is present in a list of encodings or if it is a valid subset of any encoding * in the list. diff --git a/src/Helper/Http.php b/src/Helper/Http.php index eb024cf3..3cec1493 100644 --- a/src/Helper/Http.php +++ b/src/Helper/Http.php @@ -7,7 +7,6 @@ use PhpXmlRpc\PhpXmlRpc; /** * - * @todo allow usage of a custom Logger via the DIC(ish) pattern we use in other classes */ class Http { @@ -283,4 +282,28 @@ class Http return $httpResponse; } + + /** + * Parses one of the http headers which can have a list of values with quality param. + * @see https://www.rfc-editor.org/rfc/rfc7231#section-5.3.1 + * + * @param string $header + * @return string[] + */ + public function parseAcceptHeader($header) + { + $accepted = array(); + foreach(explode(',', $header) as $c) { + if (preg_match('/^([^;]+); *q=([0-9.]+)/', $c, $matches)) { + $c = $matches[1]; + $w = $matches[2]; + } else { + $c = preg_replace('/;.*/', '', $c); + $w = 1; + } + $accepted[(trim($c))] = $w; + } + arsort($accepted); + return array_keys($accepted); + } } diff --git a/src/Server.php b/src/Server.php index c23661cf..780174de 100644 --- a/src/Server.php +++ b/src/Server.php @@ -4,6 +4,7 @@ namespace PhpXmlRpc; use PhpXmlRpc\Exception\PhpXmlrpcException; use PhpXmlRpc\Helper\Charset; +use PhpXmlRpc\Helper\Http; use PhpXmlRpc\Helper\Logger; use PhpXmlRpc\Helper\XMLParser; @@ -526,36 +527,18 @@ class Server } } - // check if client specified accepted charsets, and if we know how to fulfill - // the request + // check if client specified accepted charsets, and if we know how to fulfill the request if ($this->response_charset_encoding == 'auto') { $respEncoding = ''; if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) { // here we check if we can match the client-requested encoding with the encodings we know we can generate. // we parse q=0.x preferences instead of preferring the first charset specified - $clientAcceptedCharsets = array(); - foreach(explode(',', strtoupper($_SERVER['HTTP_ACCEPT_CHARSET'])) as $c) { - if (preg_match('/^([^;]+);Q=([0-9.]+)/', $c, $matches)) { - $c = $matches[1]; - $w = $matches[2]; - } else { - $c = preg_replace('/;.*/', '', $c); - $w = 1; - } - $clientAcceptedCharsets[(trim($c))] = $w; - } - arsort($clientAcceptedCharsets); - $clientAcceptedCharsets = array_keys($clientAcceptedCharsets); - - $knownCharsets = array('UTF-8', 'ISO-8859-1', 'US-ASCII'); - // if mbstring is enabled, we can support other charsets too! - /// @todo add a method to the Charset helper to retrieve this list (and remove from it junk entries) - if (function_exists('mb_list_encodings')) { - $knownCharsets = array_unique(array_merge($knownCharsets, mb_list_encodings())); - } + $http = new Http(); + $clientAcceptedCharsets = $http->parseAcceptHeader($_SERVER['HTTP_ACCEPT_CHARSET']); + $knownCharsets = $this->getCharsetEncoder()->knownCharsets(); foreach ($clientAcceptedCharsets as $accepted) { foreach ($knownCharsets as $charset) { - if ($accepted == strtoupper($charset)) { + if (strtoupper($accepted) == strtoupper($charset)) { $respEncoding = $charset; break 2; } -- 2.47.0