Skip to content

Commit 1896183

Browse files
authored
Merge pull request #30 from Toflar/feature/disable-content-digests
Added support for disabling generating content digests
2 parents 2922269 + 1760a61 commit 1896183

File tree

5 files changed

+121
-2
lines changed

5 files changed

+121
-2
lines changed

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,40 @@ passing an array of `$options` in the constructor:
112112

113113
**Type**: `string`
114114
**Default**: `Cache-Tags`
115+
116+
* **generate_content_digests**: Whether or not content digests should be generated.
117+
See "Generating Content Digests" for more information.
118+
119+
**Type**: `boolean`
120+
**Default**: `true`
121+
122+
### Generating Content Digests
123+
124+
By default, this cache implementation generates content digests.
125+
This means that the response meta data is stored separately from the
126+
response content. If multiple responses share the same content, it
127+
is stored in the cache only once.
128+
Compare the following illustrations to see the difference:
129+
130+
**With generating content digests**:
131+
![Illustration of the cache with generating content digests](docs/with_content_digests.svg)
132+
133+
**Without generating content digests**:
134+
![Illustration of the cache without generating content digests](docs/without_content_digests.svg)
135+
136+
Generating content digests optimizes the cache so it uses up less
137+
storage. Using them, however, also comes at the costs of requiring
138+
a second round trip to fetch the content digest from the cache during
139+
the lookup process.
140+
141+
Whether or not you want to use content digests depends on your PSR-6
142+
cache back end. If lookups are fast and storage is rather limited (e.g. Redis),
143+
you might want to use content digests. If lookups are rather slow and
144+
storage is less of an issue (e.g. Filesystem), you might want to disable
145+
them.
146+
147+
You can control the behaviour using the `generate_content_digests` configuration
148+
option.
115149

116150
### Caching `BinaryFileResponse` Instances
117151

docs/with_content_digests.svg

Lines changed: 3 additions & 0 deletions
Loading

docs/without_content_digests.svg

Lines changed: 3 additions & 0 deletions
Loading

src/Psr6Store.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ public function __construct(array $options = [])
8787
$resolver->setDefault('cache_tags_header', 'Cache-Tags')
8888
->setAllowedTypes('cache_tags_header', 'string');
8989

90+
$resolver->setDefault('generate_content_digests', true)
91+
->setAllowedTypes('generate_content_digests', 'boolean');
92+
9093
$resolver->setDefault('cache', function (Options $options) {
9194
if (!isset($options['cache_directory'])) {
9295
throw new MissingOptionsException('The cache_directory option is required unless you set the cache explicitly');
@@ -198,12 +201,18 @@ public function write(Request $request, Response $response)
198201
}
199202

200203
// Add or replace entry with current Vary header key
201-
$entries[$this->getVaryKey($response->getVary(), $request)] = [
204+
$varyKey = $this->getVaryKey($response->getVary(), $request);
205+
$entries[$varyKey] = [
202206
'vary' => $response->getVary(),
203207
'headers' => $headers,
204208
'status' => $response->getStatusCode(),
205209
];
206210

211+
// Add content if content digests are disabled
212+
if (!$this->options['generate_content_digests']) {
213+
$entries[$varyKey]['content'] = $response->getContent();
214+
}
215+
207216
// If the response has a Vary header we remove the non-varying entry
208217
if ($response->hasVary()) {
209218
unset($entries[self::NON_VARYING_KEY]);
@@ -412,7 +421,7 @@ public function getCacheKey(Request $request)
412421
}
413422

414423
/**
415-
* @return string
424+
* @return string|null
416425
*
417426
* @internal Do not use in public code, this is for unit testing purposes only
418427
*/
@@ -422,6 +431,10 @@ public function generateContentDigest(Response $response)
422431
return 'bf'.hash_file('sha256', $response->getFile()->getPathname());
423432
}
424433

434+
if (!$this->options['generate_content_digests']) {
435+
return null;
436+
}
437+
425438
return 'en'.hash('sha256', $response->getContent());
426439
}
427440

@@ -465,6 +478,11 @@ private function saveContentDigest(Response $response)
465478
}
466479

467480
$contentDigest = $this->generateContentDigest($response);
481+
482+
if (null === $contentDigest) {
483+
return;
484+
}
485+
468486
$digestCacheItem = $this->cache->getItem($contentDigest);
469487

470488
if ($digestCacheItem->isHit()) {
@@ -575,7 +593,18 @@ private function restoreResponse(array $cacheData)
575593
// Unset internal debug info
576594
unset($cacheData['headers'][self::CACHE_DEBUG_HEADER]);
577595

596+
// Check for content digest header
578597
if (!isset($cacheData['headers']['x-content-digest'][0])) {
598+
// No digest was generated but the content was stored inline
599+
if (isset($cacheData['content'])) {
600+
return new Response(
601+
$cacheData['content'],
602+
$cacheData['status'],
603+
$cacheData['headers']
604+
);
605+
}
606+
607+
// No content digest and no inline content means we cannot restore the response
579608
return null;
580609
}
581610

0 commit comments

Comments
 (0)