diff --git a/README.md b/README.md index f756909..a3df4d3 100644 --- a/README.md +++ b/README.md @@ -746,7 +746,7 @@ class CustomExceptionHandler implements IExceptionHandler /* You can use the exception handler to format errors depending on the request and type. */ - if (stripos($request->getUri(), '/api') !== false) { + if (stripos($request->getUri()->getPath(), '/api') !== false) { response()->json([ 'error' => $error->getMessage(), @@ -1131,7 +1131,7 @@ class CustomRouterRules implement IRouterBootManager { // If the current uri matches the url, we use our custom route - if($request->getUri() === $url) { + if($request->getUri()->getPath() === $url) { $request->setRewriteUrl($rule); return $request; } diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 056d23f..5d2b4cf 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -41,9 +41,9 @@ class BaseCsrfVerifier implements IMiddleware $url = rtrim($url, '/'); if ($url[strlen($url) - 1] === '*') { $url = rtrim($url, '*'); - $skip = (stripos($request->getUri(), $url) === 0); + $skip = (stripos($request->getUri()->getPath(), $url) === 0); } else { - $skip = ($url === rtrim($request->getUri(), '/')); + $skip = ($url === $request->getUri()->getPath()); } if ($skip === true) { diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 0d69a71..91cb994 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -29,8 +29,8 @@ class Request public function __construct() { $this->parseHeaders(); - $this->host = $this->getHeader('http-host'); - $this->uri = $this->getHeader('request-uri'); + $this->setHost($this->getHeader('http-host')); + $this->setUri(new Uri($this->getHeader('request-uri'))); $this->input = new Input($this); $this->method = strtolower($this->input->get('_method', $this->getHeader('request-method'), 'post')); } @@ -58,7 +58,7 @@ class Request } /** - * @return string + * @return Uri */ public function getUri() { @@ -215,9 +215,9 @@ class Request } /** - * @param string $uri + * @param Uri $uri */ - public function setUri($uri) + public function setUri(Uri $uri) { $this->uri = $uri; } diff --git a/src/Pecee/Http/Response.php b/src/Pecee/Http/Response.php index c5730f1..0c8625a 100644 --- a/src/Pecee/Http/Response.php +++ b/src/Pecee/Http/Response.php @@ -41,7 +41,7 @@ class Response public function refresh() { - $this->redirect($this->request->getUri()); + $this->redirect($this->request->getUri()->getPath()); } /** diff --git a/src/Pecee/Http/Uri.php b/src/Pecee/Http/Uri.php new file mode 100644 index 0000000..1232219 --- /dev/null +++ b/src/Pecee/Http/Uri.php @@ -0,0 +1,172 @@ +originalUrl = $url; + $this->data = array_merge($this->data, $this->parseUrl($url)); + + if (isset($this->data['path']) === true && $this->data['path'] !== '/') { + $this->data['path'] = rtrim($this->data['path'], '/') . '/'; + } + + } + + /** + * Check if url is using a secure protocol like https + * @return bool + */ + public function isSecure() + { + return (strtolower($this->getScheme()) === 'https'); + } + + /** + * Checks if url is relative + * @return bool + */ + public function isRelative() + { + return ($this->getHost() === null); + } + + /** + * Get url scheme + * @return string|null + */ + public function getScheme() + { + return $this->data['scheme']; + } + + /** + * Get url host + * @return string|null + */ + public function getHost() + { + return $this->data['host']; + } + + /** + * Get url port + * @return int|null + */ + public function getPort() + { + return ($this->data['port'] !== null) ? (int)$this->data['port'] : null; + } + + /** + * Parse username from url + * @return string|null + */ + public function getUserName() + { + return $this->data['user']; + } + + /** + * Parse password from url + * @return string|null + */ + public function getPassword() + { + return $this->data['pass']; + } + + /** + * Get path from url + * @return string + */ + public function getPath() + { + return $this->data['path']; + } + + /** + * Get querystring from url + * @return string|null + */ + public function getQueryString() + { + return $this->data['query']; + } + + /** + * Get fragment from url (everything after #) + * @return string|null + */ + public function getFragment() + { + return $this->data['fragment']; + } + + /** + * @return string + */ + public function getOriginalUrl() + { + return $this->originalUrl; + } + + /** + * UTF-8 aware parse_url() replacement. + * @param string $url + * @param int $component + * @throws \InvalidArgumentException + * @return array + */ + public function parseUrl($url, $component = -1) + { + $encodedUrl = preg_replace_callback( + '%[^:/@?&=#]+%u', + function ($matches) { + return urlencode($matches[0]); + }, + $url + ); + + $parts = parse_url($encodedUrl, $component); + + if ($parts === false) { + throw new \InvalidArgumentException('Malformed URL: ' . $url); + } + + foreach ((array)$parts as $name => $value) { + $parts[$name] = urldecode($value); + } + + return $parts; + } + + /** + * Returns data array with information about the url + * @return array + */ + public function getData() + { + return $this->data; + } + + public function __toString() + { + return $this->getOriginalUrl(); + } + +} \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index b32fa23..bafa324 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -87,9 +87,6 @@ class RouteController extends LoadableRoute implements IControllerRoute public function matchRoute($url, Request $request) { - $url = parse_url(urldecode($url), PHP_URL_PATH); - $url = rtrim($url, '/') . '/'; - /* Match global regular-expression for route */ $regexMatch = $this->matchRegex($request, $url); diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index 7e806ca..c042b23 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -79,9 +79,6 @@ class RouteResource extends LoadableRoute implements IControllerRoute public function matchRoute($url, Request $request) { - $url = parse_url(urldecode($url), PHP_URL_PATH); - $url = rtrim($url, '/') . '/'; - /* Match global regular-expression for route */ $regexMatch = $this->matchRegex($request, $url); diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index 1c348aa..6c37e55 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -14,9 +14,6 @@ class RouteUrl extends LoadableRoute public function matchRoute($url, Request $request) { - $url = parse_url(urldecode($url), PHP_URL_PATH); - $url = rtrim($url, '/') . '/'; - /* Match global regular-expression for route */ $regexMatch = $this->matchRegex($request, $url); diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 9090d6a..b646184 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -122,7 +122,7 @@ class Router $exceptionHandlers = []; - $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri(); + $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath(); /* @var $route IRoute */ for ($i = $max; $i >= 0; $i--) { @@ -224,7 +224,7 @@ class Router } } - $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri(); + $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath(); $max = count($this->processedRoutes) - 1; @@ -248,6 +248,7 @@ class Router if ($rewriteRoute !== null) { $rewriteRoute->loadMiddleware($this->request); + return $rewriteRoute->renderRoute($this->request); } @@ -265,6 +266,7 @@ class Router /* Render route */ $routeNotAllowed = false; $this->request->setLoadedRoute($route); + return $route->renderRoute($this->request); break; @@ -284,9 +286,9 @@ class Router $rewriteUrl = $this->request->getRewriteUrl(); if ($rewriteUrl !== null) { - $message = sprintf('Route not found: "%s" (rewrite from: "%s")', $rewriteUrl, $this->request->getUri()); + $message = sprintf('Route not found: "%s" (rewrite from: "%s")', $rewriteUrl, $this->request->getUri()->getPath()); } else { - $message = sprintf('Route not found: "%s"', $this->request->getUri()); + $message = sprintf('Route not found: "%s"', $this->request->getUri()->getPath()); } $this->handleException(new NotFoundHttpException($message, 404)); @@ -300,7 +302,7 @@ class Router */ protected function handleException(\Exception $e) { - $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri(); + $url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath(); $max = count($this->exceptionHandlers); @@ -323,6 +325,7 @@ class Router if ($rewriteRoute !== null) { $rewriteRoute->loadMiddleware($this->request); + return $rewriteRoute->renderRoute($this->request); } @@ -443,9 +446,7 @@ class Router /* Return current route if no options has been specified */ if ($name === null && $parameters === null) { - $url = rtrim(parse_url($this->request->getUri(), PHP_URL_PATH), '/'); - - return (($url === '') ? '/' : $url . '/') . $this->arrayToParams($getParams); + return $this->request->getUri()->getPath() . $this->arrayToParams($getParams); } $loadedRoute = $this->request->getLoadedRoute(); diff --git a/test/Dummy/Handler/ExceptionHandlerFirst.php b/test/Dummy/Handler/ExceptionHandlerFirst.php index 87e4761..db752e7 100644 --- a/test/Dummy/Handler/ExceptionHandlerFirst.php +++ b/test/Dummy/Handler/ExceptionHandlerFirst.php @@ -7,7 +7,7 @@ class ExceptionHandlerFirst implements \Pecee\Handlers\IExceptionHandler global $stack; $stack[] = static::class; - $request->setUri('/'); + $request->setUri(new \Pecee\Http\Uri('/')); return $request; } diff --git a/test/Dummy/Handler/ExceptionHandlerSecond.php b/test/Dummy/Handler/ExceptionHandlerSecond.php index 90c18ae..86a11d1 100644 --- a/test/Dummy/Handler/ExceptionHandlerSecond.php +++ b/test/Dummy/Handler/ExceptionHandlerSecond.php @@ -7,7 +7,7 @@ class ExceptionHandlerSecond implements \Pecee\Handlers\IExceptionHandler global $stack; $stack[] = static::class; - $request->setUri('/'); + $request->setUri(new \Pecee\Http\Uri('/')); return $request; } diff --git a/test/Helpers/TestRouter.php b/test/Helpers/TestRouter.php index 5db693b..8347999 100644 --- a/test/Helpers/TestRouter.php +++ b/test/Helpers/TestRouter.php @@ -5,7 +5,7 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter public static function debugNoReset($testUri, $testMethod = 'get') { - static::request()->setUri($testUri); + static::request()->setUri(new \Pecee\Http\Uri($testUri)); static::request()->setMethod($testMethod); static::start(); diff --git a/test/RouterRewriteTest.php b/test/RouterRewriteTest.php index e72bce6..d55aaa8 100644 --- a/test/RouterRewriteTest.php +++ b/test/RouterRewriteTest.php @@ -64,7 +64,7 @@ class RouteRewriteTest extends PHPUnit_Framework_TestCase TestRouter::error(function (\Pecee\Http\Request $request, \Exception $error) { - if (strtolower($request->getUri()) == '/my/test') { + if (strtolower($request->getUri()->getPath()) == '/my/test') { $request->setRewriteUrl('/another-non-existing'); return $request; diff --git a/test/RouterUrlTest.php b/test/RouterUrlTest.php index 4ea583c..f669632 100644 --- a/test/RouterUrlTest.php +++ b/test/RouterUrlTest.php @@ -31,7 +31,7 @@ class RouterUrlTest extends PHPUnit_Framework_TestCase public function testUnicodeCharacters() { // Test spanish characters - TestRouter::get('/cursos/listado/{listado?}/{category?}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s-]+']); + TestRouter::get('/cursos/listado/{listado?}/{category?}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s-\í]+']); TestRouter::debugNoReset('/cursos/listado/especialidad/cirugía local', 'get'); $this->assertEquals('/cursos/listado/{listado?}/{category?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl()); @@ -40,6 +40,13 @@ class RouterUrlTest extends PHPUnit_Framework_TestCase TestRouter::debugNoReset('/kategori/økse', 'get'); $this->assertEquals('/kategori/økse/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl()); + TestRouter::get('/test/{param}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s-\í]+']); + TestRouter::debugNoReset('/test/Dermatología'); + + $parameters = TestRouter::request()->getLoadedRoute()->getParameters(); + + $this->assertEquals('Dermatología', $parameters['param']); + TestRouter::router()->reset(); }