Browse Source
Move the notmodified check to middleware where it belongs
Move the notmodified check to middleware where it belongs
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>pull/20939/head
No known key found for this signature in database
GPG Key ID: F941078878347C0C
9 changed files with 169 additions and 61 deletions
-
1lib/composer/composer/autoload_classmap.php
-
1lib/composer/composer/autoload_static.php
-
2lib/private/AppFramework/DependencyInjection/DIContainer.php
-
19lib/private/AppFramework/Http.php
-
3lib/private/AppFramework/Http/Dispatcher.php
-
56lib/private/AppFramework/Middleware/NotModifiedMiddleware.php
-
10tests/lib/AppFramework/Http/DispatcherTest.php
-
32tests/lib/AppFramework/Http/HttpTest.php
-
106tests/lib/AppFramework/Middleware/NotModifiedMiddlewareTest.php
@ -0,0 +1,56 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
/** |
||||
|
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> |
||||
|
* |
||||
|
* @author Roeland Jago Douma <roeland@famdouma.nl> |
||||
|
* |
||||
|
* @license GNU AGPL version 3 or any later version |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify |
||||
|
* it under the terms of the GNU Affero General Public License as |
||||
|
* published by the Free Software Foundation, either version 3 of the |
||||
|
* License, or (at your option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
* GNU Affero General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Affero General Public License |
||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
namespace OC\AppFramework\Middleware; |
||||
|
|
||||
|
use OCP\AppFramework\Http; |
||||
|
use OCP\AppFramework\Http\Response; |
||||
|
use OCP\AppFramework\Middleware; |
||||
|
use OCP\IRequest; |
||||
|
|
||||
|
class NotModifiedMiddleware extends Middleware { |
||||
|
/** @var IRequest */ |
||||
|
private $request; |
||||
|
|
||||
|
public function __construct(IRequest $request) { |
||||
|
$this->request = $request; |
||||
|
} |
||||
|
|
||||
|
public function afterController($controller, $methodName, Response $response) { |
||||
|
$etagHeader = $this->request->getHeader('IF_NONE_MATCH'); |
||||
|
if ($etagHeader !== '' && $response->getETag() !== null && trim($etagHeader) === '"' . $response->getETag() . '"') { |
||||
|
$response->setStatus(Http::STATUS_NOT_MODIFIED); |
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
$modifiedSinceHeader = $this->request->getHeader('IF_MODIFIED_SINCE'); |
||||
|
if ($modifiedSinceHeader !== '' && $response->getLastModified() !== null && trim($modifiedSinceHeader) === $response->getLastModified()->format(\DateTime::RFC2822)) { |
||||
|
$response->setStatus(Http::STATUS_NOT_MODIFIED); |
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
return $response; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,106 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
/** |
||||
|
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> |
||||
|
* |
||||
|
* @author Roeland Jago Douma <roeland@famdouma.nl> |
||||
|
* |
||||
|
* @license GNU AGPL version 3 or any later version |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify |
||||
|
* it under the terms of the GNU Affero General Public License as |
||||
|
* published by the Free Software Foundation, either version 3 of the |
||||
|
* License, or (at your option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
* GNU Affero General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Affero General Public License |
||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
namespace Test\AppFramework\Middleware; |
||||
|
|
||||
|
use OC\AppFramework\Middleware\NotModifiedMiddleware; |
||||
|
use OCP\AppFramework\Controller; |
||||
|
use OCP\AppFramework\Http; |
||||
|
use OCP\IRequest; |
||||
|
|
||||
|
class NotModifiedMiddlewareTest extends \Test\TestCase { |
||||
|
|
||||
|
/** @var IRequest */ |
||||
|
private $request; |
||||
|
/** @var Controller */ |
||||
|
private $controller; |
||||
|
/** @var NotModifiedMiddleware */ |
||||
|
private $middleWare; |
||||
|
|
||||
|
protected function setUp(): void { |
||||
|
parent::setUp(); |
||||
|
|
||||
|
$this->request = $this->createMock(IRequest::class); |
||||
|
$this->middleWare = new NotModifiedMiddleware( |
||||
|
$this->request |
||||
|
); |
||||
|
|
||||
|
$this->controller = $this->createMock(Controller::class); |
||||
|
} |
||||
|
|
||||
|
public function dataModified(): array { |
||||
|
$now = new \DateTime(); |
||||
|
|
||||
|
return [ |
||||
|
[null, '', null, '', false], |
||||
|
['etag', 'etag', null, '', false], |
||||
|
['etag', '"wrongetag"', null, '', false], |
||||
|
['etag', '', null, '', false], |
||||
|
[null, '"etag"', null, '', false], |
||||
|
['etag', '"etag"', null, '', true], |
||||
|
|
||||
|
[null, '', $now, $now->format(\DateTime::RFC2822), true], |
||||
|
[null, '', $now, $now->format(\DateTime::ATOM), false], |
||||
|
[null, '', null, $now->format(\DateTime::RFC2822), false], |
||||
|
[null, '', $now, '', false], |
||||
|
|
||||
|
['etag', '"etag"', $now, $now->format(\DateTime::ATOM), true], |
||||
|
['etag', '"etag"', $now, $now->format(\DateTime::RFC2822), true], |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @dataProvider dataModified |
||||
|
*/ |
||||
|
public function testMiddleware(?string $etag, string $etagHeader, ?\DateTime $lastModified, string $lastModifiedHeader, bool $notModifiedSet) { |
||||
|
$this->request->method('getHeader') |
||||
|
->willReturnCallback(function (string $name) use ($etagHeader, $lastModifiedHeader) { |
||||
|
if ($name === 'IF_NONE_MATCH') { |
||||
|
return $etagHeader; |
||||
|
} |
||||
|
if ($name === 'IF_MODIFIED_SINCE') { |
||||
|
return $lastModifiedHeader; |
||||
|
} |
||||
|
return ''; |
||||
|
}); |
||||
|
|
||||
|
$response = new Http\Response(); |
||||
|
if ($etag !== null) { |
||||
|
$response->setETag($etag); |
||||
|
} |
||||
|
if ($lastModified !== null) { |
||||
|
$response->setLastModified($lastModified); |
||||
|
} |
||||
|
$response->setStatus(Http::STATUS_OK); |
||||
|
|
||||
|
$result = $this->middleWare->afterController($this->controller, 'myfunction', $response); |
||||
|
|
||||
|
if ($notModifiedSet) { |
||||
|
$this->assertSame(Http::STATUS_NOT_MODIFIED, $result->getStatus()); |
||||
|
} else { |
||||
|
$this->assertSame(Http::STATUS_OK, $result->getStatus()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue