* 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
245 lines
4.7 KiB
PHP
245 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Rest;
|
|
|
|
use MediaWiki\Rest\ConditionalHeaderUtil;
|
|
use MediaWiki\Rest\RequestData;
|
|
use MediaWiki\Rest\Response;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Rest\ConditionalHeaderUtil
|
|
*/
|
|
class ConditionalHeaderUtilTest extends \MediaWikiUnitTestCase {
|
|
public static function provider() {
|
|
return [
|
|
'nothing' => [
|
|
'GET',
|
|
null,
|
|
null,
|
|
null,
|
|
[],
|
|
null,
|
|
[]
|
|
],
|
|
'inm true' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-None-Match' => '"b"' ],
|
|
null,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'inm false' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-None-Match' => '"a"' ],
|
|
304,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'ims true' => [
|
|
'GET',
|
|
null,
|
|
'Mon, 14 Oct 2019 00:00:01 GMT',
|
|
null,
|
|
[ 'If-Modified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
null,
|
|
[ 'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:01 GMT' ] ]
|
|
],
|
|
'ims false' => [
|
|
'GET',
|
|
null,
|
|
'Mon, 14 Oct 2019 00:00:00 GMT',
|
|
null,
|
|
[ 'If-Modified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
304,
|
|
[ 'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:00 GMT' ] ]
|
|
],
|
|
'im true' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-Match' => '"a"' ],
|
|
null,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'im false' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-Match' => '"b"' ],
|
|
412,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'ius true' => [
|
|
'GET',
|
|
null,
|
|
'Mon, 14 Oct 2019 00:00:00 GMT',
|
|
null,
|
|
[ 'If-Unmodified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
null,
|
|
[ 'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:00 GMT' ] ]
|
|
],
|
|
'ius false' => [
|
|
'GET',
|
|
null,
|
|
'Mon, 14 Oct 2019 00:00:01 GMT',
|
|
null,
|
|
[ 'If-Unmodified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
412,
|
|
[ 'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:01 GMT' ] ]
|
|
],
|
|
'im true, ius false' => [
|
|
'GET',
|
|
'"a"',
|
|
'Mon, 14 Oct 2019 00:00:01 GMT',
|
|
null,
|
|
[
|
|
'If-Match' => '"a"',
|
|
'If-Unmodified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT'
|
|
],
|
|
null,
|
|
[
|
|
'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:01 GMT' ],
|
|
'ETag' => [ '"a"' ]
|
|
]
|
|
],
|
|
'inm true, ims false' => [
|
|
'GET',
|
|
'"a"',
|
|
'Mon, 14 Oct 2019 00:00:00 GMT',
|
|
null,
|
|
[
|
|
'If-None-Match' => '"b"',
|
|
'If-Modified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT'
|
|
],
|
|
null,
|
|
[
|
|
'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
'ETag' => [ '"a"' ]
|
|
]
|
|
],
|
|
'im true, inm false' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[
|
|
'If-Match' => '"a"',
|
|
'If-None-Match' => '"a"'
|
|
],
|
|
304,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'ius true, inm false' => [
|
|
'GET',
|
|
'"a"',
|
|
'Mon, 14 Oct 2019 00:00:00 GMT',
|
|
null,
|
|
[
|
|
'If-Unmodified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT',
|
|
'If-None-Match' => '"a"'
|
|
],
|
|
304,
|
|
[
|
|
'Last-Modified' => [ 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
'ETag' => [ '"a"' ]
|
|
]
|
|
],
|
|
'im star true' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
true,
|
|
[ 'If-Match' => '*' ],
|
|
null,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'im star false' => [
|
|
'GET',
|
|
null,
|
|
null,
|
|
false,
|
|
[ 'If-Match' => '*' ],
|
|
412,
|
|
[]
|
|
],
|
|
'inm false post' => [
|
|
'POST',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-None-Match' => '"a"' ],
|
|
412,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'im multiple true' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-Match' => '"b", "a"' ],
|
|
null,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'im multiple false' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-Match' => '"b", "c"' ],
|
|
412,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'im weak' => [
|
|
'GET',
|
|
'"a"',
|
|
null,
|
|
null,
|
|
[ 'If-Match' => 'W/"a"' ],
|
|
412,
|
|
[ 'ETag' => [ '"a"' ] ]
|
|
],
|
|
'ims with resource unknown' => [
|
|
'GET',
|
|
null,
|
|
null,
|
|
null,
|
|
[ 'If-Modified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
null,
|
|
[]
|
|
],
|
|
'ius with resource unknown' => [
|
|
'GET',
|
|
null,
|
|
null,
|
|
null,
|
|
[ 'If-Unmodified-Since' => 'Mon, 14 Oct 2019 00:00:00 GMT' ],
|
|
412,
|
|
[]
|
|
],
|
|
];
|
|
}
|
|
|
|
/** @dataProvider provider */
|
|
public function testConditionalHeaderUtil( $method, $eTag, $lastModified, $hasRepresentation,
|
|
$requestHeaders, $expectedStatus, $expectedResponseHeaders
|
|
) {
|
|
$util = new ConditionalHeaderUtil;
|
|
$util->setValidators( $eTag, $lastModified, $hasRepresentation );
|
|
$request = new RequestData( [
|
|
'method' => $method,
|
|
'headers' => $requestHeaders
|
|
] );
|
|
$status = $util->checkPreconditions( $request );
|
|
$this->assertSame( $expectedStatus, $status );
|
|
|
|
$response = new Response;
|
|
$util->applyResponseHeaders( $response );
|
|
$this->assertSame( $expectedResponseHeaders, $response->getHeaders() );
|
|
}
|
|
}
|