summaryrefslogtreecommitdiff
path: root/www/wiki/includes/libs/http/HttpAcceptParser.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/includes/libs/http/HttpAcceptParser.php')
-rw-r--r--www/wiki/includes/libs/http/HttpAcceptParser.php78
1 files changed, 78 insertions, 0 deletions
diff --git a/www/wiki/includes/libs/http/HttpAcceptParser.php b/www/wiki/includes/libs/http/HttpAcceptParser.php
new file mode 100644
index 00000000..df22b414
--- /dev/null
+++ b/www/wiki/includes/libs/http/HttpAcceptParser.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * Utility for parsing a HTTP Accept header value into a weight map. May also be used with
+ * other, similar headers like Accept-Language, Accept-Encoding, etc.
+ *
+ * @license GPL-2.0-or-later
+ * @author Daniel Kinzler
+ */
+
+namespace Wikimedia\Http;
+
+class HttpAcceptParser {
+
+ /**
+ * Parses an HTTP header into a weight map, that is an associative array
+ * mapping values to their respective weights. Any header name preceding
+ * weight spec is ignored for convenience.
+ *
+ * This implementation is partially based on the code at
+ * http://www.thefutureoftheweb.com/blog/use-accept-language-header
+ *
+ * Note that type parameters and accept extension like the "level" parameter
+ * are not supported, weights are derived from "q" values only.
+ *
+ * @todo: If additional type parameters are present, ignore them cleanly.
+ * At present, they often confuse the result.
+ *
+ * See HTTP/1.1 section 14 for details.
+ *
+ * @param string $rawHeader
+ *
+ * @return array
+ */
+ public function parseWeights( $rawHeader ) {
+ //FIXME: The code below was copied and adapted from WebRequest::getAcceptLang.
+ // Move this utility class into core for reuse!
+
+ // first, strip header name
+ $rawHeader = preg_replace( '/^[-\w]+:\s*/', '', $rawHeader );
+
+ // Return values in lower case
+ $rawHeader = strtolower( $rawHeader );
+
+ // Break up string into pieces (values and q factors)
+ $value_parse = null;
+ preg_match_all( '@([a-z\d*]+([-+/.][a-z\d*]+)*)\s*(;\s*q\s*=\s*(1(\.0{0,3})?|0(\.\d{0,3})?)?)?@',
+ $rawHeader, $value_parse );
+
+ if ( !count( $value_parse[1] ) ) {
+ return [];
+ }
+
+ $values = $value_parse[1];
+ $qvalues = $value_parse[4];
+ $indices = range( 0, count( $value_parse[1] ) - 1 );
+
+ // Set default q factor to 1
+ foreach ( $indices as $index ) {
+ if ( $qvalues[$index] === '' ) {
+ $qvalues[$index] = 1;
+ } elseif ( $qvalues[$index] == 0 ) {
+ unset( $values[$index], $qvalues[$index], $indices[$index] );
+ } else {
+ $qvalues[$index] = (float)$qvalues[$index];
+ }
+ }
+
+ // Sort list. First by $qvalues, then by order. Reorder $values the same way
+ array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $values );
+
+ // Create a list like "en" => 0.8
+ $weights = array_combine( $values, $qvalues );
+
+ return $weights;
+ }
+
+}