Routing not working because of wrong URI
thexpand opened this issue · comments
Bug Report
Summary
I have set up Swoole with Mezzio using the mezzio/mezzio-swoole
package. I'm running the application with Docker, based on the phpswoole/swoole:4.6-php7.4-alpine
image. I have set up 2 routes in the config/routes.php
, one is /foo
another is /bar
. However, when I try to open /foo
or /bar
in the browser, it matches the /
route instead, which is non-existent in my case and it falls back to the NotFoundHandler
.
Current behavior
I tried to intercept the request by placing a middleware before the RouteMiddleware
to see what does the request contain and I tried printing out the $request->getUri()->getPath()
. Regardless of what URL I use to make the request to, the resulting URI path is always /
.
How to reproduce
- Setup a mezzio application
- Add swoole
- Configure this in a Docker environment with an entrypoint or cmd to run
./vendor/bin/laminas mezzio:swoole:start
- Create a route which is not the root, e.g.
/foo
with aFooHandler
- Try to visit the
/foo
URL
Expected behavior
The expected behavior would be for the application to match the request to the specified route. For some reason it seems that Swoole/Mezzio does not recognize the URI path and always shows and matches the root /
instead.
I cannot recreate the issue.
Here were my steps:
- Started a new Mezzio application:
composer create-project mezzio/mezzio-skeleton mezzio-swoole-59
(I used defaults, except that I chose Plates for my templating.) - Add "foo" and "bar" handlers:
$ ./vendor/bin/mezzio handler:create "App\Handler\FooHandler" $ ./vendor/bin/mezzio handler:create "App\Handler\BarHandler"
- I registered these as routes in the
config/routes.php
file:$app->get('/foo', App\Handler\FooHandler::class, 'foo'); $app->get('/bar', App\Handler\BarHandler::class, 'bar');
- I installed mezzio-swoole:
composer require mezzio/mezzio-swoole
- I configured a mezzio swoole HTTP server, by creating a
config/autoload/swoole.global.php
file with the following contents:return [ 'mezzio-swoole' => [ 'swoole-http-server' => [ 'host' => '0.0.0.0', 'port' => 9000, ], ], ];
- I created an entrypoint script,
bin/entrypoint.sh
, with the following contents, and made it executable:#!/bin/sh echo "Starting web server" exec vendor/bin/laminas mezzio:swoole:start
- I created a
docker-compose.yml
file with the following contents:version: '3.3' services: php: image: phpswoole/swoole:4.6-php8.0 ports: - "9000:9000" volumes: - .:/var/www - ./bin/entrypoint.sh:/usr/local/bin/entrypoint working_dir: /var/www entrypoint: /usr/local/bin/entrypoint logging: options: max-size: 50m
- I ran
docker-compose up
- I then accessed each of the following URLs using HTTPie:
- localhost:9000/foo
- localhost:9000/bar
- localhost:9000/api/ping
Each of these resolved perfectly for me.
I tried the above using each of phpswoole/swoole:4.6-php7.4 and phpswoole/swoole:4.6-php7.4-alpine as the image, and it worked the same in each case.
Is it possible you forgot to add mezzio-swoole configuration?
@weierophinney I found the culprit.. it was my bad. Initially, when I've set up my application (probably 6-7 months ago), I removed the following lines from my config/config.php
, because I wasn't using Swoole or wasn't planning of using Swoole at all:
// Swoole config to overwrite some services (if installed)
class_exists(\Mezzio\Swoole\ConfigProvider::class)
? \Mezzio\Swoole\ConfigProvider::class
: function(): array { return[]; },
Yesterday when I tried to turn on Swoole, I added the ConfigProvider
, but I added it at the top of the ConfigAggregator
, so basically Swoole's ConfigProvider couldn't overwrite the RequestHandlerRunner
, which resulted in that the application was using Mezzio's standard runner instead of Swoole's one.
Thank you Matthew, for taking the time to look into details for such a stupid mistake of mine.
I think about closing the issue, as I don't think it could progress any further than this. However, I think that's a good point of discussion - maybe we can follow up on this and include some hint in the documentation, what do you think?
EDIT: Additionally, maybe to include this is as a PHP doc block in the ConfigProvider of mezzio/mezzio-swoole
that it should be placed after the standard config providers.
@thexpand I'm adding a note to the ConfigProvider
now. I was about to add a cookbook entry... and then realized I'm even more confused by your report than before.
Why?
You claim that youd' removed the Swoole config provider configuration from your application's configuration... and yet you also claimed that you were running via Docker using ./vendor/bin/laminas mezzio:swoole:start
as the entrypoint. What's odd about this is that ... it shouldn't work. At all. The container wouldn't have a running daemon at that point, as the script would just start and immediately stop. It might render the home page, but there'd be no port listening.
I'm really curious what the full story is!
@thexpand Never mind, I figured out how to reproduce what you did: I just moved the mezzio-swoole ConfigProvider
entry to the top of the list in the config/config.php
file, as it would be if it was injected via the laminas-component-installer. Once I did, the swoole server would start, but I'd get back the 200 response with the home page for every request, just like you detailed.
I've written a cookbook entry for this now in #81. 😄
@weierophinney Yes, exactly - it was all because of misplacing the ConfigProvider of the Swoole package. I looked through the PR for the cookbook and it all looks great!