8000 [Routing] Unexpected redirect with trailing slash · Issue #29575 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Routing] Unexpected redirect with trailing slash #29575

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
iquito opened this issue Dec 11, 2018 · 8 comments
Closed

[Routing] Unexpected redirect with trailing slash #29575

iquito opened this issue Dec 11, 2018 · 8 comments

Comments

@iquito
Copy link
Contributor
iquito commented Dec 11, 2018

Symfony version(s) affected: 4.1.8+

Description

Symfony now redirects routes with trailing slashes to routes without trailing slashes on its own, which seems unexpected and like a bad practice, as two URLs are treated equally which are not automatically equal by any official standards.

URLs in my application never have a trailing slash, and if a link points towards an URL with a trailing slash this should always be treated as a 404, which can then be captured and logged by my application to find out why there was an incorrect link. Symfony now decides on its own that an URL followed by a slash is equal to the same URL without the trailing slash and does an additional redirect, which seems like an arbitrary convention and is a BC break.

I also feel Symfony doing redirects bypassing the application is unexpected in its own way - I expect routes to be matched, but not Symfony to decide how to redirect URLs and changing my URLs. In my case this broke part of my application, because suddenly there was an additional unexpected redirect which was not issued by my application but by Symfony itself.

Possible Solution

As far as I can tell there is no way for me to bypass this functionality - no option to switch it off, nothing to do (I went through all Symfony documentation, and this now seems to be required behavior). Generally, I want to turn off ANY automatic redirection of Symfony, as this is the responsibility of my application.

So if this change really needs to happen, then there should be a possibility to turn it off. There might also be possibilities to make the router more succinct if the whole trailing slash or not part does not need to be in there, because matching something 1:1 must be a lot easier and less error-prone than also checking about trailing slashes or not.

@xabbuh
Copy link
Member
xabbuh commented Dec 12, 2018

Duplicate of #29011?

@iquito
Copy link
Contributor Author
iquito commented Dec 12, 2018

Ah I didn't find that issue before (read though some other related issues but which discussed different aspects of this redirection).

In my case it does not break the application because of the absolute URLs of the redirect, but because parts of my application are hopped over - Symfony redirects before the application decided if it should initialize the session via a kernel.view event listener, but then for logs in kernel.terminate it notices that no session exists. So the previous behavior (redirect no trailing slash to trailing slash) never occured, as I have no routes with a trailing slash. There are many possibilities in an application what could break because of this redirect, mine or the absolute URL scenarios are just some of them.

Introducing such a BC break in a bugfix version (4.1.8) also seems especially bad to me - that is exactly what you should not expect Symfony to do.

Having an option to either match routes exactly, or only redirect from no trailing slash to trailing slash (how Symfony has been doing it so far and which should be kept this way for BC reasons), or only redirect from trailing slash to no trailing slash, or both (4.1.8 behavior), would solve the problem.

@nicolas-grekas
Copy link
Member

Can you please try 4.1@dev? There have been some changes lately related to this. Maybe not exactly what you describe, but still I'd like to have your feedback after the latest changes.

@nicolas-grekas
Copy link
Member

BTW, might end up as a duplicate of #29673
See #29673 (comment)

@iquito
Copy link
Contributor Author
iquito commented Dec 24, 2018

This would fix some aspects of the problem, but I am not sure why these automatic redirects are there in the first place - what is the use case? I see these possible use cases:

  • There are typos or wrong links in the application itself (without trailing slash or with trailing slash), which means the automatic redirects by Symfony hide these errors and redirects to a valid route. Might be a valid use case, but if you are using named routes and the Symfony routing system in general this seems almost impossible, and throwing a 404 might be more beneficial long-term than just silently "fixing" the error while not fixing the root cause. Performance of an application suffers with every redirect, and just one additional (and in this case unnecessary) redirect can add a lot of latency which could be avoided.
  • People typing in the URL and forgetting the trailing slash (or adding it even though it is not needed): Nowadays this seems highly unlikely, people often don't even type in the domain name anymore but use search engines instead, or bookmarks, etc. I haven't had this case once in the last 5 years for tens of millions of page views, and I regularly go through all 404 to spot any possible problems.

So what in my case is causing these "bad" redirects, why have I been affected? For me it is only spiders and bots, who add additional slashes to links, who add query strings to links etc. to see if the application breaks, reveals something about itself, etc. Redirecting in these cases might even send the wrong signal and tell a bot that the URL was actually kind of right, and it hides the bad request to me, because Symfony silently fixes it.

For backwards compatibility reasons I see why you are still redirecting URLs without a slash to a matching route with a slash, as it would break some existing applications who (even for super bad reasons) depend on that kind of fix if you would remove it. Instead of adding this new redirect behavior the other way round (slash to no slash) I think you should instead deprecate the existing behavior - no redirects between slash or no slash and instead do exact route matching. If you disagree and think these redirects are sensible, there should be a good valid use case why these redirects are necessary - why they would happen to a substantial amount of users, why they would happen in a Symfony application which follows good practices, because I see no reason for the problem you are trying to solve to even occur - instead it adds a lot of complexity to the routing component with no visible benefit.

@Tobion
Copy link
Contributor
Tobion commented Dec 24, 2018

I think those redirects are good for usuability and should stay the default. Other websites even ignore trailing slash and match both URIs without redirect, which is worse and creates duplicate URIs, e.g.

But I can see that some people do not want or need this functionality. So I'm 👍 to create a config option to disable it.

@iquito
Copy link
Contributor Author
iquito commented Dec 24, 2018

What do you mean by "good for usability"? What is the specific use case of matching two different URLs the same way (or implying the are the same via redirect)? How would anybody get onto these slightly wrong URLs?

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
@nicolas-grekas
Copy link
Member

#30013 has fixed the BC break related to trailing slashes. I'm closing here are I don't think there is anything actionable - and also because returning a 3xx instead of a 4xx when we know we can is good defaults. Feel free to submit a feature to configure that if you really want it to happen.
Cheers.

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

6 participants
0