Skip to content

Commit

Permalink
Fix #100: Add support for multiple route hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerych1984 committed Jun 22, 2022
1 parent 1307720 commit a766320
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -2,8 +2,8 @@

## 1.0.1 under development

- no changes in this release.
- Enh #100: Add support for multiple route hosts (Gerych1984)

## 1.0.0 December 30, 2021

- Initial release.
- Initial release.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -20,7 +20,7 @@
"php": "^7.4|^8.0",
"nikic/fast-route": "^1.3",
"psr/simple-cache": "^1.0.1",
"yiisoft/router": "^1.0",
"yiisoft/router": "dev-master@dev",
"psr/http-message": "^1.0",
"yiisoft/http": "^1.2"
},
Expand Down
23 changes: 20 additions & 3 deletions src/UrlMatcher.php
Expand Up @@ -11,6 +11,7 @@
use FastRoute\RouteParser\Std as RouteParser;
use Psr\Http\Message\ServerRequestInterface;
use Psr\SimpleCache\CacheInterface;
use RuntimeException;
use Yiisoft\Http\Method;
use Yiisoft\Router\MatchingResult;
use Yiisoft\Router\RouteCollectionInterface;
Expand Down Expand Up @@ -231,10 +232,26 @@ private function injectRoutes(): void
if (!$route->getData('hasMiddlewares')) {
continue;
}
$hostPattern = $route->getData('host') ?? '{_host:[a-zA-Z0-9\.\-]*}';
$methods = $route->getData('methods');

$hosts = $route->getData('hosts');
$count = count($hosts);

if ($count > 1) {
$hosts = implode('|', $hosts);

if (preg_match('~' . RouteParser::VARIABLE_REGEX . '~x', $hosts)) {
throw new RuntimeException('Placeholders are not allowed with multiple host names.');
}

$hostPattern = '{_host:' . $hosts . '}';
} elseif ($count === 1) {
$hostPattern = $hosts[0];
} else {
$hostPattern = '{_host:[a-zA-Z0-9\.\-]*}';
}

$this->fastRouteCollector->addRoute(
$methods,
$route->getData('methods'),
$hostPattern . $route->getData('pattern'),
$route->getData('name')
);
Expand Down
46 changes: 46 additions & 0 deletions tests/UrlMatcherTest.php
Expand Up @@ -137,6 +137,52 @@ public function testSimpleRouteWithHostSuccess(): void
$this->assertTrue($result2->isSuccess());
}

public function testSimpleRouteWithMultipleHostSuccess(): void
{
$routes = [
Route::get('/site/index')
->action(fn () => 1)
->hosts('yii.test', 'yii.com', 'yii.ru'),
];

$urlMatcher = $this->createUrlMatcher($routes);
$request = new ServerRequest('GET', '/site/index');
$request1 = $request->withUri($request
->getUri()
->withHost('yii.test'));
$request2 = $request->withUri($request
->getUri()
->withHost('yii.com'));
$errorRequest = $request->withUri($request
->getUri()
->withHost('example.com'));

$result1 = $urlMatcher->match($request1);
$result2 = $urlMatcher->match($request2);
$errorResult = $urlMatcher->match($errorRequest);

$this->assertTrue($result1->isSuccess());
$this->assertTrue($result2->isSuccess());
$this->assertFalse($errorResult->isSuccess());
}

public function testMultipleHostException(): void
{
$route = Route::get('/')
->action(fn () => 1)
->hosts(
'https://yiiframework.com/',
'yf.com',
'{user}.yii.com'
);

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Placeholders are not allowed with multiple host names.');

$urlMatcher = $this->createUrlMatcher([$route]);
$urlMatcher->match(new ServerRequest('GET', '/site/index'));
}

public function testSimpleRouteWithHostFailed(): void
{
$routes = [
Expand Down

0 comments on commit a766320

Please sign in to comment.