From ec59c3367031f9be79d6cb8d2a986606afbc7b0c Mon Sep 17 00:00:00 2001 From: Thomas Barregren Date: Thu, 26 Feb 2026 19:31:05 +0100 Subject: [PATCH] Prevent page caches from storing content-negotiation redirect Many full-page caches do not vary their cache key by the Accept request header. When they store the 303 redirect from content negotiation, all subsequent visitors are redirected to the .md URL instead of seeing the HTML page. Two complementary layers prevent this: - Cache-Control: private header prevents shared caches (CDNs, reverse proxies) from storing the redirect while allowing browser caching. - DONOTCACHEPAGE constant and LiteSpeed API call tell WP-level page caches not to store the response. This is behind a filter (markdown_alternate_disable_page_cache_on_redirect) so sites with Vary-aware caching can opt out. The .md URLs themselves remain fully cacheable. Fixes ProgressPlanner#30 Co-Authored-By: Claude --- src/Router/RewriteHandler.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Router/RewriteHandler.php b/src/Router/RewriteHandler.php index e7220a1..d4995dd 100644 --- a/src/Router/RewriteHandler.php +++ b/src/Router/RewriteHandler.php @@ -372,6 +372,22 @@ public function handle_accept_negotiation(): void { return; } + // Prevent shared caches (CDNs, reverse proxies) that don't honour + // Vary from storing this content-negotiation redirect and serving + // the 303 to every visitor regardless of their Accept header. + header('Cache-Control: private'); + + // Many WordPress page-cache plugins cache at the PHP level and may + // not vary by the Accept request header. Tell them explicitly not to + // cache this response. Sites with Vary-aware caching can disable this: + // add_filter( 'markdown_alternate_disable_page_cache_on_redirect', '__return_false' ); + if ( apply_filters( 'markdown_alternate_disable_page_cache_on_redirect', true ) ) { + if ( ! defined( 'DONOTCACHEPAGE' ) ) { + define( 'DONOTCACHEPAGE', true ); + } + do_action( 'litespeed_control_set_nocache', 'Content negotiation redirect' ); + } + // 303 See Other: redirect to markdown URL with Vary for cache correctness. header('Vary: Accept'); wp_safe_redirect($md_url, 303);