[CalendarServer-changes] [9264] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue May 22 12:23:23 PDT 2012
Revision: 9264
http://trac.macosforge.org/projects/calendarserver/changeset/9264
Author: cdaboo at apple.com
Date: 2012-05-22 12:23:22 -0700 (Tue, 22 May 2012)
Log Message:
-----------
Tests for Prefer header support.
Modified Paths:
--------------
CalendarServer/trunk/twext/web2/dav/method/propfind.py
CalendarServer/trunk/twext/web2/dav/method/proppatch.py
CalendarServer/trunk/twext/web2/dav/resource.py
CalendarServer/trunk/twext/web2/http_headers.py
CalendarServer/trunk/twistedcaldav/method/mkcol.py
CalendarServer/trunk/twistedcaldav/method/post.py
CalendarServer/trunk/twistedcaldav/method/propfind.py
CalendarServer/trunk/twistedcaldav/method/put.py
CalendarServer/trunk/twistedcaldav/method/report_common.py
Modified: CalendarServer/trunk/twext/web2/dav/method/propfind.py
===================================================================
--- CalendarServer/trunk/twext/web2/dav/method/propfind.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twext/web2/dav/method/propfind.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -112,7 +112,12 @@
if depth == "infinity":
raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, davxml.PropfindFiniteDepth()))
- brief = request.headers.getHeader("brief", False)
+ # Look for Prefer header first, then try Brief
+ prefer = request.headers.getHeader("prefer", {})
+ returnMinimal = "return-minimal" in prefer
+ noRoot = "depth-noroot" in prefer
+ if not returnMinimal:
+ returnMinimal = request.headers.getHeader("brief", False)
xml_responses = []
@@ -128,7 +133,10 @@
yield filtered_aces
filtered_aces = filtered_aces.getResult()
- resources = [(self, my_url)]
+ if depth in ("1", "infinity") and noRoot:
+ resources = []
+ else:
+ resources = [(self, my_url)]
d = self.findChildren(depth, request, lambda x, y: resources.append((x, y)), (davxml.Read(),), inherited_aces=filtered_aces)
x = waitForDeferred(d)
@@ -136,6 +144,7 @@
x.getResult()
for resource, uri in resources:
+
if search_properties is "names":
try:
resource_properties = waitForDeferred(resource.listProperties(request))
@@ -175,14 +184,14 @@
status = statusForFailure(f, "getting property: %s" % (property,))
if status not in properties_by_status:
properties_by_status[status] = []
- if not brief or status != responsecode.NOT_FOUND:
+ if not returnMinimal or status != responsecode.NOT_FOUND:
properties_by_status[status].append(propertyName(property))
else:
if resource_property is not None:
properties_by_status[responsecode.OK].append(resource_property)
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))
propstats = []
Modified: CalendarServer/trunk/twext/web2/dav/method/proppatch.py
===================================================================
--- CalendarServer/trunk/twext/web2/dav/method/proppatch.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twext/web2/dav/method/proppatch.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -1,6 +1,6 @@
# -*- test-case-name: twext.web2.dav.test.test_prop.PROP.test_PROPPATCH -*-
##
-# Copyright (c) 2005-2011 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2005-2012 Apple Computer, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -84,6 +84,10 @@
undoActions = []
gotError = False
+ # Look for Prefer header
+ prefer = request.headers.getHeader("prefer", {})
+ returnMinimal = "return-minimal" in prefer
+
try:
#
# Update properties
@@ -192,8 +196,11 @@
responses.error()
#
- # Return response
+ # Return response - use 200 if Prefer:return-minimal set and no errors
#
- yield MultiStatusResponse([responses.response()])
+ if returnMinimal and not gotError:
+ yield responsecode.OK
+ else:
+ yield MultiStatusResponse([responses.response()])
http_PROPPATCH = deferredGenerator(http_PROPPATCH)
Modified: CalendarServer/trunk/twext/web2/dav/resource.py
===================================================================
--- CalendarServer/trunk/twext/web2/dav/resource.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twext/web2/dav/resource.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -2270,9 +2270,9 @@
# we redirect such requests (as above) in the event that
# this resource was created or modified by the request.
#
- if self.isCollection() and request.uri[-1:] != "/":
+ if self.isCollection() and request.path[-1:] != "/" and not response.headers.hasHeader("content-location"):
response.headers.setHeader(
- "content-location", request.uri + "/"
+ "content-location", request.path + "/"
)
return response
Modified: CalendarServer/trunk/twext/web2/http_headers.py
===================================================================
--- CalendarServer/trunk/twext/web2/http_headers.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twext/web2/http_headers.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -1501,6 +1501,7 @@
'If-Range':(parseIfRange,),
'If-Unmodified-Since':(last,parseDateTime),
'Max-Forwards':(last,int),
+ 'Prefer':(tokenize, listParser(parseExpect), dict), # Prefer like Expect
# 'Proxy-Authorization':str, # what is "credentials"
'Range':(tokenize, parseRange),
'Referer':(last,str), # TODO: URI object?
@@ -1524,6 +1525,7 @@
'If-Range':(generateIfRange, singleHeader),
'If-Unmodified-Since':(generateDateTime,singleHeader),
'Max-Forwards':(str, singleHeader),
+ 'Prefer':(iteritems, listGenerator(generateExpect), singleHeader), # Prefer like Expect
# 'Proxy-Authorization':str, # what is "credentials"
'Range':(generateRange,singleHeader),
'Referer':(str,singleHeader),
Modified: CalendarServer/trunk/twistedcaldav/method/mkcol.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/mkcol.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twistedcaldav/method/mkcol.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -111,6 +111,8 @@
if doc is not None:
+ # Can ignore Prefer:return-minimal as we don't return a body for success by default
+
# Parse response body
mkcol = doc.root_element
if not isinstance(mkcol, mkcolxml.MakeCollection):
Modified: CalendarServer/trunk/twistedcaldav/method/post.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/post.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twistedcaldav/method/post.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2012 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -117,6 +117,16 @@
# May need to add a location header
addLocation(request, request.unparseURL(path=newchildURL, params=""))
+ # Look for Prefer header
+ prefer = request.headers.getHeader("prefer", {})
+ returnRepresentation = "return-representation" in prefer
+
+ if returnRepresentation and result.code / 100 == 2:
+ result = (yield newchild.http_GET(request))
+ result.code = responsecode.CREATED
+ result.headers.removeHeader("content-location")
+ result.headers.setHeader("content-location", newchildURL)
+
returnValue(result)
except ValueError, e:
@@ -175,6 +185,16 @@
# May need to add a location header
addLocation(request, request.unparseURL(path=newchildURL, params=""))
+ # Look for Prefer header
+ prefer = request.headers.getHeader("prefer", {})
+ returnRepresentation = "return-representation" in prefer
+
+ if returnRepresentation and result.code / 100 == 2:
+ result = (yield newchild.http_GET(request))
+ result.code = responsecode.CREATED
+ result.headers.removeHeader("content-location")
+ result.headers.setHeader("content-location", newchildURL)
+
returnValue(result)
except ValueError, e:
Modified: CalendarServer/trunk/twistedcaldav/method/propfind.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/propfind.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twistedcaldav/method/propfind.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -108,7 +108,12 @@
if depth == "infinity":
raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, davxml.PropfindFiniteDepth()))
- brief = request.headers.getHeader("brief", False)
+ # Look for Prefer header first, then try Brief
+ prefer = request.headers.getHeader("prefer", {})
+ returnMinimal = "return-minimal" in prefer
+ noRoot = "depth-noroot" in prefer
+ if not returnMinimal:
+ returnMinimal = request.headers.getHeader("brief", False)
xml_responses = []
@@ -122,7 +127,10 @@
# the child resource loop and supply those to the checkPrivileges on each child.
filtered_aces = (yield self.inheritedACEsforChildren(request))
- resources = [(True, self, my_url)]
+ if depth in ("1", "infinity") and noRoot:
+ resources = []
+ else:
+ resources = [(True, self, my_url)]
yield self.findChildrenFaster(
depth,
@@ -171,14 +179,14 @@
status = statusForFailure(f, "getting property: %s" % (property,))
if status not in properties_by_status:
properties_by_status[status] = []
- if not brief or status != responsecode.NOT_FOUND:
+ if not returnMinimal or status != responsecode.NOT_FOUND:
properties_by_status[status].append(propertyName(property))
else:
if resource_property is not None:
properties_by_status[responsecode.OK].append(resource_property)
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))
propstats = []
Modified: CalendarServer/trunk/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twistedcaldav/method/put.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2012 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -83,6 +83,18 @@
calendar = calendardata,
)
result = (yield storer.run())
+
+ # Look for Prefer header
+ prefer = request.headers.getHeader("prefer", {})
+ returnRepresentation = "return-representation" in prefer
+
+ if returnRepresentation and result.code / 100 == 2:
+ oldcode = result.code
+ result = (yield self.http_GET(request))
+ if oldcode == responsecode.CREATED:
+ result.code = responsecode.CREATED
+ result.headers.setHeader("content-location", request.path)
+
returnValue(result)
except ValueError, e:
@@ -127,6 +139,18 @@
destinationparent = parent,
)
result = (yield storer.run())
+
+ # Look for Prefer header
+ prefer = request.headers.getHeader("prefer", {})
+ returnRepresentation = "return-representation" in prefer
+
+ if returnRepresentation and result.code / 100 == 2:
+ oldcode = result.code
+ result = (yield self.http_GET(request))
+ if oldcode == responsecode.CREATED:
+ result.code = responsecode.CREATED
+ result.headers.setHeader("content-location", request.path)
+
returnValue(result)
except ValueError, e:
Modified: CalendarServer/trunk/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_common.py 2012-05-22 19:19:49 UTC (rev 9263)
+++ CalendarServer/trunk/twistedcaldav/method/report_common.py 2012-05-22 19:23:22 UTC (rev 9264)
@@ -333,7 +333,11 @@
responsecode.NOT_FOUND : [],
}
- brief = request.headers.getHeader("brief", False)
+ # Look for Prefer header first, then try Brief
+ prefer = request.headers.getHeader("prefer", {})
+ returnMinimal = "return-minimal" in prefer
+ if not returnMinimal:
+ returnMinimal = request.headers.getHeader("brief", False)
for property in props:
if isinstance(property, caldavxml.CalendarData):
@@ -366,15 +370,15 @@
prop = (yield resource.readProperty(qname, request))
if prop is not None:
properties_by_status[responsecode.OK].append(prop)
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
except HTTPError:
f = Failure()
status = statusForFailure(f, "getting property: %s" % (qname,))
if status not in properties_by_status: properties_by_status[status] = []
- if not brief or status != responsecode.NOT_FOUND:
+ if not returnMinimal or status != responsecode.NOT_FOUND:
properties_by_status[status].append(propertyName(qname))
- elif not brief:
+ elif not returnMinimal:
properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
returnValue(properties_by_status)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120522/38de5b83/attachment-0001.html>
More information about the calendarserver-changes
mailing list