Skip to content

Commit

Permalink
Url: added isAbsolute() & removeDotSegments()
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Nov 5, 2024
1 parent cb1bd41 commit ad29269
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/Http/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,34 @@ public static function parseQuery(string $s): array
parse_str($s, $res);
return $res[0] ?? [];
}


public static function isAbsolute(string $url): bool
{
return (bool) preg_match('#^[a-z][a-z0-9+.-]*:#i', $url);
}


public static function removeDotSegments(string $path): string
{
$prefix = $segment = '';
if (str_starts_with($path, '/')) {
$prefix = '/';
$path = substr($path, 1);
}
$segments = explode('/', $path);
$res = [];
foreach ($segments as $segment) {
if ($segment === '..') {
array_pop($res);
} elseif ($segment !== '.') {
$res[] = $segment;
}
}

if ($segment === '.' || $segment === '..') {
$res[] = '';
}
return $prefix . implode('/', $res);
}
}
15 changes: 15 additions & 0 deletions tests/Http/Url.isAbsolute.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

use Nette\Http\Url;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


Assert::false(Url::isAbsolute('/'));
Assert::false(Url::isAbsolute('//'));
Assert::false(Url::isAbsolute(''));
Assert::false(Url::isAbsolute('https'));
Assert::true(Url::isAbsolute('https:'));
55 changes: 55 additions & 0 deletions tests/Http/Url.removeDotSegments.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

use Nette\Http\Url;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


test('begins with /', function () {
Assert::same('/', Url::removeDotSegments('/'));
Assert::same('/file', Url::removeDotSegments('/file'));
Assert::same('/file/', Url::removeDotSegments('/file/'));

Assert::same('/', Url::removeDotSegments('/.'));
Assert::same('/', Url::removeDotSegments('/./'));

Assert::same('/file/', Url::removeDotSegments('/file/.'));
Assert::same('/', Url::removeDotSegments('/file/..'));
Assert::same('/', Url::removeDotSegments('/file/../'));
Assert::same('/file', Url::removeDotSegments('/./file'));
});


test('not begins with /', function () {
Assert::same('', Url::removeDotSegments(''));
Assert::same('file', Url::removeDotSegments('file'));
Assert::same('file/', Url::removeDotSegments('file/'));

Assert::same('', Url::removeDotSegments('.'));
Assert::same('', Url::removeDotSegments('./'));

Assert::same('file/', Url::removeDotSegments('file/.'));
Assert::same('', Url::removeDotSegments('file/..'));
Assert::same('', Url::removeDotSegments('file/../'));
Assert::same('file', Url::removeDotSegments('./file'));
});


test('incorrect ..', function () {
Assert::same('/', Url::removeDotSegments('/file/../..'));
Assert::same('/', Url::removeDotSegments('/file/../../'));
Assert::same('/bar', Url::removeDotSegments('/file/../../bar'));
Assert::same('/file', Url::removeDotSegments('/../file'));
Assert::same('/bar', Url::removeDotSegments('/file/./.././.././bar'));
Assert::same('/bar/', Url::removeDotSegments('/file/./.././.././bar/'));
});


test('double slash', function () {
Assert::same('//', Url::removeDotSegments('//'));
Assert::same('//foo//', Url::removeDotSegments('//foo//'));
Assert::same('//foo//', Url::removeDotSegments('//foo//..//'));
});

0 comments on commit ad29269

Please sign in to comment.