Skip to content

Commit

Permalink
ELPP-2452 Added cache headers to recommendations (#57)
Browse files Browse the repository at this point in the history
* ELPP-2452 Added cache headers to recommendations

* ELPP-2452 Added headers test

* ELPP-2452 Changd status code

* ELPP-2452 Added ping test

* ELPP-2452 Added private response and test

* ELPP-2452 Added private response and test
  • Loading branch information
stephenwf committed Mar 30, 2017
1 parent c9e974a commit d032007
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/App/DefaultController.php
Expand Up @@ -6,6 +6,7 @@
use eLife\Recommendations\Process\Hydration;
use eLife\Recommendations\Process\Rules;
use eLife\Recommendations\RecommendationsResponse;
use eLife\Recommendations\Response\PrivateResponse;
use eLife\Recommendations\RuleModel;
use eLife\Recommendations\RuleModelRepository;
use JMS\Serializer\SerializationContext;
Expand Down Expand Up @@ -111,11 +112,10 @@ public function indexAction(Request $request, string $type, string $id)

public function pingAction()
{
return new Response(
return new PrivateResponse(
'pong',
200,
[
'Cache-Control' => 'must-revalidate, no-cache, no-store, private',
'Content-Type' => 'text/plain; charset=UTF-8',
]
);
Expand Down
23 changes: 18 additions & 5 deletions src/App/Kernel.php
Expand Up @@ -31,6 +31,7 @@
use eLife\Recommendations\Process\Hydration;
use eLife\Recommendations\Process\Rules;
use eLife\Recommendations\RecommendationResultDiscriminator;
use eLife\Recommendations\Response\PrivateResponse;
use eLife\Recommendations\Rule\BidirectionalRelationship;
use eLife\Recommendations\Rule\CollectionContents;
use eLife\Recommendations\Rule\Common\MicroSdk;
Expand Down Expand Up @@ -101,7 +102,7 @@ public function __construct($config = [], $autoRun = true)
'debug' => false,
'validate' => false,
'annotation_cache' => true,
'ttl' => 3600,
'ttl' => 300,
'process_memory_limit' => 200,
'file_logs_path' => self::ROOT.'/var/logs',
'tables' => [
Expand Down Expand Up @@ -430,7 +431,7 @@ public function handleException(Throwable $e): Response
return new JsonResponse(array_filter([
'error' => $e->getMessage(),
'trace' => $this->app['config']['debug'] ? $e->getTraceAsString() : null,
]), $e->getCode());
]), $e->getCode() ? $e->getCode() : Response::HTTP_INTERNAL_SERVER_ERROR);
}
$logger->error('An unknown exception was thrown', [
'exception' => $e,
Expand All @@ -447,7 +448,7 @@ public function handleException(Throwable $e): Response
'time' => microtime(true) - $this->startTime,
] : [
'error' => trim($errorMessage),
], 500);
], Response::HTTP_INTERNAL_SERVER_ERROR);
}

public function withApp(callable $fn)
Expand Down Expand Up @@ -482,18 +483,30 @@ public function validate(Request $request, Response $response)
$json->_validationInfo = $e->getMessage();
$json->_time = microtime(true) - $this->startTime;
$response->setContent(json_encode($json));

return $response;
}
$this->get('logger')->warning('Invalid JSON provided to user', [
'exception' => $e,
'request' => $request,
'response' => $response,
]);
}

return $response;
}

public function cache(Request $request, Response $response)
{
if ($response instanceof PrivateResponse) {
return $response;
}
$response->setMaxAge($this->app['config']['ttl']);
$response->headers->addCacheControlDirective('stale-while-revalidate', $this->app['config']['ttl']);
$response->headers->addCacheControlDirective('stale-if-error', 86400);
$response->setVary('Accept');
$response->setEtag(md5($response->getContent()));
$response->setPublic();
$response->isNotModified($request);

return $response;
}
}
14 changes: 14 additions & 0 deletions src/Recommendations/Response/PrivateResponse.php
@@ -0,0 +1,14 @@
<?php

namespace eLife\Recommendations\Response;

use Symfony\Component\HttpFoundation\Response;

final class PrivateResponse extends Response
{
public function __construct($content = '', $status = 200, array $headers = array())
{
parent::__construct($content, $status, $headers);
$this->headers->set('Cache-Control', 'must-revalidate, no-cache, no-store, private');
}
}
55 changes: 55 additions & 0 deletions tests/src/Web/CacheHeadersTest.php
@@ -0,0 +1,55 @@
<?php

namespace tests\eLife\Web;

use DateTimeImmutable;

/**
* @group web
*/
class CacheHeadersTest extends WebTestCase
{
public function testETag()
{
$this->addArticlePoAWithId('1', (new DateTimeImmutable())->setDate(2017, 1, 1));
$this->addArticlePoAWithId('2', (new DateTimeImmutable())->setDate(2017, 2, 2));

$this->newClient();
$this->jsonRequest('GET', '/recommendations/research-article/1');
$response = $this->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$eTag = $response->headers->get('ETag');
$this->assertEquals('max-age=300, public, stale-if-error=86400, stale-while-revalidate=300', $response->headers->get('Cache-Control'));
$this->assertEquals('Accept', $response->headers->get('Vary'));

$this->jsonRequest('GET', '/recommendations/research-article/1', [], ['If-None-Match' => $eTag]);
$response = $this->getResponse();
$this->assertEquals(304, $response->getStatusCode());
$this->assertEquals('max-age=300, public, stale-if-error=86400, stale-while-revalidate=300', $response->headers->get('Cache-Control'));
$this->assertEquals('Accept', $response->headers->get('Vary'));

$this->jsonRequest('GET', '/recommendations/research-article/1', [], ['If-None-Match' => 'NOT REAL ETAG']);
$response = $this->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('max-age=300, public, stale-if-error=86400, stale-while-revalidate=300', $response->headers->get('Cache-Control'));
$this->assertEquals('Accept', $response->headers->get('Vary'));
}

public function testPing()
{
$this->newClient();
$this->jsonRequest('GET', '/ping');
$response = $this->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('text/plain; charset=UTF-8', $response->headers->get('Content-Type'));
$this->assertEquals('must-revalidate, no-cache, no-store, private', $response->headers->get('Cache-Control'));
}

public function modifyConfiguration($config)
{
$config['ttl'] = 300;
$config['debug'] = false;

return $config;
}
}

0 comments on commit d032007

Please sign in to comment.