From cf1d36d56b377de30abe3442ddb98d017841e5b8 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Mon, 12 May 2014 16:05:00 -0400 Subject: [PATCH] Added BeforeHttpsRedirect hook allowing extensions to cancel forceHTTPS For ZERO, we need to be able to avoid forceHTTPS from taking place in case user logged in while on wifi, and later switched to zero.wikipedia.org for the carrier who doesn't support HTTPS. In that case, the extension will need to be able to cancel redirect and force regular HTTP handling. Open Question: should this code log off user in case hook returns false? Bug 65567 Change-Id: If04c83066c5d47b3c04ad7674e3c4e95a4cd464b --- RELEASE-NOTES-1.24 | 4 ++++ docs/hooks.txt | 7 +++++++ includes/Wiki.php | 49 ++++++++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24 index 12deb92ef7..d1c941a0ae 100644 --- a/RELEASE-NOTES-1.24 +++ b/RELEASE-NOTES-1.24 @@ -41,6 +41,10 @@ production. * (bug 63903) Thumbnails without an explicit size specification are now resized to a square bounding box. This gives better results for non-landscape thumbnails. +* (bug 65567) Added a new hook, "BeforeHttpsRedirect", to allow cancellation of the HTTP + to HTTPS redirect due to forceHTTPS cookie, userRequires, etc. This is only for page views, + since this hook doesn't affect UserLogin, OAuth, CentralAuth, etc. + ATTENTION: This hook is likely to be removed soon due to overall design of the system. === Bug fixes in 1.24 === * (bug 49116) Footer copyright notice is now always displayed in user language diff --git a/docs/hooks.txt b/docs/hooks.txt index e1c9ec6f94..0b072f29c9 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -728,6 +728,13 @@ $mediaWiki: Mediawiki object &$out: OutputPage object &$skin: Skin object +'BeforeHttpsRedirect': Prior to forcing HTTP->HTTPS redirect. Gives a chance to +override how the redirect is output by modifying, or by returning false, and +letting standard HTTP rendering take place. +ATTENTION: This hook is likely to be removed soon due to overall design of the system. +$context: IContextSource object +&$redirect: string URL, modifiable + 'BeforePageRedirect': Prior to sending an HTTP redirect. Gives a chance to override how the redirect is output by modifying, or by returning false and taking over the output. diff --git a/includes/Wiki.php b/includes/Wiki.php index 555813d169..a8bafa3f46 100644 --- a/includes/Wiki.php +++ b/includes/Wiki.php @@ -533,6 +533,7 @@ class MediaWiki { // Note: Do this after $wgTitle is setup, otherwise the hooks run from // isLoggedIn() will do all sorts of weird stuff. if ( + $request->getProtocol() == 'http' && ( $request->getCookie( 'forceHTTPS', '' ) || // check for prefixed version for currently logged in users @@ -542,34 +543,36 @@ class MediaWiki { $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS() ) - ) && - $request->getProtocol() == 'http' + ) ) { $oldUrl = $request->getFullRequestURL(); $redirUrl = preg_replace( '#^http://#', 'https://', $oldUrl ); - if ( $request->wasPosted() ) { - // This is weird and we'd hope it almost never happens. This - // means that a POST came in via HTTP and policy requires us - // redirecting to HTTPS. It's likely such a request is going - // to fail due to post data being lost, but let's try anyway - // and just log the instance. - // - // @todo @fixme See if we could issue a 307 or 308 here, need - // to see how clients (automated & browser) behave when we do - wfDebugLog( 'RedirectedPosts', "Redirected from HTTP to HTTPS: $oldUrl" ); + // ATTENTION: This hook is likely to be removed soon due to overall design of the system. + if ( wfRunHooks( 'BeforeHttpsRedirect', array( $this->context, &$redirUrl ) ) ) { + + if ( $request->wasPosted() ) { + // This is weird and we'd hope it almost never happens. This + // means that a POST came in via HTTP and policy requires us + // redirecting to HTTPS. It's likely such a request is going + // to fail due to post data being lost, but let's try anyway + // and just log the instance. + // + // @todo @fixme See if we could issue a 307 or 308 here, need + // to see how clients (automated & browser) behave when we do + wfDebugLog( 'RedirectedPosts', "Redirected from HTTP to HTTPS: $oldUrl" ); + } + // Setup dummy Title, otherwise OutputPage::redirect will fail + $title = Title::newFromText( NS_MAIN, 'REDIR' ); + $this->context->setTitle( $title ); + $output = $this->context->getOutput(); + // Since we only do this redir to change proto, always send a vary header + $output->addVaryHeader( 'X-Forwarded-Proto' ); + $output->redirect( $redirUrl ); + $output->output(); + wfProfileOut( __METHOD__ ); + return; } - - // Setup dummy Title, otherwise OutputPage::redirect will fail - $title = Title::newFromText( NS_MAIN, 'REDIR' ); - $this->context->setTitle( $title ); - $output = $this->context->getOutput(); - // Since we only do this redir to change proto, always send a vary header - $output->addVaryHeader( 'X-Forwarded-Proto' ); - $output->redirect( $redirUrl ); - $output->output(); - wfProfileOut( __METHOD__ ); - return; } if ( $wgUseFileCache && $title->getNamespace() >= 0 ) { -- 2.20.1