From d8964fb8b7c2b460570bc70597e59eff8316253e Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Sat, 16 May 2020 11:23:27 +0000 Subject: [PATCH] [HttpKernel] Fix that the `Store` would not save responses with the X-Content-Digest header present --- .../Component/HttpKernel/HttpCache/Store.php | 29 ++++++++++--------- .../HttpKernel/Tests/HttpCache/StoreTest.php | 21 ++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Store.php b/src/Symfony/Component/HttpKernel/HttpCache/Store.php index c831ba2ac3ffb..fd04a7b23d1d3 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Store.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Store.php @@ -177,19 +177,15 @@ public function write(Request $request, Response $response) $key = $this->getCacheKey($request); $storedEnv = $this->persistRequest($request); - // write the response body to the entity store if this is the original response - if (!$response->headers->has('X-Content-Digest')) { - $digest = $this->generateContentDigest($response); + $digest = $this->generateContentDigest($response); + $response->headers->set('X-Content-Digest', $digest); - if (!$this->save($digest, $response->getContent())) { - throw new \RuntimeException('Unable to store the entity.'); - } - - $response->headers->set('X-Content-Digest', $digest); + if (!$this->save($digest, $response->getContent(), false)) { + throw new \RuntimeException('Unable to store the entity.'); + } - if (!$response->headers->has('Transfer-Encoding')) { - $response->headers->set('Content-Length', \strlen($response->getContent())); - } + if (!$response->headers->has('Transfer-Encoding')) { + $response->headers->set('Content-Length', \strlen($response->getContent())); } // read existing cache entries, remove non-varying, and add this one to the list @@ -362,15 +358,20 @@ private function load($key) /** * Save data for the given key. * - * @param string $key The store key - * @param string $data The data to store + * @param string $key The store key + * @param string $data The data to store + * @param bool $overwrite Whether existing data should be overwritten * * @return bool */ - private function save($key, $data) + private function save($key, $data, $overwrite = true) { $path = $this->getPath($key); + if (!$overwrite && file_exists($path)) { + return true; + } + if (isset($this->locks[$key])) { $fp = $this->locks[$key]; @ftruncate($fp, 0); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php index 77cb34cfa5556..07c41542697e3 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php @@ -97,6 +97,27 @@ public function testSetsTheXContentDigestResponseHeaderBeforeStoring() $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $res['x-content-digest'][0]); } + public function testDoesNotTrustXContentDigestFromUpstream() + { + $response = new Response('test', 200, ['X-Content-Digest' => 'untrusted-from-elsewhere']); + + $cacheKey = $this->store->write($this->request, $response); + $entries = $this->getStoreMetadata($cacheKey); + list(, $res) = $entries[0]; + + $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $res['x-content-digest'][0]); + $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $response->headers->get('X-Content-Digest')); + } + + public function testWritesResponseEvenIfXContentDigestIsPresent() + { + // Prime the store + $this->store->write($this->request, new Response('test', 200, ['X-Content-Digest' => 'untrusted-from-elsewhere'])); + + $response = $this->store->lookup($this->request); + $this->assertNotNull($response); + } + public function testFindsAStoredEntryWithLookup() { $this->storeSimpleEntry(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy