* Added ConditionalHeaderUtil, a conditional request helper class meant for composition into Handler. I evaluated the composer package micheh/psr7-cache for this role but I decided that I prefer DIY code rather than some rather ugly glue. * Check conditional request headers prior to entry into Handler::execute(). Contrary to what was previously documented, use the results of getLastModified() and getETag() to set headers in the response. This is convenient and can be overridden in the Handler if desired by overriding a one-line function. * Instead of locking up header parsing inside ConditionalHeaderUtil as was done in micheh/psr7-cache, make a start on a new reusable header parsing framework, with recursive descent parsers for HTTP-date and IfNoneMatch. Change-Id: I260809081cad7701df8620ab03834158670d4230
113 lines
2.3 KiB
PHP
113 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Rest\HeaderParser;
|
|
|
|
use MediaWiki\Rest\HeaderParser\IfNoneMatch;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\HeaderParser\IfNoneMatch
|
|
*/
|
|
class IfNoneMatchTest extends \MediaWikiUnitTestCase {
|
|
public static function provideParseHeaderList() {
|
|
return [
|
|
'empty array' => [
|
|
[],
|
|
[]
|
|
],
|
|
'star' => [
|
|
[ '*' ],
|
|
[ [ 'weak' => true, 'contents' => null, 'whole' => '*' ] ]
|
|
],
|
|
'etag' => [
|
|
[ '"x"' ],
|
|
[ [ 'weak' => false, 'contents' => 'x', 'whole' => '"x"' ] ]
|
|
],
|
|
'star etag' => [
|
|
[ '*, "x"' ],
|
|
[]
|
|
],
|
|
'etag star' => [
|
|
[ '"x", *' ],
|
|
[]
|
|
],
|
|
'two in a string' => [
|
|
[ '"x","y"' ],
|
|
[
|
|
[ 'weak' => false, 'contents' => 'x', 'whole' => '"x"' ],
|
|
[ 'weak' => false, 'contents' => 'y', 'whole' => '"y"' ]
|
|
]
|
|
],
|
|
'two with whitespace' => [
|
|
[ "\"x\"\t, \"y\"" ],
|
|
[
|
|
[ 'weak' => false, 'contents' => 'x', 'whole' => '"x"' ],
|
|
[ 'weak' => false, 'contents' => 'y', 'whole' => '"y"' ]
|
|
]
|
|
],
|
|
'two separate headers' => [
|
|
[ '"x"', '"y"' ],
|
|
[
|
|
[ 'weak' => false, 'contents' => 'x', 'whole' => '"x"' ],
|
|
[ 'weak' => false, 'contents' => 'y', 'whole' => '"y"' ]
|
|
]
|
|
],
|
|
'trailing comma' => [
|
|
[ '"x",' ],
|
|
[]
|
|
],
|
|
'trailing garbage' => [
|
|
[ '"x",asdfg' ],
|
|
[]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideParseHeaderList
|
|
* @param array $input
|
|
* @param array $expected
|
|
*/
|
|
public function testParseHeaderList( $input, $expected ) {
|
|
$parser = new IfNoneMatch;
|
|
$actual = $parser->parseHeaderList( $input );
|
|
$this->assertSame( $expected, $actual );
|
|
}
|
|
|
|
public static function provideParseETag() {
|
|
return [
|
|
'empty' => [
|
|
'',
|
|
null
|
|
],
|
|
'strong' => [
|
|
'"x"',
|
|
[ 'weak' => false, 'contents' => 'x', 'whole' => '"x"' ]
|
|
],
|
|
'weak' => [
|
|
'W/"x"',
|
|
[ 'weak' => true, 'contents' => 'x', 'whole' => 'W/"x"' ]
|
|
],
|
|
'weak with lowercase w' => [
|
|
'w/"x"',
|
|
null
|
|
],
|
|
'quoted character outside valid range' => [
|
|
'" "',
|
|
null
|
|
],
|
|
'trailing garbage' => [
|
|
'"x"a',
|
|
null
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideParseETag
|
|
*/
|
|
public function testParseETag( $input, $expected ) {
|
|
$parser = new IfNoneMatch;
|
|
$actual = $parser->parseETag( $input );
|
|
$this->assertSame( $expected, $actual );
|
|
}
|
|
}
|