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

Allow disabling appending slash? #1246

Closed
taion opened this issue Jan 31, 2018 · 7 comments
Closed

Allow disabling appending slash? #1246

taion opened this issue Jan 31, 2018 · 7 comments
Labels

Comments

@taion
Copy link

taion commented Jan 31, 2018

We're using Werkzeug and Flask to build a REST API. In this context, we don't want the automatic behavior of appending trailing slashes, as this leads to asymmetries between GETs and other requests, and it's acceptable to be strict here.

Currently we need to use a custom rule class that hooks into internals (Rule.match and RequestSlash) to do this.

Would it make sense to add this as a first-order config option? Something like append_slash (to parallel the equivalent Django option) on URL maps?

@ThiefMaster
Copy link
Member

app.url_map.strict_slashes = False is all you need to avoid this.

@taion
Copy link
Author

taion commented Jan 31, 2018

That actually makes the route match when the slash is missing. I want it to 404.

@taion
Copy link
Author

taion commented Jan 31, 2018

The current behavior is:

Rule has trailing slash Path has trailing slash strict_slashes Result
N N True (match)
N N False (match)
N Y True 404
N Y False 404
Y N True 301
Y N False (match)
Y Y True (match)
Y Y False (match)

I want a 404 when the rule has a trailing slash but the path doesn't. Right now I'm doing this via:

class StrictRule(Rule):
    def match(self, path, method=None):
        try:
            result = super(StrictRule, self).match(path, method)
        except RequestSlash:
            return None

        return result

But I'd rather not reach into internals.

@aenglander
Copy link
Contributor

aenglander commented May 7, 2019

Using the custom rule would be the correct way to do this in Flask. We have decided internally not to try and create everything for everyone in rules. If you want a rule beyond what is offered as standard you would need to specify it. For Flask, you would set the url_rule_class to the new class. See the Flask docs for more information. https://flask.palletsprojects.com/api/#flask.Flask.url_rule_class)

@taion
Copy link
Author

taion commented May 7, 2019

@aenglander

Per #1246 (comment), the issue here is with the custom rule implementation. RequestSlash is explicitly marked as an internal exception per

class RequestSlash(RoutingException):
"""Internal exception."""
, so it's quite awkward to handle this in user code.

And while I certainly agree that base rules shouldn't support every possible use case, not matching on an absent trailing slash is a very common use case. For prior art, this pattern is one of the few that are explicitly exposed in Django config via APPEND_SLASH: https://docs.djangoproject.com/en/dev/ref/settings/#append-slash.

@davidism
Copy link
Member

davidism commented May 9, 2019

"Internal" in this case means "internally handled," not "for "internal use only." The code you've shown is fine to use.

@taion
Copy link
Author

taion commented May 9, 2019

@davidism Thank you for the clarification. I'll go ahead and go with this, then.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants