On Thu, Sep 16, 2010 at 5:48 AM, Tarek Ziadé <ziade.ta...@gmail.com> wrote: > On Thu, Sep 16, 2010 at 2:40 PM, Armin Ronacher > <armin.ronac...@active-4.com> wrote: >> Hi, >> >> On 9/16/10 2:38 PM, Tarek Ziadé wrote: >>> >>> True... I don't know what's the best option here.. I guess we need to >>> provide all children so one may visit the whole graph. >> >> Another gripe I have with WSGI is that if you attempt to combine >> applications together with a dispatcher middleware, the inner application >> does not know the URL of the outer one. It's SCRIPT_NAME points to itself >> and there is no ORIGINAL_SCRIPT_NAME. >> >>> Do you have a list of middleware that does this ? >> >> I know that Paste has a cascade middleware and I think it also has one that >> maps applications to specific prefixes. > > Ah yes, the composite thing IIRC - I didn't know this was a middleware. > > Should those be middlewares ? ISTM that they should in the front of > the stack instead, and that a stack of middleware should be dedicated > to a single application -- for the griefs you mentioned and probably > other problems. > > I mean, one call does not visit several application, and this is some > kind of dynamic rewriting of the stack.. > > Another possibility would be to define a > "get_application(environ=None)" method so the middleware is able to > return the right app at the right moment
The 'pegboard' middleware composes a result out of an arbitrary graph of WSGI apps, with one request visiting many applications. The graph can be built at runtime in application code, so it would be very difficult to report all of the '.app's applicable for a given environ until after the request. Also, it is quite reasonable in practice to have middleware both in front of such a composer and also in the stacks of the apps it composes. A concern with "should have .app" is that a single closure middleware breaks the chain. For example: def unproxy(app): def middleware(environ): environ['HTTP_HOST'] = environ['HTTP_X_FORWARDED_FOR_HOST'] return app(environ) return middleware For the use case of "original_app = self.app.app.application.app", I've had great success with a pattern I first saw in Zine: applying the middleware internally to the application instance, not wrapping the instance. It seems fairly robust against closures and middleware that can't or won't play along with .app. Unlike .app, this isn't generically traversable, but in cases where I need this kind of cross-talk between middleware/apps I haven't had any problems getting the right instances into scope at runtime. class MyApp: def apply_middleware(self, factory, *args, **kw): self.dispatch_wsgi = factory(self.dispatch_wsgi, *args, **kw) def dispatch_wsgi(self, environ): return [b'hi'], b'200 OK', [(b'Content-type', b'text/plain')] def __call__(self, environ): return self.dispatch_wsgi(environ) app = MyApp() app.apply_middleware(unproxy) app.apply_middleware(StaticContent, 'static/') _______________________________________________ Web-SIG mailing list Web-SIG@python.org Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com