Skip to content

Route variable with slash at the end makes redirect #29673

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

Closed
dzamyatin opened this issue Dec 23, 2018 · 6 comments
Closed

Route variable with slash at the end makes redirect #29673

dzamyatin opened this issue Dec 23, 2018 · 6 comments

Comments

@dzamyatin
Copy link

Symfony version(s) affected: 4.2.1

Description
I have a redirect problem with urls which contain variable with part of some path at the end, like this:

foo/somefolder/somefolder/

My route config for this looks like:

/**
     *@Route(
     *     "/some/{path}",
     *     methods={"GET"},
     *     requirements={"path"=".+"}
     * )
*/

The problem is when variable path contain slash at the end of string i get redirect to path without slash but the slash it is a part of variable

Possible Solution
Check if the end of the route is a variable don't make a redirect

@nicolas-grekas
Copy link
Member

Can you please check 4.2@dev? It's been fixed recently I think.

@dzamyatin
Copy link
Author

Nope, it doesn't working for me. But when i commented out that place my problem was solved.

somewhere here
vendor/symfony/routing/Matcher/Dumper/PhpMatcherTrait.php:133

if ('/' === $pathinfo || (!$hasTrailingSlash ? '/' !== $pathinfo[-1] || !preg_match($regex, substr($pathinfo, 0, -1), $n) || $m !== (int) $n['MARK'] : '/' === $pathinfo[-1])) {
    // no-op
} elseif ($this instanceof RedirectableUrlMatcherInterface) {
    return null;
} else {
    continue;
}

@nicolas-grekas
Copy link
Member

Note that the redirection is expected. What's not expected is the slash being part of the var.

@Tobion
Copy link
Contributor

Tobion commented Dec 24, 2018

The redirection is not expected. The requirement for the variable allows the slash (.+). How else would you achieve exactly what is asked here?

@nicolas-grekas
Copy link
Member

The current logic is the following:

  • when a route is declared with a trailing slash, the trimmed-slash url is redirected to the one with the slash
  • when a route is declared with no trailing slash, the slashed url is redirected to the trimmed-slash one

That includes routes with slash-greedy requirements: when the same greedy requirement matches both the slashed and the trimmed-slash URLs, only one of them is considered the canonical one and a redirection happens.

So yes, the current behavior is expected.

We could fine tune this logic and make an exception when a trailing slash-greedy requirement is declared with no explicit trailing slash after it. (ie disable any redirections for /foo/{.*} but keep it for /foo/{.*}/. That would mean /foo/bar and /foo/bar/ wouldn't trigger the redirection for route /foo/{.*}, breaking the "not-semantics" property of trailing slashes for catch-all routes. Which might be legit afterall.

@Tobion
Copy link
Contributor

Tobion commented Dec 24, 2018

I'm pretty sure this redirection did not happen before and thus is a bc break. Your suggested solution seems necessary.

nicolas-grekas added a commit that referenced this issue Jan 29, 2019
…ith no explicit slash (nicolas-grekas)

This PR was merged into the 4.1 branch.

Discussion
----------

[Routing] dont redirect routes with greedy trailing vars with no explicit slash

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #29673 #29734 #29575
| License       | MIT
| Doc PR        | -

From the linked issue:

> The current logic is the following:
> - when a route is declared with a trailing slash, the trimmed-slash url is redirected to the one with the slash
> - when a route is declared with *no* trailing slash, the slashed url is redirected to the trimmed-slash one
>
> That includes routes with slash-greedy requirements: when the same greedy requirement matches both the slashed and the trimmed-slash URLs, only one of them is considered the canonical one and a redirection happens.
>
> We could fine tune this logic and make an exception when a trailing slash-greedy requirement is declared with no explicit trailing slash after it. (ie disable any redirections for `/foo/{.*}` but keep it for `/foo/{.*}/`. That would mean `/foo/bar` and `/foo/bar/` wouldn't trigger the redirection for route `/foo/{.*}`, breaking the "not-semantics" property of trailing slashes for catch-all routes. Which might be legit afterall.

This PR implements this fine tuning, as that's the most BC behavior (and thus the correct one).
See #30012 for `testGreedyTrailingRequirement` in action on 3.4 as a proof.

Commits
-------

2bb8890 [Routing] dont redirect routes with greedy trailing vars with no explicit slash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants