Allow the request ID to be passed in via the `X-Request-Id` header
authorMarko Obrovac <mobrovac@wikimedia.org>
Mon, 22 Apr 2019 20:28:54 +0000 (13:28 -0700)
committerMobrovac <mobrovac@wikimedia.org>
Wed, 15 May 2019 07:27:38 +0000 (07:27 +0000)
For tracing and logging purposes, we want to be able to see/generate the
list of all of the requests that happen in the environment for a given
external incoming request. To that end, allow Mediawiki to accept the
request ID provided by the incoming request as its own.

Since this may be problematic for set-ups that don't have an entity in
front of MW that sanitises the headers on the way in, introduce a new
global variable, `$wgAllowExternalReqID`, that can disable this
behaviour. By default, the feature is disabled.

Bug: T201409
Change-Id: I605471fb8b5bbc290baeecc7d80d9d715cb240c9

RELEASE-NOTES-1.34
includes/DefaultSettings.php
includes/WebRequest.php

index c53bb6f..2531be2 100644 (file)
@@ -27,7 +27,12 @@ For notes on 1.33.x and older releases, see HISTORY.
 === Configuration changes for system administrators in 1.34 ===
 
 ==== New configuration ====
-* …
+* $wgAllowExternalReqID (T201409) - This configuration setting controls whether
+  Mediawiki accepts the request ID set by the incoming request via the
+  `X-Request-Id` header. If set to `true`, that value will be used throughout
+  the code as the request identificator. Otherwise, the sent header will be
+  ignored and the request ID will either be taken from Apache's mod_unique
+  module or will be generated by Mediawiki itself (depending on the set-up).
 
 ==== Changed configuration ====
 * …
index 0f7a606..28e9ec8 100644 (file)
@@ -8430,6 +8430,13 @@ $wgLocalVirtualHosts = [];
  */
 $wgHTTPConnectTimeout = 5e0;
 
+/**
+ * Whether to respect/honour the request ID provided by the incoming request
+ * via the `X-Request-Id` header. Set to `true` if the entity sitting in front
+ * of Mediawiki sanitises external requests. Default: `false`.
+ */
+$wgAllowExternalReqID = false;
+
 /** @} */ # End HTTP client }
 
 /************************************************************************//**
index 7da092f..76d94b2 100644 (file)
@@ -275,8 +275,18 @@ class WebRequest {
        public static function getRequestId() {
                // This method is called from various error handlers and should be kept simple.
 
-               if ( !self::$reqId ) {
-                       self::$reqId = $_SERVER['UNIQUE_ID'] ?? wfRandomString( 24 );
+               if ( self::$reqId ) {
+                       return self::$reqId;
+               }
+
+               global $wgAllowExternalReqID;
+
+               self::$reqId = $_SERVER['UNIQUE_ID'] ?? wfRandomString( 24 );
+               if ( $wgAllowExternalReqID ) {
+                       $id = RequestContext::getMain()->getRequest()->getHeader( 'X-Request-Id' );
+                       if ( $id ) {
+                               self::$reqId = $id;
+                       }
                }
 
                return self::$reqId;