wiki.techinc.nl/tests/phpunit/unit/includes/Rest/ConditionalHeaderUtilTest.php
Jakob Warkotsch 64ddedb63d ConditionalHeaderUtil: Handle If-None-Match: *
The relevant section in the RFC says the following:

> If the field-value is "*", the condition is false if the origin
> server has a current representation for the target resource.
> An origin server that evaluates an If-None-Match condition MUST NOT
> perform the requested method if the condition evaluates to false;
> instead, the origin server MUST respond with either a) the 304 (Not
> Modified) status code if the request method is GET or HEAD or b) the
> 412 (Precondition Failed) status code for all other request methods.

https://httpwg.org/specs/rfc9110.html

Bug: T319382
Change-Id: Ieb3269d61de42242602ec9c46e19c4f2c3b37f6e
2022-10-07 09:06:04 +00:00

286 lines
5.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"' ] ]
],
// A strong ETag returned by the server may have been "weakened" by
// a proxy or middleware, e.g. when applying compression and setting
// content-encoding (rather than transfer-encoding). We want to still accept
// such ETags, even though that's against the HTTP spec (T238849).
// See ConditionalHeaderUtil::setVarnishETagHack.
'If-Match weak vs strong' => [
'GET',
'"a"',
null,
null,
[ 'If-Match' => 'W/"a"' ],
null,
[ 'ETag' => [ '"a"' ] ]
],
'If-Match strong vs weak' => [
'GET',
'W/"a"',
null,
null,
[ 'If-Match' => '"a"' ],
412,
[ 'ETag' => [ 'W/"a"' ] ]
],
'If-Match weak vs weak' => [
'GET',
'W/"a"',
null,
null,
[ 'If-Match' => 'W/"a"' ],
412,
[ 'ETag' => [ 'W/"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,
[]
],
'If-None-Match wildcard GET request, resource has representation' => [
'GET',
null,
null,
true,
[ 'If-None-Match' => '*' ],
304,
[]
],
'If-None-Match wildcard non-GET request, resource has representation' => [
'POST',
null,
null,
true,
[ 'If-None-Match' => '*' ],
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() );
}
}