From f56afa36a65bbe9963be9e4000c9a4a82be97e45 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Sun, 1 May 2011 18:41:42 +0000 Subject: [PATCH] (bug 28738) Implement request splitting in mw.loader so ResourceLoader requests with query strings longer than a certain value are split up. The maximum query string length is configurable, and this behavior is disabled by default. It's needed in rare cases where there is a query string length or GET variable length limit in place that the wiki admin can't raise. --- includes/DefaultSettings.php | 13 +++++++ .../ResourceLoaderStartUpModule.php | 4 ++- resources/mediawiki/mediawiki.js | 35 +++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 6ce6e5155c..4abd2d5655 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -2537,6 +2537,19 @@ $wgResourceLoaderMinifierMaxLineLength = 1000; */ $wgIncludeLegacyJavaScript = true; +/** + * If set to a positive number, ResourceLoader will not generate URLs whose + * query string is more than this many characters long, and will instead use + * multiple requests with shorter query strings. This degrades performance, + * but may be needed if your web server has a low (less than, say 1024) + * query string length limit or a low value for suhosin.get.max_value_length + * that you can't increase. + * + * If set to a negative number, ResourceLoader will assume there is no query + * string length limit. + */ +$wgResourceLoaderMaxQueryLength = -1; + /** @} */ # End of resource loader settings } diff --git a/includes/resourceloader/ResourceLoaderStartUpModule.php b/includes/resourceloader/ResourceLoaderStartUpModule.php index 0ed0675da8..1f66c88c2a 100644 --- a/includes/resourceloader/ResourceLoaderStartUpModule.php +++ b/includes/resourceloader/ResourceLoaderStartUpModule.php @@ -37,7 +37,8 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgVariantArticlePath, $wgActionPaths, $wgUseAjax, $wgVersion, $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgEnableMWSuggest, - $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgProto, $wgCookiePrefix; + $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgProto, + $wgCookiePrefix, $wgResourceLoaderMaxQueryLength; // Pre-process information $separatorTransTable = $wgContLang->separatorTransformTable(); @@ -92,6 +93,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { 'wgProto' => $wgProto, // mediawiki sets cookies to have this prefix by default 'wgCookiePrefix' => $wgCookiePrefix, + 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, ); if ( $wgUseAjax && $wgEnableMWSuggest ) { $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate(); diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index 24f67a9036..c3467a1ef1 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -922,9 +922,38 @@ window.mediaWiki = new ( function( $ ) { version = registry[groups[group][g]].version; } } - requests[requests.length] = $.extend( - { 'modules': groups[group].join( '|' ), 'version': formatVersionNumber( version ) }, base - ); + var reqBase = $.extend( { 'version': formatVersionNumber( version ) }, base ); + var reqBaseLength = $.param( reqBase ).length; + var reqs = []; + var limit = mw.config.get( 'wgResourceLoaderMaxQueryLength', -1 ); + if ( limit > 0 ) { + // We may need to split up the request to honor the query string length limit + // So build it piece by piece + var l = reqBaseLength + 9; // '&modules='.length == 9 + var r = 0; + reqs[0] = []; + for ( var i = 0; i < groups[group].length; i++ ) { + // If the request would become too long, create a new one, + // but don't create empty requests + // '%7C'.length == 3 + if ( reqs[r].length > 0 && l + 3 + groups[group][i].length > limit ) { + // This request would become too long, create a new one + r++; + reqs[r] = []; + l = reqBaseLength + 9; + } + reqs[r][reqs[r].length] = groups[group][i]; + l += groups[group][i].length + 3; + } + } else { + // No splitting needed + reqs = [ groups[group] ]; + } + for ( var r in reqs ) { + requests[requests.length] = $.extend( + { 'modules': reqs[r].join( '|' ) }, reqBase + ); + } } // Clear the batch - this MUST happen before we append the // script element to the body or it's possible that the script -- 2.20.1