Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1431351
HttpAcceptParser.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
HttpAcceptParser.php
View Options
<?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
{
/**
* Parse media types from an Accept header and sort them by q-factor.
*
* Note that his was mostly ported from,
* https://github.com/arlolra/negotiator/blob/full-parse-access/lib/mediaType.js
*
* @param string $accept
* @return array[]
* - type: (string)
* - subtype: (string)
* - q: (float) q-factor weighting
* - i: (int) index
* - params: (array)
*/
public
function
parseAccept
(
$accept
):
array
{
$accepts
=
explode
(
','
,
$accept
);
// FIXME: Allow commas in quotes
$ret
=
[];
foreach
(
$accepts
as
$i
=>
$a
)
{
if
(
!
preg_match
(
'!^([^
\s
/;]+)/([^;
\s
]+)
\s
*(?:;(.*))?$!D'
,
trim
(
$a
),
$matches
)
)
{
continue
;
}
$q
=
1
;
$params
=
[];
if
(
isset
(
$matches
[
3
]
)
)
{
$kvps
=
explode
(
';'
,
$matches
[
3
]
);
// FIXME: Allow semi-colon in quotes
foreach
(
$kvps
as
$kv
)
{
[
$key
,
$val
]
=
explode
(
'='
,
trim
(
$kv
),
2
);
$key
=
strtolower
(
trim
(
$key
)
);
$val
=
trim
(
$val
);
if
(
$key
===
'q'
)
{
$q
=
(
float
)
$val
;
// FIXME: Spec is stricter about this
}
else
{
if
(
$val
&&
$val
[
0
]
===
'"'
&&
$val
[
strlen
(
$val
)
-
1
]
===
'"'
)
{
$val
=
substr
(
$val
,
1
,
strlen
(
$val
)
-
2
);
}
$params
[
$key
]
=
$val
;
}
}
}
$ret
[]
=
[
'type'
=>
$matches
[
1
],
'subtype'
=>
$matches
[
2
],
'q'
=>
$q
,
'i'
=>
$i
,
'params'
=>
$params
,
];
}
// Sort list. First by q values, then by order
usort
(
$ret
,
static
function
(
$a
,
$b
)
{
if
(
$b
[
'q'
]
>
$a
[
'q'
]
)
{
return
1
;
}
elseif
(
$b
[
'q'
]
===
$a
[
'q'
]
)
{
return
$a
[
'i'
]
-
$b
[
'i'
];
}
else
{
return
-
1
;
}
}
);
return
$ret
;
}
/**
* 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.
*
* Note that type parameters and accept extension like the "level" parameter
* are not supported, weights are derived from "q" values only.
*
* See RFC 7231 section 5.3.2 for details.
*
* @param string $rawHeader
*
* @return array
*/
public
function
parseWeights
(
$rawHeader
)
{
// first, strip header name
$rawHeader
=
preg_replace
(
'/^[-
\w
]+:
\s
*/'
,
''
,
$rawHeader
);
// Return values in lower case
$rawHeader
=
strtolower
(
$rawHeader
);
$accepts
=
$this
->
parseAccept
(
$rawHeader
);
// Create a list like "en" => 0.8
return
array_reduce
(
$accepts
,
static
function
(
$prev
,
$next
)
{
$type
=
"{$next['type']}/{$next['subtype']}"
;
$prev
[
$type
]
=
$next
[
'q'
];
return
$prev
;
},
[]
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 20:22 (1 d, 3 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
14/66/0c224d904f7fb95e063dcffdca43
Default Alt Text
HttpAcceptParser.php (2 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment