1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-07 23:38:29 +02:00

Fix issue where the config.maxUrlSegments wasn't working, plus add new config.longUrlResponse where you can define the http response that should be used when there is an overflow of URL length, segments, or depth.

This commit is contained in:
Ryan Cramer
2024-12-20 15:14:37 -05:00
parent 9bc02399e5
commit 1fc3cf414a
4 changed files with 58 additions and 19 deletions

View File

@@ -985,7 +985,7 @@ $config->protectCSRF = true;
* @var int
*
*/
$config->maxUrlSegments = 4;
$config->maxUrlSegments = 20;
/**
* Maximum length for any individual URL segment (default=128)
@@ -1004,7 +1004,23 @@ $config->maxUrlSegmentLength = 128;
* @var int
*
*/
$config->maxUrlDepth = 30;
$config->maxUrlDepth = 30;
/**
* Long URL response (URL depth, length or segments overflow)
*
* HTTP code that ProcessWire should respond with when it receives more URL segments,
* more URL depth, or longer URL length than what is allowed. Suggested values:
*
* - `404`: Page not found
* - `301`: Redirect to closest allowed URL (permanent)
* - `302`: Redirect to closest allowed URL (temporary)
*
* @var int
* @since 3.0.243
*
*/
$config->longUrlResponse = 404;
/**
* Pagination URL prefix

View File

@@ -91,6 +91,7 @@
* @property int $maxUrlSegments Maximum number of extra stacked URL segments allowed in a page's URL (including page numbers) #pw-group-URLs
* @property int $maxUrlSegmentLength Maximum length of any individual URL segment (default=128). #pw-group-URLs
* @property int $maxUrlDepth Maximum URL/path slashes (depth) for request URLs. (Min=10, Max=60) #pw-group-URLs
* @property int $longUrlResponse Response code when URL segments, depth or length exceeds max allowed. #pw-group-URLs @since 3.0.243
* @property string $wireInputOrder Order that variables with the $input API var are handled when you access $input->var. #pw-group-HTTP-and-input
* @property bool $wireInputLazy Specify true for $input API var to load input data in a lazy fashion and potentially use less memory. Default is false. #pw-group-HTTP-and-input
* @property int $wireInputArrayDepth Maximum multi-dimensional array depth for input variables accessed from $input or 1 to only allow single dimension arrays. #pw-group-HTTP-and-input @since 3.0.178

View File

@@ -380,8 +380,10 @@ class PagesPathFinder extends Wire {
*
*/
protected function applyPagesRow(array $parts, $row) {
$maxUrlSegmentLength = $this->wire()->config->maxUrlSegmentLength;
$config = $this->wire()->config;
$maxUrlSegmentLength = $config->maxUrlSegmentLength;
$maxUrlSegments = $config->maxUrlSegments;
$result = &$this->result;
// array of [language name] => [ 'a', 'b', 'c' ] (from /a/b/c/)
@@ -396,14 +398,28 @@ class PagesPathFinder extends Wire {
if(!$id) {
// if it didnt resolve to DB page name then it is a URL segment
if(strlen($name) > $maxUrlSegmentLength) $name = substr($name, 0, $maxUrlSegmentLength);
$result['urlSegments'][] = $name;
if($this->verbose) {
$result['parts'][] = array(
'type' => 'urlSegment',
'value' => $name,
'language' => ''
);
if(strlen($name) > $maxUrlSegmentLength) {
$name = substr($name, 0, $maxUrlSegmentLength);
if($config->longUrlResponse >= 300) {
$result['response'] = $config->longUrlResponse;
$this->addResultError('urlSegmentLength', 'URL segment length > config.maxUrlSegmentLength');
}
}
if(count($result['urlSegments']) + 1 > $maxUrlSegments) {
if($config->longUrlResponse >= 300) {
$this->addResultError('urlSegmentMAX', 'Number of URL segments exceeds config.maxUrlSegments');
$result['response'] = $config->longUrlResponse;
break;
}
} else {
$result['urlSegments'][] = $name;
if($this->verbose) {
$result['parts'][] = array(
'type' => 'urlSegment',
'value' => $name,
'language' => ''
);
}
}
continue;
}
@@ -480,7 +496,7 @@ class PagesPathFinder extends Wire {
* If language segment detected then remove it and populate language to result
*
* @param string $path
* @return array|bool
* @return array
*
*/
protected function getPathParts($path) {
@@ -497,7 +513,7 @@ class PagesPathFinder extends Wire {
$lastPart = '';
if($this->strlen($path) > $maxPathLength) {
$result['response'] = 414; // 414=URI too long
$result['response'] = $config->longUrlResponse; // 414=URI too long
$this->addResultError('pathLengthMAX', "Path length exceeds max allowed $maxPathLength");
$path = substr($path, 0, $maxPathLength);
}
@@ -506,7 +522,7 @@ class PagesPathFinder extends Wire {
if(count($parts) > $maxDepth) {
$parts = array_slice($parts, 0, $maxDepth);
$result['response'] = 414;
$result['response'] = $config->longUrlResponse;
$this->addResultError('pathDepthMAX', 'Path depth exceeds config.maxUrlDepth');
} else if($path === '/' || $path === '' || !count($parts)) {
return array();
@@ -1484,7 +1500,7 @@ class PagesPathFinder extends Wire {
*
*/
protected function addResultError($name, $message, $force = false) {
if(!$this->verbose && !$force) return;
//if(!$this->verbose && !$force) return;
$this->result['errors'][$name] = $message;
}

View File

@@ -593,9 +593,15 @@ class PagesRequest extends Wire {
}
$maxUrlDepth = $config->maxUrlDepth;
if($maxUrlDepth > 0 && substr_count($it, '/') > $config->maxUrlDepth) {
$this->setResponseCode(414, 'Request URL exceeds max depth set in $config->maxUrlDepth');
return false;
if($maxUrlDepth > 0 && substr_count($it, '/') > $maxUrlDepth) {
if(in_array($config->longUrlResponse, [ 302, 301 ])) {
$parts = array_slice(explode('/', $it), 0, $maxUrlDepth);
$it = '/' . trim(implode('/', $parts), '/') . '/';
$this->setRedirectPath($it, $config->longUrlResponse);
} else {
$this->setResponseCode($config->longUrlResponse, 'Request URL exceeds max depth set in $config->maxUrlDepth');
return false;
}
}
if(!isset($it[0]) || $it[0] != '/') $it = "/$it";