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 _______________________________________________ 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