Index: twisted/web2/static.py =================================================================== --- twisted/web2/static.py (revision 15884) +++ twisted/web2/static.py (working copy) @@ -17,7 +17,7 @@ # Twisted Imports from twisted.python import filepath -from twisted.internet.defer import succeed, maybeDeferred +from twisted.internet.defer import maybeDeferred from zope.interface import implements class MetaDataMixin(object): @@ -74,6 +74,17 @@ return True class StaticRenderMixin(resource.RenderMixin, MetaDataMixin): + def checkPreconditions(self, request): + if request.method not in ("GET", "HEAD"): + http.checkPreconditions( + request, + entityExists = self.exists(), + etag = self.etag(), + lastModified = self.lastModified(), + ) + + super(StaticRenderMixin, self).checkPreconditions(request) + def renderHTTP(self, request): """ See L{resource.RenderMixIn.renderHTTP}. Index: twisted/web2/resource.py =================================================================== --- twisted/web2/resource.py (revision 15882) +++ twisted/web2/resource.py (working copy) @@ -25,6 +25,28 @@ self._allowed_methods = tuple([name[5:] for name in dir(self) if name.startswith('http_')]) return self._allowed_methods + def checkPreconditions(self, request): + """ + Checks all preconditions imposed by this resource upon a request made + against it. + @param request: the request to process. + @raise http.HTTPError: if any precondition fails. + """ + # + # http.checkPreconditions() gets called by the server after every + # GET or HEAD request. + # + # For other methods, we need to know to bail out before request + # processing, especially for methods that modify server state (eg. PUT). + # We also would like to do so even for methods that don't, if those + # methods might be expensive to process. We're assuming that GET and + # HEAD are not expensive. + # + if request.method not in ("GET", "HEAD"): + http.checkPreconditions(request) + + super(StaticRenderMixin, self).checkPreconditions(request) + def renderHTTP(self, request): """ See L{iweb.IResource.renderHTTP}. @@ -52,6 +74,8 @@ response.headers.setHeader("allow", self.allowedMethods()) return response + self.checkPreconditions(request) + return method(request) def http_OPTIONS(self, request): Index: twisted/web2/server.py =================================================================== --- twisted/web2/server.py (revision 15880) +++ twisted/web2/server.py (working copy) @@ -40,9 +40,8 @@ defaultHeadersFilter.handleErrors = True def preconditionfilter(request, response): - newresponse = http.checkPreconditions(request, response) - if newresponse is not None: - return newresponse + if request.method in ("GET", "HEAD"): + http.checkPreconditions(request, response) return response def doTrace(request):