[Flow] Re: HTTP Reverse Proxy and "HTTP components"
Alexander Berl
a.berl at eol.de
Fri Apr 26 17:05:28 CEST 2013
Thanks for starting this thread Robert. I agree there are some things open for discussion and I'm glad my feature request brought this up now, rather than ending up with duplicate - or even worse, incompatible - work.
So, I'll just throw in what I have done so far in regards to a reverse proxy implementation and what I think some requirements are.
Basically, this idea started back a little more than a year ago or so, I remember I was even shortly in contact with Robert about my ideas for some Cache-Control AOP implementation, but I lost track as my free time for that project became short.
My first idea started with some basic page-caching mechanism, where I soon recognized that such a feature has to plug into the framework very early or otherwise completely work around it to reduce initialization overhead. I started with some pre-bootstrap code that would just map the URL to a static file, but dropped that idea pretty quickly as it just felt wrong and not *flowish*.
Pretty much at the same time, Robert was rewriting the HTTP part of Flow and I was glad about the new possibilities and that's where I started to go the route of my own RequestHandler that would easily be plugged into the normal bootstrap by giving it high priority and registering it at Package initialization.
The biggest problem was, that the Http\RequestHandler->handleRequest() method was not very flexible and did quite some work that my own RequestHandler also would have to do - namely creating the Request object from the environment, doing a minimal bootstrap and afterwards return the response. That's not DRY, so I wanted to avoid this duplication.
That's also when I lost track and now I came back to this project and found an easy solution to just do the essential bootstrap in my RequestHandler, which is just enough to make a request cache possible (you only get configuration, error handling and cache management), and then somehow forward my already created request object to the default RequestHandler. Therefore I created the change set https://review.typo3.org/#/c/20028/ - now only the essential bootstrap is run twice and this could even be prevented by doing some checks there to prevent duplicate execution.
So, as far as requirements go, that's what I would say the Framework needs to allow a good reverse proxy implementation:
- control what should be bootstrapped and provide a way so packages can "postpone" some bootstrap steps
- provide some mechanism to "hook into" the request handling and get to work with the Request early, but be able to "forward" the request to the default handler
- allow to hook into" the response returning, allowing to completely override the returned response
Point 2 and possibly 3 are where the "component" system of Christopher fits in, but it doesn't solve the requirement to only have the minimal bootstrap loaded for proxying and only when needed to go the full way of initialization. I think Christopher was going to a complete lazy loading of the bootstrap solution, which might work if done correctly.
As to the routing part, I'm not sure if the routing should work completely independent of the MVC, as normally routing resolves URLs to Controllers/Actions, so the connection is implied anyway. Also, routing should not take place before the proxy jumps in, as the proxy doesn't and shouldn't care about routing and only understand plain HTTP - ie URLs, Methods and Headers.
So IMO the process flow should look sth like this:
index.php -> boot -> essential bootstrap -> http components/plugins -> optional bootstraps -> request handling -> default request handling -> full runtime bootstrap -> routing -> mvc -> response -> http components/plugins -> echo & exit
with the option that the component request handling can return responses early or better just skip directly to the response step.
For the interested, I put up my current WIP reverse proxy code on github:
https://github.com/albe/TYPO3.Proxy
The whole Annotation/Aspect part is actually not directly part of the proxy, but should rather become part of the HTTP part of the framework IMO, as it deals with how to control HTTP caches generally from your application.
The filter classes are just a quick idea to allow the proxy to also do some post processing on the response for further optimization purposes (strip&trim html, inject dataURIs, apply compression, etc.).
More information about the Flow
mailing list