-
-
Notifications
You must be signed in to change notification settings - Fork 862
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
Use raw_path
instead of path
in the router to be able to differentiate requests which include %2F
#1828
Conversation
…inguish between paths when there are url-encoded slashes.
…distinguish between routes with path conversions when path parameters have URL-encoded slashes.
raw_path
instead of path
in the router to be able to differentiate requests which include %2F
Compare and contrast with a more well established Python web framework. What does Flask do? |
@ChiliJohnson Are you still interested in this PR? |
Yes I'm definitely still interested! As far as Flask / Werkzeug / WSGI go, it seems that PEP 3333 implicitly requires that the path variable (used for routing in Flask/Werkzeug) be pre-unquoted by time they reach the app. So as a result, Flask also has this inability to distinguish between Here are a few relevant discussions about this in WSGI land:
I guess the question here is do we want Starlette to match this behavior with the WSGI-based projects, or use this feature as a point of differentiation from them? It seems like it could be nice to give app developers more control in how they route requests, but at the same time I can see benefit to Starlette acting more like the other players in this space |
My vote would be to move forward with this change. I like the idea of giving developers more power. One thing I’m not immediately clear on is what does this break? Can it brake any Starlette or FastAPI applications? Will this require changes in FastAPI itself? |
In any case, the decision other web framework made have influence in our decisions here... Besides that, it doesn't look like there's many people interested in this over the years... |
This would break web apps relying on the fact that A complicating factor here is that there's the potential that an upstream web server or reverse proxy may be pre-unquoting the URL before we even know about it. In the case of Uvicorn + Starlette (including the changes from this PR) this doesn't happen, but I can see how it would be possible; and in that case the behavior of routing should remain exactly the same |
Is PEP 3333 (implicitly) in conflict with this explicit description in RFC 3986 aka STD 66? I should think the explicit RFC/STD takes precedence here.
|
Interpreting Screenshot: |
Thanks for the great research @kefir- ! From what you've posted it definitely seems like the current behavior of the router is in breach of these core web standards; I guess the question now is is there too much inertia coming from all the apps out there which maybe (intentionally or unintentionally) depend on this incorrect behavior? Maybe it makes sense to release this as part of a new major version? |
I'll add another source. That is RFC 3986 section 2.2, which states:
|
I have a concrete example of why this is a problem. I'm creating an HTTP proxy to simplify authentication around AWS's codeartifact and some URLs can contain So far the only way I found to work around this is to identify those queries and URL-encode the decoded URL string (which should have never been decoded in the first place). Argument extracted from the path should indeed be URL-decoded but the Request.url property should not be decoded. Please fix this. |
Related: django/asgiref#51 |
@simonw If you have time, could you give me your opinion here? 🙏 |
|
I proposed this functionality in #1827 and added a bit of color in there, this was a quick-and-dirty change so I don't really have a good sense for any far-reaching implications of this change. But it was relatively-simple to implement so I thought I'd give it a shot.
Using
raw_path
instead of the pre-parsedpath
in the router would enable the it to distinguish between paths which include URL-encoded slashes, e.g. betweenmy%2Froute/example
andmy/route/example