def renderHTTP(self, ctx): request = IRequest(ctx) # FIXME: This is for testing with litmus; comment out when not in use litmus = request.headers.getRawHeaders("x-litmus") if litmus: log.msg("*** Litmus test: %s ***" % (litmus,)) # FIXME: Ideally, this logging would be in Resource, not here protocol = "HTTP/%s.%s" % request.clientproto log.msg("%s %s %s" % (request.method, urllib.unquote(request.uri), protocol)) # # Check the If-Match and If-None-Match headers # # FIXME: RFC 2068 (HTTP) section 14.25, and 14.26 say: # If the request would, without the If-Match header field, result in # anything other than a 2xx status, then the If-Match header MUST be # ignored. # This implies that we have to attempt the request, check the status, # and act on the If-Match header only if the request resulted in an # error. That seems rather expensive. Furthermore, for many # operations, such as PUT, COPY, MOVE and DELETE, we'd have to back out # the successful operation first. Ouch! # # FIXME: This probably belongs in Resource, but that would require # adding an etag property to its interface. match = request.headers.getHeader("if-match") if match: self.fp.restat(False) if match == ("*",): if not self.fp.exists(): return responsecode.PRECONDITION_FAILED else: my_etag = self.etag if my_etag is None: return responsecode.PRECONDITION_FAILED for etag in match: if etag.match(my_etag, True): break else: return responsecode.PRECONDITION_FAILED match = request.headers.getHeader("if-none-match") if match: # FIXME: For GET, we should respond with NOT_MODIFIED and set some # cache headers. See RFC 2066 (HTTP) section 14.26. self.fp.restat(False) if match == ("*",): if self.fp.exists(): return responsecode.PRECONDITION_FAILED else: my_etag = self.etag if my_etag is not None: for etag in match: if etag.match(my_etag, True): return responsecode.PRECONDITION_FAILED # # Call super and append DAV header # response = File.renderHTTP(self, ctx) response = setHeaderInResponse(response, "dav", self.davComplianceClasses) return response