Added BeforeHttpsRedirect hook allowing extensions to cancel forceHTTPS
authorYuri Astrakhan <yurik@wikimedia.org>
Mon, 12 May 2014 20:05:00 +0000 (16:05 -0400)
committerYuri Astrakhan <yurik@wikimedia.org>
Wed, 28 May 2014 16:46:11 +0000 (12:46 -0400)
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
docs/hooks.txt
includes/Wiki.php

index 12deb92..d1c941a 100644 (file)
@@ -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
index e1c9ec6..0b072f2 100644 (file)
@@ -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.
index 555813d..a8bafa3 100644 (file)
@@ -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 ) {