X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=vendor%2Fsymfony%2Fhttp-kernel%2FTests%2FHttpCache%2FHttpCacheTest.php;fp=vendor%2Fsymfony%2Fhttp-kernel%2FTests%2FHttpCache%2FHttpCacheTest.php;h=2a9a30d9ca4092dfe255e9a36615285fd836dfa0;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hp=5e03bc7a2a878a84483763e7590612308ead630b;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0;p=yaffs-website diff --git a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php index 5e03bc7a2..2a9a30d9c 100644 --- a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php +++ b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php @@ -530,8 +530,8 @@ class HttpCacheTest extends HttpCacheTestCase $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); - $this->assertTrue(strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date')) < 2); - $this->assertTrue($this->response->headers->get('Age') > 0); + $this->assertLessThan(2, strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date'))); + $this->assertGreaterThan(0, $this->response->headers->get('Age')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); @@ -554,14 +554,54 @@ class HttpCacheTest extends HttpCacheTestCase $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); - $this->assertTrue(strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date')) < 2); - $this->assertTrue($this->response->headers->get('Age') > 0); + $this->assertLessThan(2, strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date'))); + $this->assertGreaterThan(0, $this->response->headers->get('Age')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); } + public function testDegradationWhenCacheLocked() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Skips on windows to avoid permissions issues.'); + } + + $this->cacheConfig['stale_while_revalidate'] = 10; + + // The prescence of Last-Modified makes this cacheable (because Response::isValidateable() then). + $this->setNextResponse(200, array('Cache-Control' => 'public, s-maxage=5', 'Last-Modified' => 'some while ago'), 'Old response'); + $this->request('GET', '/'); // warm the cache + + // Now, lock the cache + $concurrentRequest = Request::create('/', 'GET'); + $this->store->lock($concurrentRequest); + + /* + * After 10s, the cached response has become stale. Yet, we're still within the "stale_while_revalidate" + * timeout so we may serve the stale response. + */ + sleep(10); + + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('stale-while-revalidate'); + $this->assertEquals('Old response', $this->response->getContent()); + + /* + * Another 10s later, stale_while_revalidate is over. Resort to serving the old response, but + * do so with a "server unavailable" message. + */ + sleep(10); + + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(503, $this->response->getStatusCode()); + $this->assertEquals('Old response', $this->response->getContent()); + } + public function testHitsCachedResponseWithSMaxAgeDirective() { $time = \DateTime::createFromFormat('U', time() - 5); @@ -578,8 +618,8 @@ class HttpCacheTest extends HttpCacheTestCase $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); - $this->assertTrue(strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date')) < 2); - $this->assertTrue($this->response->headers->get('Age') > 0); + $this->assertLessThan(2, strtotime($this->responses[0]->headers->get('Date')) - strtotime($this->response->headers->get('Date'))); + $this->assertGreaterThan(0, $this->response->headers->get('Age')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); @@ -753,7 +793,7 @@ class HttpCacheTest extends HttpCacheTestCase $this->request('GET', '/'); $this->assertHttpKernelIsCalled(); $this->assertEquals(200, $this->response->getStatusCode()); - $this->assertTrue($this->response->headers->get('Age') <= 1); + $this->assertLessThanOrEqual(1, $this->response->headers->get('Age')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); $this->assertTraceContains('stale'); $this->assertTraceNotContains('fresh'); @@ -791,7 +831,7 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals(200, $this->response->getStatusCode()); $this->assertNotNull($this->response->headers->get('Last-Modified')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); - $this->assertTrue($this->response->headers->get('Age') <= 1); + $this->assertLessThanOrEqual(1, $this->response->headers->get('Age')); $this->assertEquals('Hello World', $this->response->getContent()); $this->assertTraceContains('stale'); $this->assertTraceContains('valid'); @@ -841,7 +881,7 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals(200, $this->response->getStatusCode()); $this->assertNotNull($this->response->headers->get('ETag')); $this->assertNotNull($this->response->headers->get('X-Content-Digest')); - $this->assertTrue($this->response->headers->get('Age') <= 1); + $this->assertLessThanOrEqual(1, $this->response->headers->get('Age')); $this->assertEquals('Hello World', $this->response->getContent()); $this->assertTraceContains('stale'); $this->assertTraceContains('valid'); @@ -1128,7 +1168,7 @@ class HttpCacheTest extends HttpCacheTestCase array( 'status' => 200, 'body' => 'Hello World!', - 'headers' => array('Cache-Control' => 's-maxage=300'), + 'headers' => array('Cache-Control' => 's-maxage=200'), ), array( 'status' => 200, @@ -1142,8 +1182,33 @@ class HttpCacheTest extends HttpCacheTestCase $this->request('GET', '/', array(), array(), true); $this->assertEquals('Hello World! My name is Bobby.', $this->response->getContent()); - // check for 100 or 99 as the test can be executed after a second change - $this->assertTrue(in_array($this->response->getTtl(), array(99, 100))); + $this->assertEquals(100, $this->response->getTtl()); + } + + public function testEsiCacheSendsTheLowestTtlForHeadRequests() + { + $responses = array( + array( + 'status' => 200, + 'body' => 'I am a long-lived master response, but I embed a short-lived resource: ', + 'headers' => array( + 'Cache-Control' => 's-maxage=300', + 'Surrogate-Control' => 'content="ESI/1.0"', + ), + ), + array( + 'status' => 200, + 'body' => 'I am a short-lived resource', + 'headers' => array('Cache-Control' => 's-maxage=100'), + ), + ); + + $this->setNextResponses($responses); + + $this->request('HEAD', '/', array(), array(), true); + + $this->assertEmpty($this->response->getContent()); + $this->assertEquals(100, $this->response->getTtl()); } public function testEsiCacheForceValidation() @@ -1179,6 +1244,37 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTrue($this->response->headers->hasCacheControlDirective('no-cache')); } + public function testEsiCacheForceValidationForHeadRequests() + { + $responses = array( + array( + 'status' => 200, + 'body' => 'I am the master response and use expiration caching, but I embed another resource: ', + 'headers' => array( + 'Cache-Control' => 's-maxage=300', + 'Surrogate-Control' => 'content="ESI/1.0"', + ), + ), + array( + 'status' => 200, + 'body' => 'I am the embedded resource and use validation caching', + 'headers' => array('ETag' => 'foobar'), + ), + ); + + $this->setNextResponses($responses); + + $this->request('HEAD', '/', array(), array(), true); + + // The response has been assembled from expiration and validation based resources + // This can neither be cached nor revalidated, so it should be private/no cache + $this->assertEmpty($this->response->getContent()); + $this->assertNull($this->response->getTtl()); + $this->assertTrue($this->response->mustRevalidate()); + $this->assertTrue($this->response->headers->hasCacheControlDirective('private')); + $this->assertTrue($this->response->headers->hasCacheControlDirective('no-cache')); + } + public function testEsiRecalculateContentLengthHeader() { $responses = array( @@ -1187,7 +1283,6 @@ class HttpCacheTest extends HttpCacheTestCase 'body' => '', 'headers' => array( 'Content-Length' => 26, - 'Cache-Control' => 's-maxage=300', 'Surrogate-Control' => 'content="ESI/1.0"', ), ), @@ -1205,6 +1300,37 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals(12, $this->response->headers->get('Content-Length')); } + public function testEsiRecalculateContentLengthHeaderForHeadRequest() + { + $responses = array( + array( + 'status' => 200, + 'body' => '', + 'headers' => array( + 'Content-Length' => 26, + 'Surrogate-Control' => 'content="ESI/1.0"', + ), + ), + array( + 'status' => 200, + 'body' => 'Hello World!', + 'headers' => array(), + ), + ); + + $this->setNextResponses($responses); + + $this->request('HEAD', '/', array(), array(), true); + + // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13 + // "The Content-Length entity-header field indicates the size of the entity-body, + // in decimal number of OCTETs, sent to the recipient or, in the case of the HEAD + // method, the size of the entity-body that would have been sent had the request + // been a GET." + $this->assertEmpty($this->response->getContent()); + $this->assertEquals(12, $this->response->headers->get('Content-Length')); + } + public function testClientIpIsAlwaysLocalhostForForwardedRequests() { $this->setNextResponse(); @@ -1218,7 +1344,7 @@ class HttpCacheTest extends HttpCacheTestCase */ public function testHttpCacheIsSetAsATrustedProxy(array $existing, array $expected) { - Request::setTrustedProxies($existing, -1); + Request::setTrustedProxies($existing, Request::HEADER_X_FORWARDED_ALL); $this->setNextResponse(); $this->request('GET', '/', array('REMOTE_ADDR' => '10.0.0.1')); @@ -1296,6 +1422,35 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertNull($this->response->getLastModified()); } + public function testEsiCacheRemoveValidationHeadersIfEmbeddedResponsesAndHeadRequest() + { + $time = \DateTime::createFromFormat('U', time()); + + $responses = array( + array( + 'status' => 200, + 'body' => '', + 'headers' => array( + 'Surrogate-Control' => 'content="ESI/1.0"', + 'ETag' => 'hey', + 'Last-Modified' => $time->format(DATE_RFC2822), + ), + ), + array( + 'status' => 200, + 'body' => 'Hey!', + 'headers' => array(), + ), + ); + + $this->setNextResponses($responses); + + $this->request('HEAD', '/', array(), array(), true); + $this->assertEmpty($this->response->getContent()); + $this->assertNull($this->response->getETag()); + $this->assertNull($this->response->getLastModified()); + } + public function testDoesNotCacheOptionsRequest() { $this->setNextResponse(200, array('Cache-Control' => 'public, s-maxage=60'), 'get');