API DB commit and sticky DC cookie fixes
authorAaron Schulz <aschulz@wikimedia.org>
Tue, 10 Nov 2015 06:57:00 +0000 (22:57 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 19 Nov 2015 20:33:28 +0000 (12:33 -0800)
* Make sure the API commits DBs *before* sending the
  response, in case something goes south which would
  make a sent response wrong.
* Make sticky DC cookies trigger with api.php too.
* Make sure UseDC cookies do not end up with a prefix.
  VCL rules should not have to deal with having a DB
  name as a prefix or such. This was an oversight.

Change-Id: I9e4090ab15c1c1493b0589a710184745dac9b0c1

includes/MediaWiki.php
includes/api/ApiMain.php

index d048b57..22b896f 100644 (file)
@@ -486,13 +486,22 @@ class MediaWiki {
                $this->doPostOutputShutdown( 'normal' );
        }
 
+       /**
+        * @see MediaWiki::preOutputCommit()
+        * @since 1.26
+        */
+       public function doPreOutputCommit() {
+               self::preOutputCommit( $this->context );
+       }
+
        /**
         * This function commits all DB changes as needed before
         * the user can receive a response (in case commit fails)
         *
-        * @since 1.26
+        * @param IContextSource $context
+        * @since 1.27
         */
-       public function doPreOutputCommit() {
+       public static function preOutputCommit( IContextSource $context ) {
                // Either all DBs should commit or none
                ignore_user_abort( true );
 
@@ -505,16 +514,17 @@ class MediaWiki {
 
                // Set a cookie to tell all CDN edge nodes to "stick" the user to the
                // DC that handles this POST request (e.g. the "master" data center)
-               $request = $this->context->getRequest();
+               $request = $context->getRequest();
+               $config = $context->getConfig();
                if ( $request->wasPosted() && $factory->hasOrMadeRecentMasterChanges() ) {
-                       $expires = time() + $this->config->get( 'DataCenterUpdateStickTTL' );
-                       $request->response()->setCookie( 'UseDC', 'master', $expires );
+                       $expires = time() + $config->get( 'DataCenterUpdateStickTTL' );
+                       $request->response()->setCookie( 'UseDC', 'master', $expires, array( 'prefix' => '' ) );
                }
 
                // Avoid letting a few seconds of slave lag cause a month of stale data
                if ( $factory->laggedSlaveUsed() ) {
-                       $maxAge = $this->config->get( 'CdnMaxageLagged' );
-                       $this->context->getOutput()->lowerCdnMaxage( $maxAge );
+                       $maxAge = $config->get( 'CdnMaxageLagged' );
+                       $context->getOutput()->lowerCdnMaxage( $maxAge );
                        $request->response()->header( "X-Database-Lagged: true" );
                        wfDebugLog( 'replication', "Lagged DB used; CDN cache TTL limited to $maxAge seconds" );
                }
index 2768409..14b27ee 100644 (file)
@@ -440,6 +440,9 @@ class ApiMain extends ApiBase {
                // Log the request whether or not there was an error
                $this->logRequest( microtime( true ) - $t );
 
+               // Commit DBs and send any related cookies and headers
+               MediaWiki::preOutputCommit( $this->getContext() );
+
                // Send cache headers after any code which might generate an error, to
                // avoid sending public cache headers for errors.
                $this->sendCacheHeaders( $isError );