Skip to content

Commit

Permalink
Readme additions, normalize paths, testing fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
midwestE authored and midwestE committed Jul 1, 2020
1 parent 685ea2b commit bb9b049
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
13 changes: 12 additions & 1 deletion README.md
@@ -1,3 +1,14 @@
# SlimRedirects

Redirect a request to a different domain. Supports wildcard, regex, http to https redirection.
PSR7 Based Redirect library. Supports wildcard, regex, http to https redirection. Query string handling

-Trailing slash is ignored for request matching
-Assumes http://localhost is http://localhost/
-Querystring
--Defaults to combination of request and rule with rule overridding request where matching
--Rule fragment overrides request fragment
--Rule user info overrides request user info

TODO

-"/wild/card/\*/?old=querystring" match only when qs present
27 changes: 11 additions & 16 deletions src/RedirectController.php
Expand Up @@ -6,6 +6,7 @@
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\UriInterface;
use Slim\Psr7\Factory\ResponseFactory;
use Slim\Psr7\Factory\ServerRequestFactory;

Expand Down Expand Up @@ -128,8 +129,7 @@ protected function setRedirects(array $redirects): self
$array = [];
foreach ($redirects as $redirect) {
$r = ($redirect instanceof RedirectRule) ? $redirect : RedirectRule::factory($redirect);
$r->setSource($this->normalizePath($r->getSource()));
$array[$r->getSource()] = $r;
$array[$r->getSourceUri()->getPathNormalized()] = $r;
}
$this->redirects = $array;
return $this;
Expand Down Expand Up @@ -276,14 +276,6 @@ protected function isExcluded(string $path): bool
return in_array($path, $this->getExcludes());
}

protected function normalizePath(string $path): string
{
if ($path == '' || $path === '/') {
return '/';
}
return rtrim(strtolower($path), '/');
}

protected function mergeRuleIntoUri(RedirectRule $rule, RedirectUri $uri): RedirectUri
{
$destination = $rule->getDestinationUri();
Expand Down Expand Up @@ -317,7 +309,7 @@ public function redirectProcess(): ?Response
{
$redirects = $this->getRedirectsFiltered(true);
$uri = new RedirectUri($this->getRequest()->getUri(), $this->getResponse()->getStatusCode());
$path = $this->normalizePath($uri->getPath());
$path = $uri->getPathNormalized();
$noRedirectsOrExcluded = empty($redirects) || $this->isExcluded($path);
$nullOrResponse = null;

Expand Down Expand Up @@ -353,22 +345,24 @@ public function redirectProcess(): ?Response
if (!empty($redirects[$path])) {
$redirect = $redirects[$path];
$uri = $this->mergeRuleIntoUri($redirect, $uri);

$typeHandlerCallback = $this->getTypeHandler($redirect->getType());
$uri = $typeHandlerCallback($uri, $redirect, $this->getRequest());

return $uri->toRedirectResponse();
}

$newPath = '';
foreach ($redirects as $redirect) {
foreach ($redirects as $sourcePath => $redirect) {

$source = $redirect->getSource();
if (strpos($source, '*') === false) {
$sourcePath = urldecode($sourcePath);
if (strpos($sourcePath, '*') === false) {
continue;
}

// TODO refactor into matching method
$destination = $redirect->getDestination();
$sourcePattern = rtrim(str_replace('*', '(.*)', $source), '/');
$sourcePattern = rtrim(str_replace('*', '(.*)', $sourcePath), '/');
$sourcePatternRegex = '/^' . str_replace('/', '\/', $sourcePattern) . '/';
$regexPath = preg_replace($sourcePatternRegex, $this->parseDestination($destination), $path);

Expand All @@ -377,10 +371,11 @@ public function redirectProcess(): ?Response
continue;
}

$typeHandlerCallback = $this->getTypeHandler($redirect->getType());
$regexRule = clone $redirect;
$regexRule = $regexRule->setDestination($regexPath);
$uri = $this->mergeRuleIntoUri($regexRule, $uri);

$typeHandlerCallback = $this->getTypeHandler($redirect->getType());
$uri = $typeHandlerCallback($uri, $regexRule, $this->getRequest());

// the second condition here prevents redirect loops as a result of wildcards.
Expand Down
10 changes: 10 additions & 0 deletions src/RedirectUri.php
Expand Up @@ -58,6 +58,16 @@ public function withStatusCode(int $statusCode)
return $this;
}

public function getPathNormalized(): string
{
$path = $this->getPath();
if ($path == '' || $path === '/') {
return '/';
}
$path = rtrim(strtolower($path), '/');
return $path;
}

public function toRedirectResponse(ResponseInterface $response = null): ResponseInterface
{
$factory = new RedirectResponseFactory();
Expand Down
12 changes: 12 additions & 0 deletions tests/ControllerTest.php
Expand Up @@ -347,6 +347,18 @@ public function testTrailingSlash()
$result = $this->slimRedirect('https://localhost/?query=string', [$rule]);
$this->assertEquals($rule['httpStatus'], $result->responseStatus);
$this->assertEquals($result->location, 'https://localhost/root/?new=querystring&query=string');

$rule = [
"id" => "1",
"source" => "/wild/card/*/?old=querystring",
"type" => "path",
"destination" => "/root/?new=querystring",
"httpStatus" => 302,
"active" => 1
];
$result = $this->slimRedirect('https://localhost/wild/card/random?query=string', [$rule]);
$this->assertEquals($rule['httpStatus'], $result->responseStatus);
$this->assertEquals($result->location, 'https://localhost/root/?new=querystring&query=string');
}

public function testOnlyDestinationHasQs()
Expand Down

0 comments on commit bb9b049

Please sign in to comment.