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