Skip to content

Python: Model Django request handler without route#4864

Merged
yoff merged 12 commits into
github:mainfrom
RasmusWL:django-request-handler-without-route
Jan 14, 2021
Merged

Python: Model Django request handler without route#4864
yoff merged 12 commits into
github:mainfrom
RasmusWL:django-request-handler-without-route

Conversation

@RasmusWL
Copy link
Copy Markdown
Member

I would strongly recommend going through this commit-by-commit 😉

Since I really want to use our existing infrastructure to model that we can
recognize something as a request handler without it having a route, we need this
as a separate concept. All tests have been adjusted.

The early modeling was based on flask, where all request-handling is based on
handling requests from a specific route. But with the standard library handling
and handlers without routes, the naming had to change.
A bit scary that we don't have any tests to indicate that I forgot to add this :O
Not doing so earlier was just a mistake.
Since this was causing a CI error.

also changed things a bit so we do it in a consistent way :)
I accidentially deleted that line :D
Copy link
Copy Markdown
Contributor

@yoff yoff left a comment

Choose a reason for hiding this comment

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

Generally looks fine. I had to think it through, but it seems right that there are route setups, which have request handlers. Routed parameters are a concept associated with route setups, and "handled routed parameters" is a concept associated with request handlers. The latter is currently also called routed parameters, should we consider renaming it?


/** Gets a function that will handle incoming requests for this route, if any. */
Function getARouteHandler() { result = range.getARouteHandler() }
Function getARequestHandler() { result = range.getARequestHandler() }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could this return a RequestHandler? (likewise in Range)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was something I struggled a bit with myself. Thanks for pointing it out, I should definitely have added a comment about this myself.

With the current setup, since the result of getARouteHandler is a Function. This means if you're modeling a web-library that uses "route to specific function/class" pattern (like flask/Django/Tornado), it's easy to specify the request handler function: Example of defining a route-setup in flask.

If we changed the result of getARouteHandler to be a HTTP::Server::RequestHandler, then we need to write some boiler code to make things work. Why? Since RequestHandler doesn't include any functions by default, we need a separate class to extend HTTP::Server::RequestHandler::Range before getARouteHandler can have a valid result.

Writing this up, it seems like I was faced with a trade-off between making it easy to write library models, and using library models, and I chose to make it easy to write them. That's probably the wrong trade-off. Can I fix this in a separate PR? I know deep down in my engineering heart that I should probably do it in this PR since this is the PR that introduces the concept, but I also know that it'll probably take me a bit of time, and I also have an urge to get this (and the Tornado PR) merged 😄 Let me know what you think 😉

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Doing it in a separate PR is probably fine, especially if it will touch many separate places. That PR will just need some explanatory text to not be confusing. If that is now the intention, we might add a comment already now to that effect.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sure, added a comment now 😊

Comment thread python/ql/src/semmle/python/Concepts.qll Outdated
Comment thread python/ql/src/semmle/python/frameworks/Django.qll
@RasmusWL
Copy link
Copy Markdown
Member Author

it seems right that there are route setups, which have request handlers. Routed parameters are a concept associated with route setups, and "handled routed parameters" is a concept associated with request handlers. The latter is currently also called routed parameters, should we consider renaming it?

That doesn't match my understanding. My understanding is that specific URL-patterns in route setups can make web frameworks pass part of the URL to parameters of the function handling the request. These parameters are "routed parameters" (I think I invented this term myself, since different frameworks calls this different things).

@RasmusWL RasmusWL requested a review from yoff January 11, 2021 11:25
@yoff
Copy link
Copy Markdown
Contributor

yoff commented Jan 11, 2021

My understanding is that specific URL-patterns in route setups can make web frameworks pass part of the URL to parameters of the function handling the request. These parameters are "routed parameters" (I think I invented this term myself, since different frameworks calls this different things).

Ok, so we agree that inherent in the route setup is the fact that part of the url is passed on. I should like a name for those parts and for that to be used with the associated get-function of the route setup. A handler for such a route then may or may not actually be ready to handle being passed such a thing, but if it is, we call it a routed parameter. I would expect that we could write a query saying "Here is a route setup and here is one of its handlers. The route may pass on this part of the url, but that handler will not handle it". Is that expectation off?

@RasmusWL
Copy link
Copy Markdown
Member Author

My understanding is that specific URL-patterns in route setups can make web frameworks pass part of the URL to parameters of the function handling the request. These parameters are "routed parameters" (I think I invented this term myself, since different frameworks calls this different things).

Ok, so we agree that inherent in the route setup is the fact that part of the url is passed on. I should like a name for those parts and for that to be used with the associated get-function of the route setup. A handler for such a route then may or may not actually be ready to handle being passed such a thing, but if it is, we call it a routed parameter. I would expect that we could write a query saying "Here is a route setup and here is one of its handlers. The route may pass on this part of the url, but that handler will not handle it". Is that expectation off?

I see your point. I didn't really consider this, but I think it's a good idea! Being able to write such a query would be nice, but for sure not something you can today 😬

Having such a setup might also make it easier to get to a point where we can write any(DjangoRequestHandler handler).getRequestParam()

@yoff
Copy link
Copy Markdown
Contributor

yoff commented Jan 14, 2021

I see your point. I didn't really consider this, but I think it's a good idea! Being able to write such a query would be nice, but for sure not something you can today 😬

Having such a setup might also make it easier to get to a point where we can write any(DjangoRequestHandler handler).getRequestParam()

Cool. This meaning some rejigging of interfaces, is that something you would rather postpone or sort out right away? Is it enough work to be shunted to a separate PR?

@RasmusWL
Copy link
Copy Markdown
Member Author

This meaning some rejigging of interfaces, is that something you would rather postpone or sort out right away? Is it enough work to be shunted to a separate PR?

No I really want to merge this PR now, since there are 2 other PRs that build on top of this PR. So it will become much easier (for me) to do proper cleanups after merging those 2 PRs as well.

Although we have agreed that we can make improvements to the way our Concepts are modeled (yay), I don't see it as a blocker, and the changes present in these 3 PRs should still add a good deal of value without perfectly modeled Concepts (in my view)

Copy link
Copy Markdown
Contributor

@yoff yoff left a comment

Choose a reason for hiding this comment

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

Happy to merge this now and postpone improvements.

@yoff yoff merged commit c69b776 into github:main Jan 14, 2021
@RasmusWL RasmusWL deleted the django-request-handler-without-route branch January 14, 2021 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants