jenkins-bot has submitted this change and it was merged.

Change subject: Add header to flag API POST requests with no write intentions
......................................................................


Add header to flag API POST requests with no write intentions

This performs sanity check that request *is* for a non-write module.
By handling the validation, the CDN layer can simply use the presence
of this header to route POST requests to the local datacenter.
Without validation, users could cause strange traffic patterns and slow
cross-DC database writes (which can involve many RTTs).

This is useful for AJAX widgets that need to post a payload to get a
response, but that don't actually change anything in the process. They
should be able to use the local datacenter.

Bug: T91820
Change-Id: I34248ddee33033e3d1d86c3391236259d917d4a7
---
M includes/WebStart.php
M includes/api/ApiMain.php
M languages/i18n/en.json
M languages/i18n/qqq.json
4 files changed, 32 insertions(+), 4 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  Anomie: Looks good to me, but someone else must approve
  Siebrand: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/includes/WebStart.php b/includes/WebStart.php
index b095577..adce346 100644
--- a/includes/WebStart.php
+++ b/includes/WebStart.php
@@ -141,3 +141,25 @@
 if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 
'POST' ) {
        ignore_user_abort( true );
 }
+
+if ( !defined( 'MW_API' ) &&
+       RequestContext::getMain()->getRequest()->getHeader( 
'Promise-Non-Write-API-Action' )
+) {
+       header( 'Cache-Control: no-cache' );
+       header( 'Content-Type: text/html; charset=utf-8' );
+       HttpStatus::header( 400 );
+       $error = wfMessage( 'nonwrite-api-promise-error' )->escaped();
+       $content = <<<EOT
+<!DOCTYPE html>
+<html>
+<head><meta charset="UTF-8" /></head>
+<body>
+$error
+</body>
+</html>
+
+EOT;
+       header( 'Content-Length: ' . strlen( $content ) );
+       echo $content;
+       die();
+}
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index c641c95..86a8a87 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -1151,13 +1151,17 @@
                if ( $module->isWriteMode() ) {
                        if ( !$this->mEnableWrite ) {
                                $this->dieUsageMsg( 'writedisabled' );
-                       }
-                       if ( !$user->isAllowed( 'writeapi' ) ) {
+                       } elseif ( !$user->isAllowed( 'writeapi' ) ) {
                                $this->dieUsageMsg( 'writerequired' );
-                       }
-                       if ( wfReadOnly() ) {
+                       } elseif ( wfReadOnly() ) {
                                $this->dieReadOnly();
                        }
+                       if ( $this->getRequest()->getHeader( 
'Promise-Non-Write-API-Action' ) ) {
+                               $this->dieUsage(
+                                       "Promise-Non-Write-API-Action HTTP 
header cannot be sent to write API modules",
+                                       'promised-nonwrite-api'
+                               );
+                       }
                }
 
                // Allow extensions to stop execution for arbitrary reasons.
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index d62913a..c4e7d92 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -323,6 +323,7 @@
        "missingarticle-rev": "(revision#: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "readonly_lag": "The database has been automatically locked while the 
slave database servers catch up to the master",
+       "nonwrite-api-promise-error" : "The 'Promise-Non-Write-API-Action' HTTP 
header was sent but the request was to an API write module.",
        "internalerror": "Internal error",
        "internalerror_info": "Internal error: $1",
        "internalerror-fatal-exception": "Fatal exception of type \"$1\"",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index 7298f4e..34240d4 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -497,6 +497,7 @@
        "missingarticle-rev": "Used as <code>$2</code> in 
{{msg-mw|Missing-article}}\n\nPreceded by the page 
title.\n\n[{{canonicalurl:Translating:Tasks|oldid=371789000}} Click here] to 
see an example of such an error message.\n\nParameters:\n* $1 - revision# of 
the requested ID",
        "missingarticle-diff": "Used as <code>$2</code> in 
{{msg-mw|Missing-article}}\n\nPreceded by the page 
title.\n\n[{{canonicalurl:Translating:Tasks|diff=372398&oldid=371789000}} Click 
here] to see an example of such an error message.\n\nParameters:\n* $1 - the 
old revision ID\n* $2 - the revision ID to build the diff with",
        "readonly_lag": "Error message displayed when the database is locked.",
+       "nonwrite-api-promise-error": "Error message displayed when the 
'Promise-Non-Write-API-Action' HTTP header is misused.",
        "internalerror": "{{Identical|Internal error}}",
        "internalerror_info": "Parameters:\n* $1 - error message",
        "internalerror-fatal-exception": "Error message displayed by MediaWiki 
itself when the request failed, inside an error box which also contains a code, 
a timestamp and a colon before this message.\nParameters:\n* $1 - proper name 
of the kind of error\n* $2 - alphanumeric code identifying the error in the 
server logs\n* $3 - URL which resulted in the error\n$2 and $3 are not used by 
default and only available for wiki customisations, because they are useful for 
communication to the wiki system administrator.",

-- 
To view, visit https://gerrit.wikimedia.org/r/248668
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I34248ddee33033e3d1d86c3391236259d917d4a7
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: Gilles <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to