Uncle! Uncle! On Wed, Jan 25, 2006 at 12:17:29PM -0500, Phillip J. Eby wrote: | If each middleware or application does this: | | remote_user = environ.setdefault('paste.remote_user', []) | | And then uses the contents of that list as the thing to check or modify, | then you will get the exact same result as the "pass the same environ" | approach, except that it's actually compatible with PEP 333, as opposed | to relying on implementation accidents.
Ok, assuming that we want an "extension API" for this sort of thing; I'd rather have a bit more general solution. At the very least, it would be nice to have a unified way to pass the REMOTE_USER up the WSGI stack so that each WSGI middleware toolkit doesn't have to roll their own (ie, paste.remote_user and zope.set_user). But ideally, the solution should handle more than just REMOTE_USER since I need to track session identifiers and other environment changes. Here is a proposal. wsgi.notify(key, value) This optional environment variable is a function used to notify previous stages of processing about a change in the ``environ``. Authentication middleware components, for example, would want to do something like: if environ.get('wsgi.notify'): environ.get('wsgi.notify')('REMOTE_USER','foo') environ['REMOTE_USER'] = 'foo' when setting an common environment variable which may be useful to previous processing stages. Prior stages may then watch for particularly important changes by replacing this function, making sure to call prior instances, like: class Logger: def __init__(self, application): self.application = application self.user_counts = {} def __call__(self, environ, start_response): prev_notify = environ.get('wsgi.notify', lambda k,v: None) def notify(k,v): if 'REMOTE_USER' == k: environ['bing.user'] = v prev_notify(k,v) def _start_response(status, response_headers, exce_info=None): user = environ.get('bing.user','anonymous') self.access[user] = self.access.get(user,0) + 1 return start_response(status, response_headers, exce_info) environ['wsgi.notify'] = notify return self.application(environ, _start_response) | >The WSGI middleware components that actually create their own environ | >are few and far between. This is an uncommon edge case. | | Composability of applications is a critical requirement for WSGI | middleware. It doesn't matter how uncommon it is. Even if there were | *zero* implementations of such middleware right now, that principle | would take precedence, meaning you'd have to have a proposal that would | preserve composability. Right now, you haven't described a way to do | that without introducing temporal coupling (or worse) among subrequests. If you assume a single thread of control; ie, all sub-requests are done sequentially, then "extension APIs" share all of the pitfalls as mandating a single ``environ``. I've demonstrated how this is possible in an earlier message. However, in a *threaded* environment, the approach I proposed is unworkable if sub-requests are executed in parallel. In this case, strange and nasty consequences would exist if multiple sub-applications were accessing the same ``environ`` dict. It is for this reason that I'm throwing in the towel. I hope something like the proposal above; or my other attempt to formalize a response-based approach are closer to your liking. Best Wishes, Clark _______________________________________________ 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