From 6765092258242e766ecfa281508aa10d10c15ad5 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 11 Jul 2014 10:05:36 -0400 Subject: [PATCH] Take redirect modifications into account for If-Modified-Since When the pageview is following a redirect, MediaWiki is only considering the page_touched timestamp for the target page. This causes issues with handling If-Modified-Since if the redirect is retargeted after the target page was last touched. The simple solution is to use the maximum page_touched of the page or the redirect (or any other redirect in the chain, if $wgMaxRedirects > 1). Bug: 67849 Change-Id: Ia359aaff6eab34c1d609254055c122a644fa7cce --- includes/page/Article.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/includes/page/Article.php b/includes/page/Article.php index 0e989d3d2f..2f27826265 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -480,7 +480,7 @@ class Article implements Page { * page of the given title. */ public function view() { - global $wgUseFileCache, $wgUseETag, $wgDebugToolbar; + global $wgUseFileCache, $wgUseETag, $wgDebugToolbar, $wgMaxRedirects; wfProfileIn( __METHOD__ ); @@ -542,8 +542,31 @@ class Article implements Page { $outputPage->setETag( $parserCache->getETag( $this, $parserOptions ) ); } + # Use the greatest of the page's timestamp or the timestamp of any + # redirect in the chain (bug 67849) + $timestamp = $this->mPage->getTouched(); + if ( isset( $this->mRedirectedFrom ) ) { + $timestamp = max( $timestamp, $this->mRedirectedFrom->getTouched() ); + + # If there can be more than one redirect in the chain, we have + # to go through the whole chain too in case an intermediate + # redirect was changed. + if ( $wgMaxRedirects > 1 ) { + $titles = Revision::newFromTitle( $this->mRedirectedFrom ) + ->getContent( Revision::FOR_THIS_USER, $user ) + ->getRedirectChain(); + $thisTitle = $this->getTitle(); + foreach ( $titles as $title ) { + if ( Title::compare( $title, $thisTitle ) === 0 ) { + break; + } + $timestamp = max( $timestamp, $title->getTouched() ); + } + } + } + # Is it client cached? - if ( $outputPage->checkLastModified( $this->mPage->getTouched() ) ) { + if ( $outputPage->checkLastModified( $timestamp ) ) { wfDebug( __METHOD__ . ": done 304\n" ); wfProfileOut( __METHOD__ ); -- 2.20.1