From c5298dd24bf18c07b3033687407ad95ea330b291 Mon Sep 17 00:00:00 2001 From: bellington3 <71927099+bellington3@users.noreply.github.com> Date: Mon, 19 Oct 2020 20:18:03 +0000 Subject: [PATCH] Provide basePath support (#309) * Provide basePath support To be able to serve the application via a reverse proxy in a subfolder smarty needs to be aware of the basepath if any. * Provide basepath support via X-Forwarded headers * Fix warnings * Review adjustments * Provide support X-Forwarded-Host header * Use $uri in view factory directly * Use middleware to set basepath from X-Forwarded-Path header * Fix invalid type hint in RouterPathMiddleware * Add "X-Forwarded-Host" to README --- README.md | 6 +++++ classes/RouterPathMiddleware.php | 42 ++++++++++++++++++++++++++++++++ classes/ViewFactory.php | 22 +++++++++++++++-- index.php | 3 +++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 classes/RouterPathMiddleware.php diff --git a/README.md b/README.md index 047c175..90cc05e 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,12 @@ You will need PHP 7.2 (or higher) and the following PHP modules: ## Web server configuration +If you want to serve the application under a basepath and/or with a different internal than external port (scenario: nginx->docker setup) Alltube supports the following X-Forwarded headers: + +* X-Forwarded-Host (ex. `another.domain.com`) +* X-Forwarded-Path (ex: `/alltube`) +* X-Forwarded-Port (ex: `5555`) + ### Apache The following modules are recommended: diff --git a/classes/RouterPathMiddleware.php b/classes/RouterPathMiddleware.php new file mode 100644 index 0000000..71e2314 --- /dev/null +++ b/classes/RouterPathMiddleware.php @@ -0,0 +1,42 @@ +router = $container->get('router'); + } + + /** + * @param Request $request + * @param Response $response + * @param callable $next + * @return mixed + */ + public function __invoke(Request $request, Response $response, callable $next) + { + $this->router->setBasePath(current($request->getHeader('X-Forwarded-Path'))); + + return $next($request, $response); + } +} diff --git a/classes/ViewFactory.php b/classes/ViewFactory.php index b082798..23f3957 100644 --- a/classes/ViewFactory.php +++ b/classes/ViewFactory.php @@ -33,14 +33,32 @@ class ViewFactory } $view = new Smarty(__DIR__ . '/../templates/'); + + $uri = $request->getUri(); if (in_array('https', $request->getHeader('X-Forwarded-Proto'))) { - $request = $request->withUri($request->getUri()->withScheme('https')->withPort(443)); + $uri = $uri->withScheme('https')->withPort(443); + } + + // set values from X-Forwarded-* headers + $host = current($request->getHeader('X-Forwarded-Host')); + if ($host) { + $uri = $uri->withHost($host); + } + + $port = current($request->getHeader('X-Forwarded-Port')); + if ($port) { + $uri = $uri->withPort(intVal($port)); + } + + $path = current($request->getHeader('X-Forwarded-Path')); + if ($path) { + $uri = $uri->withBasePath($path); } /** @var LocaleManager $localeManager */ $localeManager = $container->get('locale'); - $smartyPlugins = new SmartyPlugins($container->get('router'), $request->getUri()->withUserInfo(null)); + $smartyPlugins = new SmartyPlugins($container->get('router'), $uri->withUserInfo(null)); $view->registerPlugin('function', 'path_for', [$smartyPlugins, 'pathFor']); $view->registerPlugin('function', 'base_url', [$smartyPlugins, 'baseUrl']); $view->registerPlugin('block', 't', [$localeManager, 'smartyTranslate']); diff --git a/index.php b/index.php index 7368054..137e1fd 100644 --- a/index.php +++ b/index.php @@ -10,6 +10,7 @@ use Alltube\ErrorHandler; use Alltube\LocaleManagerFactory; use Alltube\LocaleMiddleware; use Alltube\LoggerFactory; +use Alltube\RouterPathMiddleware; use Alltube\ViewFactory; use Slim\App; use Slim\Container; @@ -31,7 +32,9 @@ try { // Locales. $container['locale'] = LocaleManagerFactory::create(); + $app->add(new LocaleMiddleware($container)); + $app->add(new RouterPathMiddleware($container)); // Smarty. $container['view'] = ViewFactory::create($container);