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

host() in routes with schema and/or port does not work #151

Open
Teran123 opened this issue Jul 17, 2024 · 4 comments
Open

host() in routes with schema and/or port does not work #151

Teran123 opened this issue Jul 17, 2024 · 4 comments
Labels
status:ready for adoption Feel free to implement this issue. type:bug Bug

Comments

@Teran123
Copy link

Teran123 commented Jul 17, 2024

->getHost() . $path);

What steps will reproduce the problem?

Specify host() with a schema and/or port in routes
As example:

Group::create("/{_language}")
        ->routes(
            Route::get("/")
                ->action([SiteController::class, 'index'])
                ->name("site.index"),
        )
        ->host("http://localhost:8080") // doesn't work
or
        ->host("http://localhost") // doesn't work
or
        ->host("localhost:8080") // doesn't work
or
        ->host("localhost") // works fine, but only if the site is on port 80

What is the expected result?

When I go to the url http://localhost:8080 in my browser, I will see the page rendered by SiteController::index

What do you get instead?

404 error

Additional info

The problem spot is in the UrlMatcher class, when calling dispatch() on line 107: https://github.com/yiisoft/router-fastroute/blob/master/src/UrlMatcher.php#L107
Only host and path are specified in the $uri parameter.
But schema and port are returned in getUri() separately from host.

So, for example, if this dispatch() call looked something like this, there wouldn't be a problem:

$uri = $request->getUri();
$scheme = $uri->getScheme();
$host = $uri->getHost();
$port = $uri->getPort() ? ":{$uri->getPort()}" : "";
$result = $this
    ->getDispatcher($dispatchData)
    ->dispatch($method, "{$scheme}://{$host}{$port}{$path}");
Q A
Version ^3.0
PHP version 8.3.9 / 8.2.20
Operating system Linux
@samdark samdark added type:bug Bug status:ready for adoption Feel free to implement this issue. labels Jul 18, 2024
@samdark
Copy link
Member

samdark commented Jul 18, 2024

Thanks for reporting. Do you want to work on pull request w/ tests and the fix?

@Teran123
Copy link
Author

Thanks for reporting. Do you want to work on pull request w/ tests and the fix?

I don't write tests, so I don't)

I also want to add that my example solution is just an example, and the problem here is probably getHost() which returns the host not in the same form as I specified it in the routes - your team knows better :)

Here's another example:
If I want to use UrlGenerator to generate the absolute url of the route site.index from my example - I will be forced to re-specify the host in the form I have specified it in the routes.
I.e. like this (if without schema):

$uri = $request->getUri();
$host = $uri->getHost();
$port = $uri->getPort() ? ":{$uri->getPort()}" : "";
$urlGenerator->generateAbsolute(name: "site.index", host: "{$host}{$port}");

Instead, I would like to be able to generate an absolute url as follows:

$urlGenerator->generateAbsolute("site.index")

Or at least something like this:

$urlGenerator->generateAbsolute(name: "site.index", host: $uri->getHost())

or

$urlGenerator->generateAbsolute(name: "site.index", host: $currentRoute->getHost())

@ev-gor
Copy link
Contributor

ev-gor commented Nov 2, 2024

I don't think it's a bug. According to RFC 3986, a host is a part of a URI located between a scheme and a port. Therefore, this host method expects only a host (localhost in this case). However, you provided not just a host, but also a scheme and a port. That's why there is no match. This behavior is expected, in my opinion. Perhaps it should be specifically emphasized in the documentation.

@vjik
Copy link
Member

vjik commented Nov 7, 2024

If I want to use UrlGenerator to generate the absolute url of the route site.index from my example - I will be forced to re-specify the host in the form I have specified it in the routes.

No. Url generation works correct:

Route::get('/home/index')->name('index')->host('http://test.com:8080');

// Result: http://test.com:8080/home/index
$generator->generateAbsolute('index');

Problem with URL matching only.


I don't think it's a bug. According to RFC 3986, a host is a part of a URI located between a scheme and a port. Therefore, this host method expects only a host (localhost in this case). However, you provided not just a host, but also a scheme and a port. That's why there is no match. This behavior is expected, in my opinion. Perhaps it should be specifically emphasized in the documentation.

Good point. We should to decide whether to allow Route to have host, port and scheme in "host" property or host only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:ready for adoption Feel free to implement this issue. type:bug Bug
Projects
None yet
Development

No branches or pull requests

4 participants