Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for mezzio to be run in a sub directory of the web server #69

Open
mosbth opened this issue Apr 21, 2021 · 6 comments
Open

Allow for mezzio to be run in a sub directory of the web server #69

mosbth opened this issue Apr 21, 2021 · 6 comments
Labels
Enhancement New feature or request

Comments

@mosbth
Copy link

mosbth commented Apr 21, 2021

Feature Request

Allow for mezzio to be run in a sub directory of the web server, out of the box, without need of configuration.

Q A
New Feature yes
RFC no
BC Break maybe

Summary

When installing mezzio it does not work, out of the box, when running the website in a sub directory.

I found an article on "Cookbook Using Mezzio from a subdirectory", but that contains a series of actions and configurations.

My humble opinion is that it should work in a sub directory out of the box, like for example the Laravel, Symfony and Yii Framework does. Doing so would make it easier for first come users to adapt the framework since it has less restrictions on the development- and production environment in which it runs.

My reason for this opinion is mainly from an educational perspective. When doing education using Mezzio, one can not always expect the students to have their own servers. We for example are using a shared server where the students publish their websites. This can also be thought of as a usability perspective.

I can not say if this request would interfere with other existing features of mezzio. This was just my first experience of using mezzio. I did not see any notes on this requirement while I was browsing the documentation (however I might have missed it...).

How to repeat

  1. I install mezzio and use the defaults.
composer create-project mezzio/mezzio-skeleton app

I access the website and gets this.

2021-04-21_17:30:53_502x90

  1. I reinstall and use Plates template system.

I then get this response.

2021-04-21_17:33:10_654x390

@boesing
Copy link
Member

boesing commented Apr 22, 2021

Imho, this is all about webserver configuration.

You can work with mod_rewrite (apache) and location regex (nginx) which remove parts of the path so PHP does not have to handle all that stuff.
If you dont want to configure your webserver like that, you can create your own middleware and add it to the pipeline.
That middleware could remove the subdirectory from your ServerRequestInterface like this:

final class RemoveBasePathMiddleware implements MiddlewareInterface
{
    private string $basePath;

    public function __construct(string $basePath)
    {
        $this->basePath = $basePath;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        return $handler->handle($this->removeBasePathFromRequest($request));
    }

    private function removeBasePathFromRequest(ServerRequestInterface $request): ServerRequestInterface
    {
        $uri = $request->getUri();
        return $request->withUri(
            $uri->withPath(
                (string) \preg_replace(sprintf('!^%s!', $this->basePath), '', $uri->getPath())
            )
        );
    }
}

When adding this as the very first entry in your pipeline.php like the example below, the router will properly match:

$app->pipe(new RemoveBasePathMiddleware('/laminas-mezzio/app/public'));

If this middleware might be something you would like to see provided by mezzio directly, feel free to use my code and create a PR for https://github.com/mezzio/mezzio-helpers 👍🏼


The reason, why this wont work without any "configuration" (either webserver or pipeline) is, that there is absolutely no way to handle endless combinations of directory structures which might occur, so I don't think that this behavior should become a default thing for mezzio. But having a middleware available in the helpers is definitely an option.


Oh, and the app folder should never be available via any webserver configuration. This might lead to things you dont want to happen, like someone reading out your vendor/composer/installed.json to see which versions of your dependencies are installed.
Thats where the public folder is for. This has to be the document root, even tho, you want to run it in subdirectories. And here we are again with the webserver configuration. 🤷🏼‍♂️

@froschdesign
Copy link
Member

But having a middleware available in the helpers is definitely an option.

Which can be activate or deactivate during the installation process via the installer and by using mezzio-tooling / laminas-cli.

@froschdesign
Copy link
Member

@mosbth
Thanks for your feedback! 👍

When installing mezzio it does not work, out of the box, when running the website in a sub directory.

You use a local environment for development and there you can follow the first two steps of the quick start guide:

This uses PHP's built-in web server and it runs without further configuration on your local machine from every (sub) directory.

My humble opinion is that it should work in a sub directory out of the box, like for example the Laravel, Symfony and Yii Framework does.

…and laminas-mvc. 😃

We for example are using a shared server where the students publish their websites.

@boesing has already given important security warning: The vendor directory must not be accessible to the public.
Here is an article on this topic: https://thephp.cc/news/2020/02/phpunit-a-security-risk

@boesing
Copy link
Member

boesing commented Apr 26, 2021

I've created a feature request in the mezzio-helpers component as I think that this middleware is a good addition.
I've also added the integration to the mezzio-skeleton for this, so it can be configured during installation process and (if needed) afterwards via laminas-cli command 👍🏼

@boesing boesing added Awaiting Author Updates Enhancement New feature or request and removed Enhancement New feature or request labels Apr 26, 2021
@mosbth
Copy link
Author

mosbth commented Apr 28, 2021

Thanx for the responses!

TLDR;

If I use the laminas-router it will (likely) work in my setup.This router does take the baseurl into account. That is an acceptable solution for me.

Perhaps this issue is not so trivial one could expect at a first glance, there might be several things to consider, if one want to implement this feature, including the following.

  1. Is this in general a good suggestion for Mezzio usability for first time users in development environment? Probably yes.
  2. Is it good to have it like this in production? Depends on how one implements it.
  3. Can Mezzio detach the public/ directory from its installation base, to allow to be run in a subdirectory of the webserver, and have its installed base in another directory? Yes, its seems like the frontcontroller partly supports that indirectly through the PHP include path.
  4. Could this change have impact on how urls are generated in the framework? Maybe (RemoveBasePathMiddleware to run mezzio application within a subdirectory mezzio-helpers#13 (comment)).
  5. Could this have impact on how one should register the paths to a route? Maybe.

Anyway, there do exists a more simple solution to this feature requests. Here are some background on it.

While I was trying out the suggestion on the RemoveBasePathMiddleware I did not see any effect on using it (uncertain why). So I did dig a bit deeper and tried out the different routers.

I did three new installations and I selected the three different routers to try them out with the following result.

  1. ❎ Aura.Router
  2. ❎ FastRoute
  3. ✔️ laminas-router

The Aura.Router did not support installation in a sub directory, the same with the FastRoute that I used initially.

However, the laminas-router did support it and worked out of the box.

I tried the following routes where hello is a newly added route for test purpose:

http://localhost:11074/laminas-mezzio/app/public/
http://localhost:11074/laminas-mezzio/app/public/api/ping
http://localhost:11074/laminas-mezzio/app/public/hello

The following examples are for the url http://localhost:11074/laminas-mezzio/app/public/hello and the expected result is $path='/hello' or perhaps $path='hello' depending on how one sees it.

Aura.Router extracts the path like this.

$path = $request->getUri()->getPath();
// '/laminas-mezzio/app/public/hello'

FastRoute extracts the path like this.

$path = rawurldecode($request->getUri()->getPath());
// '/laminas-mezzio/app/public/hello'

The laminas-router extracts the path like this (simplified).

$this->setBaseUrl($request->getBaseUrl());
$uri = $request->getUri();
$baseUrlLength = strlen((string) $this->baseUrl) ?: null;
// Using the baseurl, attached to to Request object, it calculates the $path and removes the baseurl from the path

So, to summarize.

If I use the laminas-router it will (likely) work in my setup.This router does take the baseurl into account. That is an acceptable solution for me.

To my knowledge, the FastRoute only uses the concept of path and not PSR Requests so if that router should support the "removal of the baseurl" then this could/should be an implementation in how Mezzio integrates with that router (Mezzio\Router\FastRouteRouter) and what path is supplied to the router.

It looks like the Aurora router works on the PSR Request (Aura\Router\Matcher), so perhaps there is some configuration option within that router to support the removal of the baseurl. I can not say. I did find one issue (auraphp/Aura.Router#154) on their GitHub repo related to the baseurl, but no fix or solution.

@harikt
Copy link
Contributor

harikt commented Feb 3, 2022

Hi,

I don't recall how laminas is using aura router under the hood. But just to mention the base path is already supported in 3.x . See docs http://auraphp.com/packages/3.x/Router/other-topics.html#3-4-7-3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants