Arlolra has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/187848

Change subject: Set X-Forwarded-Proto when proxying https
......................................................................

Set X-Forwarded-Proto when proxying https

 * Refactors a bit about how proxies are stored in order to accommodate
   associating setting a header for that proxy.

Bug: T88100
Change-Id: Iad6d64971085c54e77adfbe76a3a8499c4d5c9ef
---
M lib/mediawiki.ApiRequest.js
M lib/mediawiki.ParsoidConfig.js
M lib/mediawiki.WikiConfig.js
M lib/mediawiki.parser.environment.js
4 files changed, 87 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid 
refs/changes/48/187848/1

diff --git a/lib/mediawiki.ApiRequest.js b/lib/mediawiki.ApiRequest.js
index d977513..6b31a3f 100644
--- a/lib/mediawiki.ApiRequest.js
+++ b/lib/mediawiki.ApiRequest.js
@@ -235,14 +235,15 @@
                apiargs.titles = title;
        }
 
-       var uri = env.conf.wiki.apiURI + '?' + qs.stringify( apiargs );
+       var uri = env.conf.wiki.apiURI + '?' + qs.stringify( apiargs ),
+               proxy = env.conf.wiki.apiProxy;
 
        this.requestOptions = {
                method: 'GET',
                followRedirect: true,
                uri: uri,
                timeout: 40 * 1000, // 40 seconds
-               proxy: env.conf.wiki.apiProxyURI,
+               proxy: proxy && proxy.uri,
                strictSSL: env.conf.parsoid.strictSSL,
                headers: {
                        'User-Agent': userAgent,
@@ -250,7 +251,11 @@
                }
        };
 
-       if (env.cookie) {
+       if ( proxy && proxy.headers ) {
+               Object.assign( this.requestOptions.headers, proxy.headers );
+       }
+
+       if ( env.cookie ) {
                // Forward the cookie if set
                this.requestOptions.headers.Cookie = env.cookie;
        }
@@ -375,7 +380,8 @@
                apiargs.revid = env.page.meta.revision.revid;
        }
 
-       var uri = env.conf.wiki.apiURI;
+       var uri = env.conf.wiki.apiURI,
+               proxy = env.conf.wiki.apiProxy;
 
        this.requestOptions = {
                // Use POST since we are passing a bit of source, and GET has a 
very
@@ -386,7 +392,7 @@
                followRedirect: true,
                uri: uri,
                timeout: 30 * 1000, // 30 seconds
-               proxy: env.conf.wiki.apiProxyURI,
+               proxy: proxy && proxy.uri,
                strictSSL: env.conf.parsoid.strictSSL,
                headers: {
                        'User-Agent': userAgent,
@@ -394,7 +400,11 @@
                }
        };
 
-       if (env.cookie) {
+       if ( proxy && proxy.headers ) {
+               Object.assign( this.requestOptions.headers, proxy.headers );
+       }
+
+       if ( env.cookie ) {
                // Forward the cookie if set
                this.requestOptions.headers.Cookie = env.cookie;
        }
@@ -476,7 +486,9 @@
                contentmodel: 'wikitext',
                prop: 'text|modules|categories'
        };
-       var uri = env.conf.wiki.apiURI;
+
+       var uri = env.conf.wiki.apiURI,
+               proxy = env.conf.wiki.apiProxy;
 
        // Pass the page title to the API
        var title = env.page && env.page.title && env.page.title.key;
@@ -493,7 +505,7 @@
                followRedirect: true,
                uri: uri,
                timeout: 16 * 1000, // 16 seconds
-               proxy: env.conf.wiki.apiProxyURI,
+               proxy: proxy && proxy.uri,
                strictSSL: env.conf.parsoid.strictSSL,
                headers: {
                        'User-Agent': userAgent,
@@ -501,7 +513,11 @@
                }
        };
 
-       if (env.cookie) {
+       if ( proxy && proxy.headers ) {
+               Object.assign( this.requestOptions.headers, proxy.headers );
+       }
+
+       if ( env.cookie ) {
                // Forward the cookie if set
                this.requestOptions.headers.Cookie = env.cookie;
        }
@@ -610,14 +626,12 @@
        var apiargs = {
                oldid: oldid
        };
+
        var uri = env.conf.parsoid.parsoidCacheURI +
                        env.conf.wiki.iwp + '/' + 
encodeURIComponent(title.replace(/ /g, '_')) +
                        '?' + qs.stringify( apiargs );
+
        this.uri = uri;
-
-       //console.warn('Cache request:', uri);
-
-
        this.retries = 0;
        this.requestOptions = {
                // Use GET so that our request is cacheable
@@ -675,14 +689,18 @@
  * A request for the wiki's configuration variables.
  *
  * @constructor
- * @param {string} apiURI The API URI to use for fetching
+ * @param {string} uri The API URI to use for fetching
  * @param {MWParserEnvironment} env
- * @param {string} apiProxyURI (optional) The proxy URI to use for the
- * ConfigRequest
+ * @param {string} proxy (optional) The proxy to use for the ConfigRequest.
  */
-var ConfigRequest = function ( apiURI, env, apiProxyURI ) {
+var ConfigRequest = function( uri, env, proxy ) {
        ApiRequest.call( this, env, null );
-       this.queueKey = apiURI;
+       this.queueKey = uri;
+
+       if ( !uri ) {
+               this._requestCB( new Error( 'There was no base URI for the API 
we tried to use.' ) );
+               return;
+       }
 
        var metas = [
                        'siteinfo'
@@ -705,17 +723,12 @@
                        siprop: siprops.join( '|' )
                };
 
-       if ( !apiURI ) {
-               this._requestCB( new Error( 'There was no base URI for the API 
we tried to use.' ) );
-               return;
-       }
-
        this.requestOptions = {
                method: 'GET',
                followRedirect: true,
-               uri: apiURI + '?' + qs.stringify( apiargs ),
+               uri: uri + '?' + qs.stringify( apiargs ),
                timeout: 40 * 1000,
-               proxy: apiProxyURI,
+               proxy: proxy && proxy.uri,
                strictSSL: env.conf.parsoid.strictSSL,
                headers: {
                        'User-Agent': userAgent,
@@ -723,11 +736,14 @@
                }
        };
 
-       if (env.cookie) {
+       if ( proxy && proxy.headers ) {
+               Object.assign( this.requestOptions.headers, proxy.headers );
+       }
+
+       if ( env.cookie ) {
                // Forward the cookie if set
                this.requestOptions.headers.Cookie = env.cookie;
        }
-
 
        this.request( this.requestOptions, this._requestCB.bind( this ) );
 };
@@ -804,18 +820,25 @@
 
        uri += qs.stringify( apiArgs );
 
+       var proxy = env.conf.wiki.apiProxy;
+
        this.requestOptions = {
                method: 'GET',
                followRedirect: true,
                uri: uri,
                timeout: 40 * 1000,
-               proxy: env.conf.wiki.apiProxyURI,
+               proxy: proxy && proxy.uri,
                headers: {
                        'User-Agent': userAgent,
                        'Connection': 'close'
                }
        };
-       if (env.cookie) {
+
+       if ( proxy && proxy.headers ) {
+               Object.assign( this.requestOptions.headers, proxy.headers );
+       }
+
+       if ( env.cookie ) {
                // Forward the cookie if set
                this.requestOptions.headers.Cookie = env.cookie;
        }
diff --git a/lib/mediawiki.ParsoidConfig.js b/lib/mediawiki.ParsoidConfig.js
index 11cbc9b..a4230cd 100644
--- a/lib/mediawiki.ParsoidConfig.js
+++ b/lib/mediawiki.ParsoidConfig.js
@@ -26,7 +26,7 @@
 function ParsoidConfig( localSettings, options ) {
        this.interwikiMap = new Map();
        this.reverseIWMap = new Map();
-       this.apiProxyURIs = new Map();
+       this.apiProxys = new Map();
        this.interwikiRegexp = "";
 
        if ( localSettings && localSettings.setup ) {
@@ -60,18 +60,22 @@
  *
  * @param {string} prefix
  * @param {string} apiURI The URL to the wiki's api.php.
- * @param {string} apiProxyURI The URL of a proxy to use for API requests, or
+ * @param {string} proxyURI The URL of a proxy to use for API requests, or
  * null to explicitly disable API request proxying for this wiki. Will fall
  * back to ParsoidConfig.defaultAPIProxyURI if undefined (default value).
+ * @param {object} proxyHeaders Headers to add when proxying.
  */
-ParsoidConfig.prototype.setInterwiki = function( prefix, apiURI, apiProxyURI ) 
{
+ParsoidConfig.prototype.setInterwiki = function( prefix, apiURI, proxyURI, 
proxyHeaders ) {
        this.interwikiMap.set( prefix, apiURI );
        this.reverseIWMap.set( url.parse( apiURI ).host, prefix );
 
-       if ( apiProxyURI !== undefined ) {
-               this.apiProxyURIs.set(prefix, apiProxyURI);
+       if ( proxyURI !== undefined || proxyHeaders !== undefined ) {
+               this.apiProxys.set(prefix, {
+                       uri: proxyURI,
+                       headers: proxyHeaders
+               });
        } else {
-               this.apiProxyURIs.delete(prefix);
+               this.apiProxys.delete(prefix);
        }
 
        if ( this.interwikiRegexp.match( '(^|\\|)' + prefix + '(\\||$)' ) === 
null ) {
@@ -93,7 +97,7 @@
        var u = url.parse( this.interwikiMap.get(prefix) );
        this.reverseIWMap.delete(u.host);
        this.interwikiMap.delete(prefix);
-       this.apiProxyURIs.delete(prefix);
+       this.apiProxys.delete(prefix);
        this.interwikiRegexp = this.interwikiRegexp.replace(
                new RegExp( '(^|\\|)' + prefix + '(\\||$)' ), function() {
                        return arguments[0] === ("|" + prefix + "|") ? "|" : '';
@@ -213,7 +217,7 @@
 ParsoidConfig.prototype.strictSSL = true;
 
 /**
- * The default api proxy, overridden by apiProxyURIs entries.
+ * The default api proxy, overridden by apiProxys entries.
  */
 ParsoidConfig.prototype.defaultAPIProxyURI = undefined;
 
@@ -226,19 +230,20 @@
  * Initialize the interwikiMap and friends.
  */
 ParsoidConfig.prototype.initInterwikiMap = function() {
-       var insertInMaps = function( proxy, site ) {
+       var insertInMaps = function( proxyURI, site ) {
+               var proxyHeaders;
                // Avoid overwriting those already set in localsettings setup.
                if ( !this.interwikiMap.has( site.dbname ) ) {
-                       var url = site.url;
-                       // Strip TLS if we're using the default proxy.
-                       if ( proxy === undefined ) {
-                               url = url.replace("https", "http");
+                       // When proxying https, lie to the appserver to indicate
+                       // unwrapping has just occurred.
+                       if ( proxyURI === undefined && /https/.test( site.url ) 
) {
+                               proxyHeaders = { "X-Forwarded-Proto": "https" };
                        }
-                       this.setInterwiki( site.dbname, url + "/w/api.php", 
proxy );
+                       this.setInterwiki( site.dbname, site.url + 
"/w/api.php", proxyURI, proxyHeaders );
                }
        };
 
-       // See MWParserEnvironment.prototype.getAPIProxyURI for the meaning
+       // See MWParserEnvironment.prototype.getAPIProxy for the meaning
        // of null / undefined in setInterwiki.
 
        var self = this;
diff --git a/lib/mediawiki.WikiConfig.js b/lib/mediawiki.WikiConfig.js
index 530894e..95c44f5 100644
--- a/lib/mediawiki.WikiConfig.js
+++ b/lib/mediawiki.WikiConfig.js
@@ -22,15 +22,12 @@
  * @param {Object} resultConf The configuration object from a MediaWiki API 
request. See the #ConfigRequest class in lib/mediawiki.ApiRequest.js for 
information about how we get this object. If null, we use the contents of 
lib/mediawiki.BaseConfig.json instead.
  * @param {string} prefix The interwiki prefix this config will represent. 
Will be used for caching elsewhere in the code.
  * @param {string} apiURI The URI that represents this wiki's API endpoint. 
Usually ends in api.php.
- * @param {string} apiProxyURI (optional) The URI of a proxy that should be
- * used to access apiURI, or null to explicitly disable proxying for this
- * wiki.
+ * @param {string} apiProxy (optional) The proxy that should be used to access 
apiURI.
  */
-function WikiConfig( resultConf, prefix, apiURI, apiProxyURI ) {
+function WikiConfig( resultConf, prefix, apiURI, apiProxy ) {
        var nsid,
                name,
                conf = this;
-
 
        // Mapping from canonical namespace name to id
        // The English namespace names are built-in and will work in any 
language.
@@ -67,7 +64,7 @@
        this.apiURI = apiURI || null;
 
        // The proxy to use for this wiki.
-       this.apiProxyURI = apiProxyURI;
+       this.apiProxy = apiProxy;
 
        if ( resultConf === null ) {
                // Use the default JSON that we've already loaded above.
diff --git a/lib/mediawiki.parser.environment.js 
b/lib/mediawiki.parser.environment.js
index 90ee85e..87f7171 100644
--- a/lib/mediawiki.parser.environment.js
+++ b/lib/mediawiki.parser.environment.js
@@ -271,18 +271,19 @@
 };
 
 /**
- * Figure out the proxy URI to use for API requests for a given wiki
+ * Figure out the proxy to use for API requests for a given wiki
  */
-MWParserEnvironment.prototype.getAPIProxyURI = function (prefix) {
-       var apiProxyURI = this.conf.parsoid.apiProxyURIs.get(prefix);
-       if (apiProxyURI === undefined) {
+MWParserEnvironment.prototype.getAPIProxy = function( prefix ) {
+       var apiProxy = this.conf.parsoid.apiProxys.get(prefix) ||
+               { uri: undefined, headers: undefined };
+       if ( apiProxy.uri === undefined ) {
                // No specific api proxy set. Fall back to generic API proxy.
-               apiProxyURI = this.conf.parsoid.defaultAPIProxyURI;
-       } else if (apiProxyURI === null) {
+               apiProxy.uri = this.conf.parsoid.defaultAPIProxyURI;
+       } else if ( apiProxy.uri === null ) {
                // Explicitly disable the proxy if null was set for this prefix
-               apiProxyURI = undefined;
+               apiProxy.uri = undefined;
        }
-       return apiProxyURI;
+       return apiProxy;
 };
 
 
@@ -295,14 +296,12 @@
  * @param {Error} cb.err
  */
 MWParserEnvironment.prototype.switchToConfig = function ( prefix, cb ) {
-
        function setupWikiConfig(env, apiURI, error, config) {
                if ( error === null ) {
-                       env.conf.wiki = new WikiConfig( config, prefix, apiURI, 
env.getAPIProxyURI(prefix) );
+                       env.conf.wiki = new WikiConfig( config, prefix, apiURI, 
env.getAPIProxy(prefix) );
                        env.confCache[prefix] = env.conf.wiki;
 
                }
-
                cb( error );
        }
 
@@ -330,10 +329,8 @@
                this.conf.wiki = this.confCache[prefix];
                cb( null );
        } else if ( this.conf.parsoid.fetchConfig ) {
-
-               var apiProxyURI = this.getAPIProxyURI(prefix),
-                       confRequest = new ConfigRequest( uri, this, apiProxyURI 
);
-               confRequest.on( 'src', setupWikiConfig.bind(null, this, uri));
+               var confRequest = new ConfigRequest( uri, this, 
this.getAPIProxy(prefix) );
+               confRequest.on('src', setupWikiConfig.bind(null, this, uri));
        } else {
                // Load the config from cached config on disk
                var localConfigFile = './baseconfig/' + prefix + '.json',

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iad6d64971085c54e77adfbe76a3a8499c4d5c9ef
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <abrea...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to