On Sun, Dec 12, 2010 at 9:59 PM, Alice Bevan–McGregor <span dir="ltr">&lt;<a href="mailto:alice@gothcandy.com">alice@gothcandy.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Howdy!<br>
<br>
There&#39;s one issue I&#39;ve seen repeated a lot in working with WSGI1 and that is the use of middleware to process incoming data, but not outgoing, and vice-versa; middleware which filters the output in some way, but cares not about the input.<br>


<br>
Wrapping middleware around an application is simple and effective, but costly in terms of stack allocation overhead; it also makes debugging a bit more of a nightmare as the stack trace can be quite deep.<br>
<br>
My updated draft PEP 444[1] includes a section describing Filters, both ingress (input filtering) and egress (output filtering).  The API is trivially simple, optional (as filters can be easily adapted as middleware if the host server doesn&#39;t support filters) and easy to implement in a server.  (The Marrow HTTP/1.1 server implements them as two for loops.)<br>

</blockquote><div><br>It&#39;s not clear to me how this can be composed or abstracted.<br><br>@webob.dec.wsgify does kind of handle this with its request/response pattern; in a simplified form it&#39;s like:<br><br>def wsgify(func):<br>

    def replacement(environ):<br>        req = Request(environ)<br>        resp = func(req)<br>        return resp(environ)<br>    return replacement<br><br>This allows you to do an output filter like:<br><br>@wsgify<br>
def output_filter(req):<br>
    resp = some_app(req.environ)<br>    fiddle_with_resp(resp)<br>    return resp<br><br>(Most output filters also need the request.)  And an input filter like:<br><br>@wsgify<br>def input_filter(req):<br>    fiddle_with_req(req)<br>

    return some_app<br><br><br>But while it handles the input filter case, it doesn&#39;t try to generalize this or move application composition into the server.  An application is an application and servers are imagined but not actually concrete.  If you handle filters at the server level you have to have some way of registering these filters, and it&#39;s unclear what order they should be applied.  At import?  Does the server have to poke around in the app it is running?  How can it traverse down if you have dispatching apps (like paste.urlmap or Routes)?<br>

<br>You can still implement this locally of course, as a class that takes an app and input and output filters.<br clear="all"><br></div></div><br>-- <br>Ian Bicking  |  <a href="http://blog.ianbicking.org">http://blog.ianbicking.org</a><br>