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

IncomingRequest - Trim trailing slash #4974

Merged
merged 2 commits into from
Sep 23, 2021

Conversation

najdanovicivan
Copy link
Contributor

Description
If trailing slash is forced via apache or nginx the router will be unable to find the appropriate route. The router will try to match path from request uri with trailing slash but it is impossible to define such route in the route collection since slash is used as separator.

This changes the way request uri is handled so that trailing slash is removed at the end which enables the router to handle the url in both cases with or without trailing slash

Checklist:

  • Securely signed commits
  • [] Component(s) with PHPdocs
  • [] Unit testing, with >80% coverage
  • [] User guide updated
  • Conforms to style guide

Copy link
Member

@paulbalandan paulbalandan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test for this?

@paulbalandan paulbalandan changed the title IncommingRequest - Trim trailing slash IncomingRequest - Trim trailing slash Jul 29, 2021
@najdanovicivan
Copy link
Contributor Author

@paulbalandan Since this is only being handled inside IncomingRequest instead of Router I've added test for the Incoming request.

With this implementation URI path will always be returned without trailing slash. I'm not sure it this is the best way to do it since with this implementation it is impossible to detect if url have trailing slash or not. The better solution might be to handle the stripping of slash inside Router class instead of stripping it from the URI path in incoming request.

With current setup $request->getPath() will return the same value of 'fruits/banana' for both $_SERVER['REQUEST_URI'] = '/index.php/fruits/banana/'; and $_SERVER['REQUEST_URI'] = '/sub/folder/index.php/fruits/banana';

@MGatner
Copy link
Member

MGatner commented Jul 29, 2021

I'm hesitant about this one with all the URI issues we've had in the past. My hunch is that we need a way to distinguish between fruits/banana and fruits/banana/, but I'm not sure if that actually matters? Anyone know what the RFC says about trailing slashes?

@najdanovicivan
Copy link
Contributor Author

@MGatner looking at PSR-7 underlying RCF document I found this https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.4

But I also found this middleware https://github.com/middlewares/trailing-slash which can do a redirection to force urls either with or without trailing slash

But none of this defines if there should be slash there or no

@MGatner
Copy link
Member

MGatner commented Aug 3, 2021

After reading those and looking around a little more I think it is more clear that trailing slashes may differentiate a URI. For framework purposes I think this means we need to leave the URI intact for the developer. However, I also think it is logical for the Router to treat them as equivalent, since we don't have a meaningful way to differentiate the trailing slash in Route Collection anyways.

Instead of changing IncomingRequest, check out Router::checkRoutes(). There are two ltrim() calls in there that could be changed to trim() to ignore trailing slashes during route comparison. If you decide to implement this, we would need some updated test cases and maybe a side note in the User Guide.

@najdanovicivan
Copy link
Contributor Author

Sure thing. I also found another issue that will occur if this is done in such way. Web Page Caching uses url to generate the md5 filename which means urls with slash and without will have different caches which in the end will result in cache using double amount of space if urls work with and without slash.

So maybe generating the cache filename should also strip the trailing slash

@lonnieezell
Copy link
Member

I don't see a problem stripping trailing slash for the cache filename.

@najdanovicivan
Copy link
Contributor Author

I've updated the code trim the path in Router class. I also fixed the trailing slash in page cache and while I was there I added method to be used for manually purging single cached page

Copy link
Member

@MGatner MGatner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better! I like the new method but it will need test coverage. Please either add the tests or pull the method for a separate PR.

system/CodeIgniter.php Outdated Show resolved Hide resolved
@najdanovicivan
Copy link
Contributor Author

I've split the page cache in separate PR #5073 so that this one can be merged

Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com>
@paulbalandan paulbalandan merged commit 9843737 into codeigniter4:develop Sep 23, 2021
@najdanovicivan najdanovicivan deleted the request-uri-fix branch November 5, 2021 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants