sanic
sanic copied to clipboard
Rewrite request and re-route
Is there an existing issue for this?
- [X] I have searched the existing issues
Is your feature request related to a problem? Please describe.
Web servers such as Apache, Nginx and Caddy make heavy use of rewrites, which are essentially internal redirects. Rather than ask the client do another request some place else (redirect), the server while handling a request itself determines a new location and handles it internally, and the client doesn't see any of this but gets a response from the rewritten request.
Typically the path of the request is altered in a redirect, although other changes are also possible.
I am seeing use for this at least within Sanic's own static files handler, that may need rewrite to index.html
after determining the target was a directory, and then re-enter itself (rather than bail out by simple return file(path / "index.html")
that lacks the features of the normal static file handler. But this is in general a powerful tool for implementing some odd flows.
Describe the solution you'd like
In a handler or middleware one could
return sanic.response.rewrite(request, url="/new/path", headers=...)
After this Sanic would re-run routing to find a matching handler and restart as if it were a new request.
Alternatively this could be a request accessor: (I think I prefer this)
return request.rewrite(**changes)
Additional context
Partially read body, or streaming if body has already been consumed are hard to support. Presumably the connection handling (http1.py etc) keep track of request body and response status even if the Request object is altered, making this less of an issue (even in presence of incorrect content-length
header).
Probably needs to keep a count of rewrites per request to avoid accidental infinite loops.
(I think I prefer this)
I would agree. The response module seems more like a place for creating response objects which is not really what this proposal is doing. My initial impression would be to raise a RewriteException
and catch that inside the app's handle_request
, swap out the path on a new Request
object and call handle_request
again.
Hopefully Sanic supports this, I can ditch the routing createWebHistory
mode in the Nginx hosted Vue.js application and instead use app.static("/"...)