[Web-SIG] [extension] x-wsgiorg.flush
Thomas Broyer
t.broyer at gmail.com
Mon Oct 8 19:49:06 CEST 2007
2007/10/8, Manlio Perillo:
> Phillip J. Eby ha scritto:
> > [...]
> >
> > I don't think there's any point to having a WSGI extension for If-*
> > header support.
>
> I have just found that the WSGI spec says:
> """...it should be clear that a server may handle cache validation via
> the If-None-Match and If-Modified-Since request headers and the
> Last-Modified and ETag response headers."""
>
>
> So a WSGI implementation is *allowed* to perform cache validation, but
> it is not clear *how* this should be done.
>
> As an example, without the need of an extension, the start_response
> callable may check if Last-Modified or ETag is in the headers.
> In this case, it may perform a cache validation, and if the client
> representation is fresh, it may omit to send the body.
>
> However there are two problems here:
> 1) It is not clear if WSGI explicitly allows an implementation to skip
> the iteration over the app_iter object, for optimization purpose
> 2) For a WSGI implementation embedded in an existing webserver, the
> most convenient method to perform cache validation is to let the
> server do it; however this requires to send the headers as soon as
> start_response is called, and this is not allowed.
How about (not tested, and simplified to require the app to return an
iterable, and without support for If-Range):
def has_precondition(environ):
return "HTTP_IF_MATCH" in environ or
"HTTP_IF_NONE_MATCH" in environ or
"HTTP_IF_MODIFIED_SINCE" in environ or
"HTTP_IF_UNMODIFIED_SINCE" in environ
def matches_preconditions(environ, headers):
# TODO
def notmodifed_middleware(application):
def middleware(environ, start_response):
notmodified = [False]
def sr(status, headers, exc_info=None):
if status[0] == "2" and matches_preconditions(environ, headers):
start_response("304 Not Modified", headers, exc_info)
notmodified[0] = True
return lambda s: raise NotSupportedError("The write
callback is deprecated")
else:
notmodified[0] = False
return start_response(status, headers, exc_info)
app_iter = application(environ,
environ["wsgi.method"] == "GET" and
has_preconditions(environ) and sr or start_response)
if notmodified[0]:
return ("", )
else:
return app_iter
return middleware
We're still waiting for the app to complete (and return its app_iter)
before sending anything to the client but this doesn't prevent us from
checking preconditions and in this case replace the status with a 304
Not Modified and an empty body (ignoring the app_iter all together;
but maybe we should iterate it to allow the wrapped application to
*really* complete its execution)
--
Thomas Broyer
More information about the Web-SIG
mailing list