sanic icon indicating copy to clipboard operation
sanic copied to clipboard

Rewrite request and re-route

Open Tronic opened this issue 1 year ago • 3 comments

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.

Tronic avatar Oct 15 '23 03:10 Tronic

(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.

ahopkins avatar Nov 12 '23 08:11 ahopkins

Hopefully Sanic supports this, I can ditch the routing createWebHistory mode in the Nginx hosted Vue.js application and instead use app.static("/"...)

shaoerkuai avatar Jun 26 '24 10:06 shaoerkuai