Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/StaticCaching/Middleware/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ private function handleRequest($request, Closure $next)

private function copyError($request, $response)
{
$status = $response->getStatusCode();
if ($response->isSuccessful()) {
return;
}

if (! config('statamic.static_caching.share_errors')) {
return;
}

$request = Request::createFrom($request)->fakeStaticCacheStatus($status);
$request = Request::createFrom($request)->fakeStaticCacheStatus($response->getStatusCode());

if (! $this->cacher->hasCachedPage($request)) {
$this->cacher->cachePage($request, $response);
Expand Down
42 changes: 42 additions & 0 deletions tests/StaticCaching/HalfMeasureStaticCachingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,48 @@ public function index()
->assertSee('1 3', false);
}

public function shareErrorsEnabled($app)
{
$app['config']->set('statamic.static_caching.share_errors', true);
}

#[Test]
#[DefineEnvironment('shareErrorsEnabled')]
public function nocache_session_is_written_under_the_real_url_when_share_errors_is_enabled()
{
\Illuminate\Support\Facades\Cache::flush();

// Regression: when share_errors is enabled, the middleware's copyError()
// step used to call Request::fakeStaticCacheStatus() on every cacheable
// response, including 200s. That mutated the singleton nocache Session
// URL to /__shared-errors/200, causing Session::write() to persist the
// regions list under the wrong cache key. On subsequent hits in a
// fresh PHP process, the cached page was found but its nocache regions
// could not be restored, a RegionNotFound was caught, and the request
// fell through to a full dynamic re-render — defeating half-measure
// caching. See discussion: nocache regions silently failing under
// share_errors on 200 responses.

$this->withStandardFakeViews();
$this->viewShouldReturnRaw('default', '{{ title }} {{ nocache }}{{ title }}{{ /nocache }}');

$this->createPage('about', ['with' => ['title' => 'Hello']]);

$this->get('/about')->assertOk();

// The session metadata must be persisted under the real request URL,
// not under the fake /__shared-errors/200 URL.
$store = \Statamic\Facades\StaticCache::cacheStore();
$this->assertNotNull(
$store->get('nocache::session.'.md5('http://localhost/about')),
'Expected nocache session to be stored under the real request URL.'
);
$this->assertNull(
$store->get('nocache::session.'.md5('/__shared-errors/200')),
'nocache session must not be stored under the shared-errors URL for 200 responses.'
);
}

#[Test]
public function it_can_keep_parts_dynamic_using_nocache_tags_in_loops()
{
Expand Down
Loading