mezzio / mezzio-swoole

Swoole support for Mezzio

Home Page:https://docs.mezzio.dev/mezzio-swoole/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

  1. Setup a mezzio application
  2. Add swoole
  3. Configure this in a Docker environment with an entrypoint or cmd to run ./vendor/bin/laminas mezzio:swoole:start
  4. Create a route which is not the root, e.g. /foo with a FooHandler
  5. 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!