This follows on from the disappearing resource tree thread. In desperation, I start a new topic, now that the hosting company is putting the blame on MODX for not encoding backslashes in its query strings (assuming that is indeed the case, and not just an unjustified slur).
According to the hosting company, LiteSpeed considers backslashes in query strings a security threat. However, if they are encoded (%5C), the query runs normally (and so the resource tree reappears).
The advice I have been given is this:
The best course of action is patching the MODX to use URL encoded backslashes instead of explicit ones in the query string.
It may be possible to catch the query string being written and doing a search and replace manually. This can be shown by injecting the following in a developer console for the page:
(function() {
function fixUrl(url) {
if (typeof url === 'string' && url.indexOf('\\') !== -1) {
return url.replace(/\\/g, '%5C');
}
return url;
}
var origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
arguments[1] = fixUrl(url);
return origOpen.apply(this, arguments);
};
})();
This just replaces \ with the URL encoding of it (%5C) whenever a HTTP request is generated by the page. If added in the console then the refresh icon on the resources is clicked then the pages load in the list.
The hosting support person kindly wrote the following plugin:
if ($modx->context->key !== 'mgr') {
return;
}
/** @var \MODX\Revolution\Controllers\modManagerController $controller */
$controller = $scriptProperties['controller'];
if (!$controller) {
return;
}
$js = <<<'EOD'
<script>
(function() {
function fixUrl(url) {
if (typeof url === 'string' && url.indexOf('\\') !== -1) {
return url.replace(/\\/g, '%5C');
}
return url;
}
var origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
arguments[1] = fixUrl(url);
return origOpen.apply(this, arguments);
};
if (window.fetch) {
var origFetch = window.fetch;
window.fetch = function(input, init) {
if (typeof input === 'string') input = fixUrl(input);
return origFetch.call(this, input, init);
};
}
})();
</script>
EOD;
$controller->addHtml($js);
Apparently, the plugin needs to be bound to the OnManagerPageBeforeRender system event, which injects the script immediately into the page.
The questions that occur to the uninitiated in these dark arts are two:
-
Does this even make sense?
-
If it does make sense, what needs to be done to make it work? At the moment, I have that plugin in the plugins list, but still no resources visible.