[CalendarServer-changes] [6433] CalendarServer/branches/users/glyph/more-deferreds-7

source_changes at macosforge.org source_changes at macosforge.org
Sun Oct 17 21:33:37 PDT 2010


Revision: 6433
          http://trac.macosforge.org/projects/calendarserver/changeset/6433
Author:   glyph at apple.com
Date:     2010-10-17 21:33:34 -0700 (Sun, 17 Oct 2010)
Log Message:
-----------
Catch up to trunk, pass more CDT tests

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tap/caldav.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/export.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/gateway.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/purge.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/util.py
    CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-apple.plist
    CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-test.plist
    CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-srv-caldav.txt
    CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-webdav-sync.txt
    CalendarServer/branches/users/glyph/more-deferreds-7/run
    CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh
    CalendarServer/branches/users/glyph/more-deferreds-7/twext/web2/dav/resource.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directory/principal.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directorybackedaddressbook.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/mail.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/method/report_sync_collection.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/notify.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/resource.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/implicit.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/processing.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/scheduler.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/test/test_implicit.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/stdconfig.py
    CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/storebridge.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/base/datastore/subpostgres.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql_legacy.py

Added Paths:
-----------
    CalendarServer/branches/users/glyph/more-deferreds-7/bin/calendarserver_config
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/config.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/test_util.py
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist
    CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.txt
    CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.xml

Removed Paths:
-------------
    CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist

Property Changed:
----------------
    CalendarServer/branches/users/glyph/more-deferreds-7/
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py
    CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py


Property changes on: CalendarServer/branches/users/glyph/more-deferreds-7
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:6369-6396
   + /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:6369-6432

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/bin/calendarserver_config (from rev 6432, CalendarServer/trunk/bin/calendarserver_config)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/bin/calendarserver_config	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/bin/calendarserver_config	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2007 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+import sys
+
+#PYTHONPATH
+
+if __name__ == "__main__":
+    if "PYTHONPATH" in globals():
+        sys.path.insert(0, PYTHONPATH)
+    else:
+        from os.path import dirname, abspath, join
+        from subprocess import Popen, PIPE
+
+        home = dirname(dirname(abspath(__file__)))
+        run = join(home, "run")
+
+        child = Popen((run, "-p"), stdout=PIPE)
+        path, stderr = child.communicate()
+
+        path = path.rstrip("\n")
+
+        if child.wait() == 0:
+            sys.path[0:0] = path.split(":")
+
+        sys.argv[1:1] = ["-f", join(home, "conf", "caldavd-dev.plist")]
+
+    from calendarserver.tools.config import main
+    main()

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tap/caldav.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tap/caldav.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -496,7 +496,7 @@
 
         additional = []
         if config.Scheduling.iMIP.Enabled:
-            additional.append(("inbox", IMIPReplyInboxResource, [], "basic"))
+            additional.append(("inbox", IMIPReplyInboxResource, [], "digest"))
         rootResource = getRootResource(config, additional)
 
         #

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/config.py (from rev 6432, CalendarServer/trunk/calendarserver/tools/config.py)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/config.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/config.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2010 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+This tool reads the Calendar Server configuration file and emits the
+requested value.
+"""
+
+import os, sys
+from getopt import getopt, GetoptError
+
+from twistedcaldav import config
+from twistedcaldav.config import ConfigurationError
+from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
+
+from calendarserver.tools.util import UsageError
+from calendarserver.tools.util import loadConfig
+
+def usage(e=None):
+    if e:
+        print e
+        print ""
+
+    name = os.path.basename(sys.argv[0])
+    print "usage: %s [options] config_key" % (name,)
+    print ""
+    print "Print the value of the given config key."
+    print "options:"
+    print "  -h --help: print this help and exit"
+    print "  -f --config: Specify caldavd.plist configuration path"
+
+    if e:
+        sys.exit(64)
+    else:
+        sys.exit(0)
+
+def main():
+    try:
+        (optargs, args) = getopt(
+            sys.argv[1:], "hf:", [
+                "help",
+                "config=",
+            ],
+        )
+    except GetoptError, e:
+        usage(e)
+
+    configFileName = DEFAULT_CONFIG_FILE
+
+    for opt, arg in optargs:
+        if opt in ("-h", "--help"):
+            usage()
+
+        elif opt in ("-f", "--config"):
+            configFileName = arg
+
+    try:
+        config = loadConfig(configFileName)
+    except ConfigurationError, e:
+        sys.stdout.write("%s\n" % (e,))
+        sys.exit(1)
+
+    for configKey in args:
+        c = config
+        for subKey in configKey.split("."):
+            c = c.get(subKey, None)
+            if c is None:
+                sys.stderr.write("No such config key: %s\n" % configKey)
+                break
+        else:
+            sys.stdout.write("%s\n" % c)

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/export.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/export.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/export.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -36,6 +36,7 @@
 from getopt import getopt, GetoptError
 from os.path import dirname, abspath
 
+from twistedcaldav import config
 from twistedcaldav.config import ConfigurationError
 from twistedcaldav.ical import Component as iComponent, Property as iProperty
 from twistedcaldav.ical import iCalendarProductID

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/gateway.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/gateway.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/gateway.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -119,7 +119,7 @@
             return
         setupMemcached(config)
     except ConfigurationError, e:
-        respondWithError(e)
+        respondWithError(str(e))
         return
 
     #

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/purge.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/purge.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -56,6 +56,7 @@
     print ""
 
     if e:
+        sys.stderr.write("%s\n" % (e,))
         sys.exit(64)
     else:
         sys.exit(0)
@@ -75,6 +76,7 @@
     print ""
 
     if e:
+        sys.stderr.write("%s\n" % (e,))
         sys.exit(64)
     else:
         sys.exit(0)
@@ -160,10 +162,18 @@
         else:
             raise NotImplementedError(opt)
 
+    if args:
+        usage_purge_events("Too many arguments: %s" % (args,))
+
     cutoff = (date.today()-timedelta(days=days)).strftime("%Y%m%dT000000Z")
 
-    shared_main(configFileName, purgeOldEvents, cutoff, verbose=verbose,
-        dryrun=dryrun)
+    shared_main(
+        configFileName,
+        purgeOldEvents,
+        cutoff,
+        verbose=verbose,
+        dryrun=dryrun,
+    )
 
 
 def main_purge_principals():
@@ -205,7 +215,13 @@
 
     # args is a list of guids
 
-    shared_main(configFileName, purgeGUIDs, args, verbose=verbose, dryrun=dryrun)
+    shared_main(
+        configFileName,
+        purgeGUIDs,
+        args,
+        verbose=verbose,
+        dryrun=dryrun,
+    )
 
 
 @inlineCallbacks

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/test_util.py (from rev 6432, CalendarServer/trunk/calendarserver/tools/test/test_util.py)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/test_util.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/test_util.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,28 @@
+##
+# Copyright (c) 2005-2010 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+import os
+from twistedcaldav.test.util import TestCase
+from calendarserver.tools.util import loadConfig
+
+class UtilTestCase(TestCase):
+
+    def test_loadConfig(self):
+        testRoot = os.path.join(os.path.dirname(__file__), "util")
+        configPath = os.path.join(testRoot, "caldavd.plist")
+        config = loadConfig(configPath)
+        self.assertEquals(config.EnableCalDAV, True)
+        self.assertEquals(config.EnableCardDAV, True)

Deleted: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/util/caldavd.plist	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist	2010-10-18 04:33:34 UTC (rev 6433)
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-  <dict>
-    <key>EnableCalDAV</key>
-    <false/>
-    <key>EnableCardDAV</key>
-    <false/>
-  </dict>
-</plist>

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist (from rev 6432, CalendarServer/trunk/calendarserver/tools/test/util/caldavd.plist)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/test/util/caldavd.plist	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>EnableCalDAV</key>
+    <false/>
+    <key>EnableCardDAV</key>
+    <false/>
+  </dict>
+</plist>

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/util.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/util.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/calendarserver/tools/util.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -47,6 +47,10 @@
 log = Logger()
 
 def loadConfig(configFileName):
+    """
+    Helper method for command-line utilities to load configuration plist
+    and override certain values.
+    """
     if configFileName is None:
         configFileName = DEFAULT_CONFIG_FILE
 
@@ -55,6 +59,10 @@
 
     config.load(configFileName)
 
+    # Command-line utilities always want these enabled:
+    config.EnableCalDAV = True
+    config.EnableCardDAV = True
+
     return config
 
 def getDirectory():

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-apple.plist
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-apple.plist	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-apple.plist	2010-10-18 04:33:34 UTC (rev 6433)
@@ -514,6 +514,9 @@
     <key>EnableWebAdmin</key>
     <true/>
 
+    <!-- Directory searching -->
+    <key>EnableSearchAddressBook</key>
+    <true/>
 
   </dict>
 </plist>

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-test.plist
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-test.plist	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/conf/caldavd-test.plist	2010-10-18 04:33:34 UTC (rev 6433)
@@ -786,6 +786,8 @@
 
     <key>Localization</key>
     <dict>
+      <key>TranslationsDirectory</key>
+      <string>locales</string>
       <key>LocalesDirectory</key>
       <string>locales</string>
       <key>Language</key>

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.txt (from rev 6432, CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.txt	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.txt	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,1736 @@
+
+
+
+Calendar Server Extension                                       C. Daboo
+                                                                 E. York
+                                                              Apple Inc.
+                                                         October 6, 2010
+
+
+                Shared and Published Calendars in CalDAV
+
+Abstract
+
+   This specification defines an extension to CalDAV that enables the
+   sharing of calendars between users on a CalDAV server.
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  3
+   3.  Overview . . . . . . . . . . . . . . . . . . . . . . . . . . .  4
+   4.  Notifications  . . . . . . . . . . . . . . . . . . . . . . . .  5
+     4.1.  Additional Principal Properties  . . . . . . . . . . . . .  5
+       4.1.1.  CS:notification-URL Property . . . . . . . . . . . . .  6
+     4.2.  Properties on Notification Resources . . . . . . . . . . .  6
+       4.2.1.  CS:notificationtype Property . . . . . . . . . . . . .  6
+   5.  Shared Calendaring . . . . . . . . . . . . . . . . . . . . . .  7
+     5.1.  Feature Discovery  . . . . . . . . . . . . . . . . . . . .  7
+     5.2.  Additional Properties for Calendars  . . . . . . . . . . .  7
+       5.2.1.  DAV:resourcetype Property  . . . . . . . . . . . . . .  7
+       5.2.2.  CS:invite Property . . . . . . . . . . . . . . . . . .  8
+       5.2.3.  CS:allowed-sharing-modes Property  . . . . . . . . . .  8
+       5.2.4.  CS:shared-url Property . . . . . . . . . . . . . . . .  9
+     5.3.  Sharer Actions on Shared Calendars . . . . . . . . . . . .  9
+       5.3.1.  Creating a Shared Calendar . . . . . . . . . . . . . .  9
+         5.3.1.1.  Example: Successful MKCALENDAR Request . . . . . . 10
+         5.3.1.2.  Example: Successful Extended MKCOL Request . . . . 10
+       5.3.2.  Sharing an Existing Calendar . . . . . . . . . . . . . 11
+         5.3.2.1.  Example: Successful PROPPATCH Request  . . . . . . 11
+       5.3.3.  Manipulating Sharees of a Shared Calendar  . . . . . . 12
+         5.3.3.1.  Example: Successful Sharee Add Request . . . . . . 13
+         5.3.3.2.  Example: Successful Multiple Sharee Change
+                   Request  . . . . . . . . . . . . . . . . . . . . . 14
+     5.4.  Sharee Actions on Shared Calendars . . . . . . . . . . . . 15
+       5.4.1.  Replying to a Sharing Invite . . . . . . . . . . . . . 15
+       5.4.2.  Removing a Shared Calendar . . . . . . . . . . . . . . 16
+     5.5.  General Considerations . . . . . . . . . . . . . . . . . . 16
+       5.5.1.  Access Levels  . . . . . . . . . . . . . . . . . . . . 16
+       5.5.2.  Allowing or Disallowing Sharing  . . . . . . . . . . . 16
+       5.5.3.  Per-user WebDAV Properties . . . . . . . . . . . . . . 17
+
+
+
+Daboo & York                                                    [Page 1]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+       5.5.4.  Per-user Calendar Data . . . . . . . . . . . . . . . . 17
+       5.5.5.  Scheduling . . . . . . . . . . . . . . . . . . . . . . 18
+   6.  XML Element Definitions  . . . . . . . . . . . . . . . . . . . 19
+     6.1.  CS:shared-owner  . . . . . . . . . . . . . . . . . . . . . 19
+     6.2.  CS:shared  . . . . . . . . . . . . . . . . . . . . . . . . 20
+     6.3.  CS:can-be-shared . . . . . . . . . . . . . . . . . . . . . 20
+     6.4.  CS:can-be-published  . . . . . . . . . . . . . . . . . . . 21
+     6.5.  CS:user  . . . . . . . . . . . . . . . . . . . . . . . . . 21
+     6.6.  CS:invite-noresponse . . . . . . . . . . . . . . . . . . . 21
+     6.7.  CS:invite-deleted  . . . . . . . . . . . . . . . . . . . . 22
+     6.8.  CS:invite-accepted . . . . . . . . . . . . . . . . . . . . 22
+     6.9.  CS:invite-declined . . . . . . . . . . . . . . . . . . . . 22
+     6.10. CS:invite-invalid  . . . . . . . . . . . . . . . . . . . . 23
+     6.11. CS:access  . . . . . . . . . . . . . . . . . . . . . . . . 23
+     6.12. CS:read  . . . . . . . . . . . . . . . . . . . . . . . . . 24
+     6.13. CS:read-write  . . . . . . . . . . . . . . . . . . . . . . 24
+     6.14. CS:summary . . . . . . . . . . . . . . . . . . . . . . . . 24
+     6.15. CS:invite-notification . . . . . . . . . . . . . . . . . . 25
+     6.16. CS:uid . . . . . . . . . . . . . . . . . . . . . . . . . . 25
+     6.17. CS:hosturl . . . . . . . . . . . . . . . . . . . . . . . . 25
+     6.18. CS:organizer . . . . . . . . . . . . . . . . . . . . . . . 26
+     6.19. CS:common-name . . . . . . . . . . . . . . . . . . . . . . 26
+     6.20. CS:invite-reply  . . . . . . . . . . . . . . . . . . . . . 26
+     6.21. CS:in-reply-to . . . . . . . . . . . . . . . . . . . . . . 27
+     6.22. CS:notification  . . . . . . . . . . . . . . . . . . . . . 27
+     6.23. CS:dtstamp . . . . . . . . . . . . . . . . . . . . . . . . 28
+     6.24. CS:share . . . . . . . . . . . . . . . . . . . . . . . . . 28
+     6.25. CS:set . . . . . . . . . . . . . . . . . . . . . . . . . . 28
+     6.26. CS:remove  . . . . . . . . . . . . . . . . . . . . . . . . 29
+     6.27. CS:shared-as . . . . . . . . . . . . . . . . . . . . . . . 29
+   7.  Security Considerations  . . . . . . . . . . . . . . . . . . . 29
+   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 29
+   9.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 30
+   10. Normative References . . . . . . . . . . . . . . . . . . . . . 30
+   Appendix A.  Change History  . . . . . . . . . . . . . . . . . . . 30
+   Appendix B.  Change History  . . . . . . . . . . . . . . . . . . . 30
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 31
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & York                                                    [Page 2]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+1.  Introduction
+
+   CalDAV [RFC4791] provides a way for calendar users to store calendar
+   data and exchange this data via scheduling operations.  Based on the
+   WebDAV [RFC4918] protocol, it also includes the ability to manage
+   access to calendar data via the WebDAV ACL [RFC3744] extension.
+
+   WebDAV ACL [RFC3744] provides a way to manage fine-grained access
+   controls on WebDAV resources.  Whilst this could be used directly to
+   manage sharing of calendars, experience has shown that client
+   developers are averse to using it due to its complexity.  Instead a
+   simpler process for sharing calendars is preferred.
+
+   This extension defines a way for individual calendar users to share
+   calendars with other users.  This is done via an "opt-in" process in
+   which a sharing invite is sent from the sharer to a sharee, allowing
+   the sharee to accept or decline.  If the sharee accepts the sharing
+   invite, the shared calendar is made available to them in their own
+   calendar home collection (i.e., alongside their own personal
+   calendars).  HTTP POST operations are used to manage the sharing
+   invitations and replies, and WebDAV properties are used to expose the
+   state of shared calendars.
+
+
+2.  Conventions Used in This Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in [RFC2119].
+
+   When XML element types in the namespaces "DAV:" and
+   "urn:ietf:params:xml:ns:caldav" are referenced in this document
+   outside of the context of an XML fragment, the string "DAV:" and
+   "CALDAV:" will be prefixed to the element type names respectively.
+
+   The namespace "http://calendarserver.org/ns/" is used for XML
+   elements defined in this specification.  When XML element types in
+   that namespace are referenced in this document outside of the context
+   of an XML fragment, the string "CS:" will be prefixed to the element
+   type names.
+
+   Terms Used:
+
+   Sharer  A calendar user who is sharing a calendar with other calendar
+      users.
+
+
+
+
+
+
+Daboo & York                                                    [Page 3]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Sharee  A calendar user to whom a calendar has been shared.
+
+   Sharing Invite  A message sent by a sharer to a sharee to indicate
+      the status of a shared calendar.
+
+   Sharing Reply  A message sent by a sharee to a sharer to indicate the
+      status of a shared calendar.
+
+
+3.  Overview
+
+   This section provides a basic overview of this protocol by way of a
+   simple use case of a sharer sharing a calendar with a single sharee.
+
+   To share a calendar with another user, the sharer's client executes
+   an HTTP POST request against the calendar collection resource for the
+   calendar to be shared.  The POST request body will contain details of
+   the calendar user to whom the calendar is to be shared as well as the
+   access right to be granted to them.  If the request succeeds, a
+   notification is sent to the sharee with details of the calendar being
+   shared to them.
+
+   The sharer's client will show the notification to the sharee and
+   present them with the choice to accept or decline the invitation to
+   the shared calendar.  If the sharee chooses to decline, then nothing
+   changes for that sharee.  If the sharee chooses to accept, then the
+   server automatically creates a new calendar collection resource in
+   the sharee's calendar home collection, and ensures that calendar
+   provides a mapping to the actual shared calendar of the sharer.  Thus
+   the shared calendar is available to the sharee as just another
+   calendar in their calendar home.  The server enforces the appropriare
+   access privileges for the sharee.
+
+   At any time, the sharer can inspect properties on the calendar
+   collection being shared, and determine the accept/decline status of
+   each sharee.  Additional sharees can be added and existing ones
+   removed.  The access privileges for existing sharees can also be
+   changed.
+
+   Once a sharee has a shared calendar set to appear in their calendar
+   home collection, they can remove it and decline the sharing invite by
+   simply having their client issue an HTTP DELETE request on the shared
+   calendar collection.  That does not delete any calendar data, but
+   rather simply removes the "link" to the sharer's calendar collection
+   and sets the sharee's inviate status to declined.
+
+
+
+
+
+
+Daboo & York                                                    [Page 4]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+4.  Notifications
+
+   In order to facilitate the process of sharing invitations, this
+   specification defines a new generic notification mechanism for CalDAV
+   servers.  When this feature is available, a CS:notification-URL
+   (Section 4.1.1) property appears on principal resources for those
+   principals who are able to receive notifications.  That property
+   specifies a single DAV:href element whose content refers to a WebDAV
+   collection resource.  Notification "messages" are deposited into this
+   collection and can be retrieved by clients and acted on accordingly.
+
+   The notification collection referenced by the CS:notification-URL
+   (Section 4.1.1) property MUST have a DAV:resourcetype property with
+   DAV:collection and CS:notification (Section 6.22) child elements.
+
+   Notification "messages" are XML documents stored as resources in the
+   notification collection.  Each XML document contains a CS:
+   notification (Section 6.22) element as its root.  The root element
+   contains a CS:dtstamp (Section 6.23) element, and one additional
+   element which represents the type of notification being conveyed in
+   the message.  That child element will typically contain additional
+   content that describes the notification.
+
+   Each notification resource has a CS:notificationtype (Section 4.2.1)
+   property which contains as its single child element an empty element
+   that matches the child element of the notification resource XML
+   document root.  Any attributes on the child element in the XML
+   document are also present in the property child element.
+
+   Notifications are automatically generated by the server (perhaps in
+   response to a client action) with an appropriate resource stored in
+   the notifications collection of the user to whom the notification is
+   targeted.  Clients SHOULD monitor the notification collection looking
+   for new notification resources.  When doing so, clients SHOULD look
+   at the CS:notificationtype (Section 4.2.1) property to ensure that
+   the notification is of a type that the client can handle.  Once a
+   client has handled the notification in whatever way is appropriate it
+   SHOULD delete the notification resource.  Servers MAY delete
+   notification resources on their own if they determine that the
+   notifications are no longer relevant or valid.  Servers MAY coalesce
+   notifications as appropriate.
+
+4.1.  Additional Principal Properties
+
+   This section defines new properties for WebDAV principal resources as
+   defined in RFC3744 [RFC3744].  These properties are likely to be
+   protected but the server MAY allow them to be written by appropriate
+   users.
+
+
+
+Daboo & York                                                    [Page 5]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+4.1.1.  CS:notification-URL Property
+
+   Name:  notification-URL
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Identify the URL of the notification collection owned by
+      the associated principal resource.
+
+   Protected:  This property SHOULD be protected.
+
+   PROPFIND behavior:  This property SHOULD NOT be returned by a
+      PROPFIND allprop request (as defined in Section 14.2 of
+      [RFC4918]).
+
+   COPY/MOVE behavior:  This property value SHOULD be preserved in COPY
+      and MOVE operations.
+
+   Description:  This property is needed for a client to determine where
+      the notification collection of the current user is located so that
+      processing of notification messages can occur.  If not present,
+      then the associated calendar user is not enabled for notification
+      messages on the server.
+
+   Definition:
+
+   <!ELEMENT notification-URL (DAV:href)>
+
+4.2.  Properties on Notification Resources
+
+   The following new WebDAV properties are defined for notification
+   resources.
+
+4.2.1.  CS:notificationtype Property
+
+   Name:  notificationtype
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Identify the type of notification of the corresponding
+      resource.
+
+   Protected:  This property MUST be protected.
+
+   PROPFIND behavior:  This property SHOULD NOT be returned by a
+      PROPFIND allprop request (as defined in Section 14.2 of
+      [RFC4918]).
+
+
+
+
+Daboo & York                                                    [Page 6]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   COPY/MOVE behavior:  This property value MUST be preserved in COPY
+      and MOVE operations.
+
+   Description:  This property allows a client, via a PROPFIND Depth:1
+      request, to quickly find notification messages that the client can
+      handle in a notification collection.  The single child element is
+      the notification resource root element's child defining the
+      notification itself.  This element MUST be empty, though any
+      attributes on the element in the notification resource MUST be
+      present in the property element.
+
+   Definition:
+
+   <!ELEMENT notificationtype (invite-notification | invite-reply)>
+   <!-- Child elements are empty but will have appropriate attributes.
+        Any valid notification message child element can appear.-->
+
+
+5.  Shared Calendaring
+
+5.1.  Feature Discovery
+
+   A server that supports the features described in this document MUST
+   include "calendarserver-sharing" as a field in the DAV response
+   header from an OPTIONS request on any resource that supports these
+   features.
+
+5.2.  Additional Properties for Calendars
+
+   The following new or modified WebDAV properties are defined for
+   calendar collections and used to view or manipulate shared calendar
+   features.
+
+5.2.1.  DAV:resourcetype Property
+
+   Calendar collections that are shared have addition elements listed in
+   their DAV:resourcetype property in addition to DAV:collection and
+   CALDAV:calendar.
+
+   o  CS:shared-owner (Section 6.1): used to indicate that the calendar
+      is owned by the current user and is being shared by them.
+
+   o  CS:shared (Section 6.2): used to indicate that the calendar is
+      owned by another user and is being shared to the current user.
+
+
+
+
+
+
+
+Daboo & York                                                    [Page 7]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+5.2.2.  CS:invite Property
+
+   Name:  invite
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to show to whom a calendar has been shared.
+
+   Protected:  This property MUST be protected.
+
+   PROPFIND behavior:  This property SHOULD NOT be returned by a
+      PROPFIND allprop request (as defined in Section 14.2 of
+      [RFC4918]).
+
+   COPY/MOVE behavior:  This property value MUST be preserved in COPY
+      and MOVE operations.
+
+   Description:  This WebDAV property is present on a calendar
+      collection resource that has been shared by the owner.  It MUST
+      NOT appear on the calendar collection resources of the sharees of
+      the calendar.  It provides a list of users to whom the calendar
+      has been shared, along with the "status" of the sharing invites
+      sent to each user.
+
+   Definition:
+
+   <!ELEMENT invite (user*)>
+
+5.2.3.  CS:allowed-sharing-modes Property
+
+   Name:  allowed-sharing-modes
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to show which modes of sharing are supported on a
+      calendar collection.
+
+   Protected:  This property MUST be protected.
+
+   PROPFIND behavior:  This property SHOULD NOT be returned by a
+      PROPFIND allprop request (as defined in Section 14.2 of
+      [RFC4918]).
+
+   COPY/MOVE behavior:  This property value MUST be preserved in COPY
+      and MOVE operations.
+
+
+
+
+
+
+Daboo & York                                                    [Page 8]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Description:  This WebDAV property is present on a calendar
+      collection resource that can been shared or published.  It
+      provides a list of options indicating what sharing modes are
+      allowed as per Section 5.5.2.
+
+   Definition:
+
+   <!ELEMENT allowed-sharing-modes
+             (can-be-shared?, can-be-published?)>
+
+5.2.4.  CS:shared-url Property
+
+   Name:  shared-url
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Indicates the URL of the owner's copy of a shared calendar.
+
+   Protected:  This property MUST be protected.
+
+   PROPFIND behavior:  This property SHOULD NOT be returned by a
+      PROPFIND allprop request (as defined in Section 14.2 of
+      [RFC4918]).
+
+   COPY/MOVE behavior:  This property value MUST be preserved in COPY
+      and MOVE operations.
+
+   Description:  This WebDAV property is present on a shared calendar
+      collection resource that appears in a sharee's calendar home
+      collection.  Its content is a single DAV:href element whose value
+      is the URL of the sharer's calendar being shared.
+
+   Definition:
+
+   <!ELEMENT shared-url (DAV:href)>
+
+5.3.  Sharer Actions on Shared Calendars
+
+5.3.1.  Creating a Shared Calendar
+
+   To create a shared calendar, clients use the MKCALENDAR [RFC4791] or
+   extended MKCOL [RFC5689] requests, and include a DAV:resourcetype
+   property to be set upon creation.  That property MUST contain DAV:
+   collection, CALDAV:calendar and CS:shared-owner child elements to
+   enable sharing.
+
+
+
+
+
+
+Daboo & York                                                    [Page 9]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+5.3.1.1.  Example: Successful MKCALENDAR Request
+
+   This example shows how the MKCALENDAR request is used to create a
+   shared calendar collection.  The response body is empty as the
+   request completed successfully.
+
+   >> Request <<
+
+   MKCALENDAR /calendars/users/cyrus/shared/ HTTP/1.1
+   Host: calendar.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <C:mkcalendar xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav"
+                 xmlns:CS="http://calendarserver.org/ns/">
+     <D:set>
+       <D:prop>
+         <D:resourcetype>
+           <D:collection/>
+           <C:calendar/>
+           <CS:shared-owner/>
+         </D:resourcetype>
+       </D:prop>
+     </D:set>
+   </C:mkcalendar>
+
+   >> Response <<
+
+   HTTP/1.1 201 Created
+   Cache-Control: no-cache
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+
+5.3.1.2.  Example: Successful Extended MKCOL Request
+
+   This example shows how the extended MKCOL request is used to create a
+   shared calendar collection.  The response body is empty as the
+   request completed successfully.
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 10]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   >> Request <<
+
+   MKCOL /calendars/users/cyrus/shared/ HTTP/1.1
+   Host: calendar.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:mkcol xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav"
+                 xmlns:CS="http://calendarserver.org/ns/">
+     <D:set>
+       <D:prop>
+         <D:resourcetype>
+           <D:collection/>
+           <C:calendar/>
+           <CS:shared-owner/>
+         </D:resourcetype>
+       </D:prop>
+     </D:set>
+   </D:mkcol>
+
+   >> Response <<
+
+   HTTP/1.1 201 Created
+   Cache-Control: no-cache
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+
+5.3.2.  Sharing an Existing Calendar
+
+   Sharing an existing calendar can be accomplished in two ways.  One
+   option is to use a PROPPATCH request to set the DAV:resourcetype
+   property to include CS:shared-owner as a child element.  Another
+   option is to add sharee's directly to the calendar collection (as
+   described in Section 5.3.3) - that action MUST upgrade a non-shared
+   calendar to a shared calendar when it completes successfully,
+   assuming that such an upgrade is allowed as per Section 5.5.2.
+
+5.3.2.1.  Example: Successful PROPPATCH Request
+
+   This example shows how the PROPPATCH request is used to upgrade to a
+   shared calendar collection.
+
+
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 11]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   >> Request <<
+
+   PROPPATCH /calendars/users/cyrus/shared/ HTTP/1.1
+   Host: calendar.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:propertyupdate xmlns:D="DAV:"
+                 xmlns:C="urn:ietf:params:xml:ns:caldav"
+                 xmlns:CS="http://calendarserver.org/ns/">
+     <D:set>
+       <D:prop>
+         <D:resourcetype>
+           <D:collection/>
+           <C:calendar/>
+           <CS:shared-owner/>
+         </D:resourcetype>
+       </D:prop>
+     </D:set>
+   </D:propertyupdate>
+
+   >> Response <<
+
+   HTTP/1.1 207 Multi-Status
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:">
+     <D:response>
+       <D:href>/calendars/users/cyrus/shared/</D:href>
+       <D:propstat>
+         <D:prop>
+           <D:resourcetype/>
+         </D:prop>
+         <D:status>HTTP/1.1 200 OK</D:status>
+       </D:propstat>
+     </D:response>
+   </D:multistatus>
+
+5.3.3.  Manipulating Sharees of a Shared Calendar
+
+   The sharer of a shared calendar is able to manipulate the sharee list
+   by issuing a POST request targeted at the shared calendar collection
+   resource.  The POST request MUST contain an XML document as its body
+   with the root element being CS:share (Section 6.24).
+
+
+
+Daboo & York                                                   [Page 12]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   The CS:share (Section 6.24) element in the POST requests MUST contain
+   one or more CS:set (Section 6.25) or CS:remove (Section 6.26)
+   elements.  For each CS:set (Section 6.25) element, the server MUST
+   add the specified sharee access to the shared calendar.  For each CS:
+   remove (Section 6.26) element the server MUST remove the specified
+   sharee access from the shared calendar.  In each case the server MUST
+   send a notification message to any sharees whose status is changed
+   (added, modified or removed), indicating to them a change in status
+   for the shared calendar.  The server SHOULD NOT send notification
+   messages to sharees whose status is unchanged.
+
+   Sharee's are identified via a DAV:href element whose value is either
+   a principal-URL for a sharee hosted on the same server, a calendar
+   user address or email address.  In the case of the later two, the
+   sharee might not be a user on the same server - though in that case
+   how invitations are sent or access enabled is out of scope for this
+   specification.  A server MAY change the sharee's "address" to any
+   suitable alternative that it might prefer when returning the list of
+   sharees via the CS:invite property (Section 5.2.2).
+
+   The client MAY include a CS:common-name (Section 6.19) element in the
+   CS:set (Section 6.25) element.  When provided, the value represents
+   the common name for the sharee, and is returned in the list of
+   sharees via the CS:invite property (Section 5.2.2).  The server MAY
+   change this to a suitable alternative when it is able to match the
+   sharee to a known user.  If absent from the client request, the
+   server SHOULD add a CS:common-name when it is able to match the
+   sharee with a known user, and a common name for that user can be
+   determined.
+
+   When the sharee list on a shared calendar is changed, the server MUST
+   send notifications to each sharee to update them on their current
+   sharing status.  This is accomplished by sending a CS:invite-
+   notification (Section 6.15) notification to each sharee.
+
+5.3.3.1.  Example: Successful Sharee Add Request
+
+   This example shows how to add a single sharee (with calendar user
+   address "mailto:eric at example.com") to a shared calendar with CS:read-
+   write access.
+
+
+
+
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 13]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   >> Request <<
+
+   POST /calendars/users/cyrus/shared/ HTTP/1.1
+   Host: calendar.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <CS:share xmlns:D="DAV:"
+                 xmlns:CS="http://calendarserver.org/ns/">
+     <CS:set>
+       <D:href>mailto:eric at example.com</D:href>
+       <CS:common-name>Eric York</CS:common-name>
+       <CS:summary>Shared workspace</CS:summary>
+       <CS:read-write />
+     </CS:set>
+   </CS:share>
+
+   >> Response <<
+
+   HTTP/1.1 200 OK
+   Cache-Control: no-cache
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+
+5.3.3.2.  Example: Successful Multiple Sharee Change Request
+
+   This example shows how multiple sharee's can be manipulated in a
+   single request.  The sharee with calendar user address
+   "mailto:eric at example.com" has their access downgraded to CS:read,
+   whilst another sharee is removed from the access list entirely.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 14]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   >> Request <<
+
+   POST /calendars/users/cyrus/shared/ HTTP/1.1
+   Host: calendar.example.com
+   Content-Type: application/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <CS:share xmlns:D="DAV:"
+                 xmlns:CS="http://calendarserver.org/ns/">
+     <CS:set>
+       <D:href>mailto:eric at example.com</D:href>
+       <CS:summary>Shared workspace</CS:summary>
+       <CS:read-write />
+     </CS:set>
+     <CS:remove>
+       <D:href>mailto:wilfredo at example.com</D:href>
+     </CS:remove>
+   </CS:share>
+
+   >> Response <<
+
+   HTTP/1.1 200 OK
+   Cache-Control: no-cache
+   Date: Sat, 11 Nov 2006 09:32:12 GMT
+
+5.4.  Sharee Actions on Shared Calendars
+
+5.4.1.  Replying to a Sharing Invite
+
+   When a sharee is invited to a shared calendar they can accept or
+   decline the invite by issuing a POST request to the sharee's calendar
+   home collection resource.  The POST request MUST contain an XML
+   document as its body with the root element being CS:invite-reply
+   (Section 6.20).
+
+   The CS:invite-reply (Section 6.20) element in the POST request
+   specifies the sharee who is replying in the DAV:href element, the
+   accept or decline action via the CS:invite-accepted or CS:invite-
+   declined elements, the URL of the shared calendar in the CS:hosturl
+   element, the unique identifier of the invite to which it is a reply
+   in the CS:in-reply-to element, and an optional CS:summary element.
+
+   The response to a POST request that accepts a shared calendar invite
+   MUST be an XML document containing CS:shared-as (Section 6.27) as its
+   root element.  That root element contains a single DAV:href element
+   whose content is the URI of the shared calendar in the sharee's
+   calendar home created by the invite acceptance.
+
+
+
+Daboo & York                                                   [Page 15]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   When the sharee replies to an invite, the server SHOULD send a
+   notification to the sharer to update them on the change in the sharee
+   state.  This is accomplished by sending a CS:invite-reply
+   (Section 6.20) notification to the sharer.
+
+5.4.2.  Removing a Shared Calendar
+
+   To remove a shared calendar from a sharee's calendar home collection
+   a DELETE request is targeted at the shared calendar URI.  When such a
+   request is received the server MUST remove the shared calendar from
+   the sharee's calendar home and automatically update the sharee's
+   status in the sharer's calendar's CS:invite property.
+
+5.5.  General Considerations
+
+5.5.1.  Access Levels
+
+   Two levels of access ca be granted by a sharer to any sharee.  These
+   are governed by the CS:access element used in the CS:invite/CS:user
+   element that specifies a shared user invite.  CS:access contains a
+   single empty element that defines the type of access granted:
+
+   CS:read  When present this indicates that sharees can read calendar
+      data but cannot change it.
+
+   CS:read-write  When present this indicates that sharees can read and
+      write calendar data.
+
+5.5.2.  Allowing or Disallowing Sharing
+
+   Servers MAY support calendar sharing on a per-calendar basis - e.g.,
+   they could treat some calendars as always private (cannot be shared)
+   or always public (always shared).  As a result clients need a way to
+   determine which calendar could be shared so they can enable or
+   disable sharing options on a per-calendar basis.
+
+   This specification adds a CS:allowed-sharing-modes (Section 5.2.3)
+   WebDAV property which servers can return on calendar collection
+   resources.  This property contains XML elements that describe which
+   sharing or publishing capabilities can be supported by the
+   corresponding calendar collection:
+
+      CS:can-be-shared (Section 6.3): when present indicates that the
+      calendar collection can be shared.  When not present, the calendar
+      collection cannot be shared.
+
+      CS:can-be-published (Section 6.4): when present indicates that the
+      calendar collection can be published.  When not present, the
+
+
+
+Daboo & York                                                   [Page 16]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+      calendar collection cannot be published.
+
+   When not present on a calendar collection, sharing or publishing of
+   that calendar is not allowed.  Clients SHOULD NOT attempt to use
+   requests to enable sharing or publishing targeted at those calendar
+   collections.
+
+5.5.3.  Per-user WebDAV Properties
+
+   Servers MUST support "per-user" WebDAV properties on shared calendar
+   collections and MAY support them on calendar object resources within
+   shared calendar collections.  A "per-user" WebDAV property is one
+   whose value can be set and retrieved independently by each user with
+   appropriate access rights. e.g., user "A" changes the DAV:displayname
+   property on a shared calendar in their calendar home to "My
+   calendar", and user "B" changes the same property to "Shared" on the
+   same shared calendar in their calendar home.  When each user
+   retrieves the property value they will see their own last stored
+   value and not the value of the other user.
+
+   For shared calendars, the server MUST allow all users to write "per-
+   user" WebDAV properties on the shared calendar collection and MAY
+   allow property writes on calendar object resources within the shared
+   calendar collection.  This is required even in the case where the
+   sharee has been granted read access only (i.e., the ability to change
+   calendar data is disallowed).  This requirement ensures that sharees
+   can always change "personal" properties such as calendar colors and
+   display names.
+
+   Servers MUST treat the following properties as "per-user":
+
+      DAV:displayname
+
+      CALDAV:calendar-description
+
+      CALDAV:schedule-calendar-transp
+
+      ICAL:calendar-color
+
+   Servers MAY treat any dead property as per-user.
+
+   Servers MUST NOT treat live properties as per-user.
+
+5.5.4.  Per-user Calendar Data
+
+   Servers MUST support "per-user" calendar data in calendar object
+   resources stored in shared calendars.  This allows each sharee and
+   the sharer to store their own alarms and free busy transparency
+
+
+
+Daboo & York                                                   [Page 17]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   status without "interfering" with other users who also have access to
+   the same calendar object resources.
+
+   For calendaring object resources in shared calendar collections, the
+   server MUST treat the following iCalendar data objects as per-user:
+
+      TRANSP property
+
+      VALARM component
+
+   Servers MAY treat any non-standard X- iCalendar properties as per-
+   user.
+
+   When handling per-user data in recurring components, servers SHOULD
+   eliminate overridden instances when returning iCalendar data to
+   clients in the case where there are no differences between the
+   overridden component and the instance that could be derived from the
+   "master" recurrence component.  For example, consider a daily
+   recurring event, Monday through Friday, initially defined without any
+   overridden instances, that is in a shared calendar.  If user "A"
+   overrides the Tuesday instance and adds their own "VALARM" component
+   only, then when user "A" later retrieves the data again they would
+   see that overridden instance, but when user "B" does so, they would
+   not.  This ensures that each user sees the most "compact"
+   representation of the calendar data.
+
+5.5.5.  Scheduling
+
+   CalDAV Scheduling [I-D.desruisseaux-caldav-sched] defines how a
+   CalDAV server carries out scheduling operations when calendar object
+   resources are created, modified or deleted and include "ORGANIZER"
+   and "ATTENDEE" iCalendar properties.
+
+   When calendar object resources are created, modified or deleted in
+   shared calendars by sharees, the following restrictions apply:
+
+   1.  The "ORGANIZER" iCalendar property value in the iCalendar data
+       MUST match a calendar user address of the sharer (owner) of the
+       shared calendar.  The DAV:owner WebDAV property MUST be present
+       on a shared calendar and MUST provide a reference to a principal-
+       URL of the sharer (owner) of the shared calendar.  Clients can
+       use this value to determine what the allowed "ORGANIZER"
+       iCalendar property values are.  The server MUST reject any
+       attempt by a sharee to create an iCalendar component with an
+       "ORGANIZER" property value other than the sharer (owner) of the
+       shared calendar.
+
+
+
+
+
+Daboo & York                                                   [Page 18]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   2.  The server MUST reject any attempt by a sharee to MOVE a calendar
+       object resource in a shared calendar to some other collection.
+
+   3.  When a sharee is listed as an Attendee in a calendar object
+       resource in a shared calendar, and write access is granted, the
+       sharee is allowed to change not only iCalendar data related to
+       the Organizer, but also data related to the Attendee. i.e., a
+       sharee can change their own participation status on the
+       "ATTENDEE" iCalendar property referring to them.  Additionally,
+       if the sharee is not listed as an Attendee, and write access is
+       granted, the sharee can add themselves as an Attendee.
+
+   4.  The default calendar collection defined in Section 6.3 of
+       [I-D.desruisseaux-caldav-sched] MUST NOT be a calendar shared to
+       the corresponding calendar user.
+
+   Following are additional considerations for scheduling with shared
+   calendars:
+
+   1.  A scheduled iCalendar component could appear in more than one
+       calendar collection within a sharee's calendar home if the sharee
+       is an Attendee and the Organizer or other Attendees have shared a
+       calendar with the sharee that includes their copies of the
+       iCalendar component.  It is important to note that the scheduled
+       component in the shared calendar could have different access
+       rights than the one in the sharee's owned calendar.
+
+   2.  A scheduled iCalendar component appearing in a sharee's shared
+       calendar could include the sharee as an Attendee.  For recurring
+       events, it is possible for the sharee to only be listed as an
+       Attendee in some instances, as opposed to all.  Clients will need
+       to be aware of this when allowing sharee's to set their own
+       participation status.
+
+   In addition, when a shared calendar is first accepted by a sharee,
+   the server SHOULD set the CALDAV:schedule-calendar-transp property to
+   the value CALDAV:transparent to ensure newly accepted shared
+   calendars do not contribute to the sharee's freebusy time until the
+   sharee explicitly requests it.
+
+
+6.  XML Element Definitions
+
+6.1.  CS:shared-owner
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 19]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Name:  shared-owner
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to indicate that a calendar is being shared by the
+      owner.
+
+   Description:  This property appears in the DAV:resourcetype property
+      on the calendar collection resource shared by a sharer.  See
+      Section 5.2.
+
+   Definition:
+
+   <!ELEMENT shared-owner EMPTY>
+
+6.2.  CS:shared
+
+   Name:  shared
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to indicate that a calendar is being shared to a
+      sharee.
+
+   Description:  This property appears in the DAV:resourcetype property
+      on a calendar collection resource that is shared to a sharee and
+      appears in the sharee's calendar home collection.  See
+      Section 5.2.
+
+   Definition:
+
+   <!ELEMENT shared EMPTY>
+
+6.3.  CS:can-be-shared
+
+   Name:  can-be-shared
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to indicate that a calendar can be shared.
+
+   Description:  This element indicates that a calendar can be shared
+      with other users.  See Section 5.2.3
+
+   Definition:
+
+   <!ELEMENT can-be-shared EMPTY>
+
+
+
+
+Daboo & York                                                   [Page 20]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+6.4.  CS:can-be-published
+
+   Name:  can-be-published
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to indicate that a calendar can be published.
+
+   Description:  This element indicates that a calendar can be published
+      to anyone.  See Section 5.2.3
+
+   Definition:
+
+   <!ELEMENT can-be-published EMPTY>
+
+6.5.  CS:user
+
+   Name:  user
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Used to show status of sharing invites sent to sharees.
+
+   Description:  This element provides the "status" of a sharing invite
+      sent to a particular user.  See Section 5.2.2.
+
+   Definition:
+
+   <!ELEMENT user (DAV:href, common-name?, (invite-noresponse |
+                   invite-accepted | invite-declined | invite-invalid),
+                   access, summary?)>
+
+6.6.  CS:invite-noresponse
+
+   Name:  invite-noresponse
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Sharing invite status.
+
+   Description:  When used in a CS:user (Section 6.5) element, this
+      element is used to indicate that the sharee has never replied to
+      the corresponding sharing invite.  When used in a CS:invite-
+      notification (Section 6.15) element, this element is used to
+      indicate to the sharee that a sharing reply is needed.
+
+
+
+
+
+
+Daboo & York                                                   [Page 21]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Definition:
+
+   <!ELEMENT invite-noresponse EMPTY>
+
+6.7.  CS:invite-deleted
+
+   Name:  invite-deleted
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Sharing invite status.
+
+   Description:  When used in a CS:invite-notification (Section 6.15)
+      element, this element is used to indicate to the sharee that a
+      shared calendar has been unshared by the sharer.
+
+   Definition:
+
+   <!ELEMENT invite-deleted EMPTY>
+
+6.8.  CS:invite-accepted
+
+   Name:  invite-accepted
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Sharing invite status.
+
+   Description:  When used in a CS:user (Section 6.5) element, this
+      element is used to indicate that the sharee has accepted the
+      corresponding sharing invite.  When used in a CS:invite-
+      notification (Section 6.15) element, this element is used to
+      indicate to the sharee that the sharing invite is an update for
+      one they previously accepted.
+
+   Definition:
+
+   <!ELEMENT invite-accepted EMPTY>
+
+6.9.  CS:invite-declined
+
+   Name:  invite-declined
+
+   Namespace:  http://calendarserver.org/ns/
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 22]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Purpose:  Sharing invite status.
+
+   Description:  When used in a CS:user (Section 6.5) element, this
+      element is used to indicate that the sharee has declined the
+      corresponding sharing invite.  When used in a CS:invite-
+      notification (Section 6.15) element, this element is used to
+      indicate to the sharee that the sharing invite is an update for
+      one they previously declined.
+
+   Definition:
+
+   <!ELEMENT invite-declined EMPTY>
+
+6.10.  CS:invite-invalid
+
+   Name:  invite-invalid
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Sharing invite status.
+
+   Description:  When used in a CS:user (Section 6.5) element, this
+      element is used to indicate that the corresponding sharee is not a
+      valid calendar user known to the server.
+
+   Definition:
+
+   <!ELEMENT invite-invalid EMPTY>
+
+6.11.  CS:access
+
+   Name:  access
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Shared calendar access level.
+
+   Description:  When used in a CS:user (Section 6.5) element, this
+      element is used to indicate the sharing access level granted to
+      the corresponding sharee.
+
+   Definition:
+
+   <!ELEMENT invite-invalid (read | read-write)>
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 23]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+6.12.  CS:read
+
+   Name:  read
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Shared calendar access level privilege.
+
+   Description:  Indicates that the access level granted only allows
+      sharees to read data in the shared calendar (though they can write
+      per-user data (Section 5.5.4)).
+
+   Definition:
+
+   <!ELEMENT read EMPTY>
+
+6.13.  CS:read-write
+
+   Name:  read-write
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Shared calendar access level privilege.
+
+   Description:  Indicates that the access level granted allows sharees
+      to read and write all data in the shared calendar, with the
+      exception of components that would trigger scheduling.
+
+   Definition:
+
+   <!ELEMENT read-write EMPTY>
+
+6.14.  CS:summary
+
+   Name:  summary
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Summary or title of shared calendar.
+
+   Description:  A brief description of a shared calendar.  This can be
+      used by sharers to communicate the nature of a shared calendar to
+      sharees, as well as used by sharees to indicate back to the sharer
+      how each sharee is refering to the shared calendar.
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 24]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Definition:
+
+   <!ELEMENT summary (#PCDATA)>
+
+6.15.  CS:invite-notification
+
+   Name:  invite-notification
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  A notification used as a shared calendar invite.
+
+   Description:  Defines a notification message sent automatically by
+      the server when a sharer adds, changes or removes a sharee from a
+      shared calendar.  The DAV:href element specifies the calendar user
+      address of the sharee to whom the message was sent.
+
+   Definition:
+
+   <!ELEMENT invite-notification (uid, DAV:href,
+                                  (invite-noresponse | invite-deleted |
+                                   invite-accepted | invite-declined),
+                                  access, hosturl, organizer, summary?>
+
+6.16.  CS:uid
+
+   Name:  uid
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Unique identifier.
+
+   Description:  A unique identifier for an invitation to a shared
+      calendar.
+
+   Definition:
+
+   <!ELEMENT uid (#PCDATA)>
+
+6.17.  CS:hosturl
+
+   Name:  hosturl
+
+   Namespace:  http://calendarserver.org/ns/
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 25]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Purpose:  Identifies the source URL of a shared calendar.
+
+   Description:  Contains a single DAV:href element that refers to the
+      source of a shared calendar - i.e., the URL of the calendar shared
+      by the sharer.
+
+   Definition:
+
+   <!ELEMENT hosturl (DAV:href)>
+
+6.18.  CS:organizer
+
+   Name:  organizer
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Identifies the sharer of a shared calendar.
+
+   Description:  Contains a single DAV:href element that identifies the
+      calendar user address of the sharer of a shared calendar, and an
+      optional CS:common-name element that matches that user.
+
+   Definition:
+
+   <!ELEMENT organizer (DAV:href, CS:common-name?)>
+
+6.19.  CS:common-name
+
+   Name:  common-name
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  The common name of a sharer or sharee.
+
+   Description:  The common name is optionally provided by a client when
+      adding a sharee and optionally included (or modified) by the
+      server when returning results for sharers or sharees and in
+      notifications.
+
+   Definition:
+
+   <!ELEMENT common-name (#PCDATA)>
+
+6.20.  CS:invite-reply
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 26]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+   Name:  invite-reply
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  A notification used as a reply to a shared calendar invite.
+
+   Description:  Defines a notification message sent automatically by
+      the server when a sharee replies to a shared calendar invite.  The
+      DAV:href element specifies the calendar user address of the sharee
+      to whom the original invite message was sent.
+
+   Definition:
+
+   <!ELEMENT invite-reply (DAV:href,
+                           (invite-accepted | invite-declined),
+                           hosturl, in-reply-to, summary?>
+
+6.21.  CS:in-reply-to
+
+   Name:  in-reply-to
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Unique identifier.
+
+   Description:  Specifies the unique identifier of the inviate message
+      that this notification message is a reply to.
+
+   Definition:
+
+   <!ELEMENT in-reply-to (#PCDATA)>
+
+6.22.  CS:notification
+
+   Name:  notification
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Notification message root element.
+
+   Description:  The root element used in notification resources.
+
+   Definition:
+
+   <!ELEMENT notification (CS:dtstamp,
+                           (invite-notification | invite-reply)>
+   <!-- Any notification type element can appear after CS:dtstamp,
+        this specification defines only the two listed above -->
+
+
+
+Daboo & York                                                   [Page 27]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+6.23.  CS:dtstamp
+
+   Name:  dtstamp
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Date-time stamp.
+
+   Description:  Contains the date-time stamp corresponding to the
+      creation of a notification message.
+
+   Definition:
+
+   <!ELEMENT dtstamp (#PCDATA)>
+
+6.24.  CS:share
+
+   Name:  share
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Describes changes to sharees.
+
+   Description:  The root element used in POST requests on calendars by
+      sharers to manipulate the sharee list of a shared calendar.
+
+   Definition:
+
+   <!ELEMENT share (set | remove)*>
+
+6.25.  CS:set
+
+   Name:  set
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Sets access for a sharee.
+
+   Description:  Used to add or modify sharee access to a shared
+      calendar.  The specified access to the shared calendar is given to
+      the sharee.
+
+   Definition:
+
+   <!ELEMENT set (DAV:href, common-name?, summary?,
+                  (read | read-write)>
+
+
+
+
+
+Daboo & York                                                   [Page 28]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+6.26.  CS:remove
+
+   Name:  remove
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Removes access for a sharee.
+
+   Description:  Used to remove sharee access to a shared calendar.  All
+      access to the shared calendar is removed for the sharee.
+
+   Definition:
+
+   <!ELEMENT remove (DAV:href)>
+
+6.27.  CS:shared-as
+
+   Name:  shared-as
+
+   Namespace:  http://calendarserver.org/ns/
+
+   Purpose:  Identifies a shared calendar.
+
+   Description:  Returned by the server for a POST request by a sharee
+      accepting a shared calendar invite.  The DAV:href element
+      specifies the URI of the calendar created by the acceptance.
+
+   Definition:
+
+   <!ELEMENT shared-as (DAV:href)>
+
+
+7.  Security Considerations
+
+   Per-user WebDAV properties and iCalendar data MUST only be accessible
+   by the user that created them.
+
+   Alarms set by the sharer SHOULD NOT be propagated to sharees by
+   default.  Clients SHOULD NOT automatically enable triggering of
+   alarms on shared calendars that have just been accepted without
+   confirmation by the user.
+
+   TBD
+
+
+8.  IANA Considerations
+
+   This document does not require any actions on the part of IANA.
+
+
+
+Daboo & York                                                   [Page 29]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+9.  Acknowledgments
+
+   This specification is the result of discussions between the Apple
+   calendar server and client teams.
+
+
+10.  Normative References
+
+   [I-D.desruisseaux-caldav-sched]
+              Daboo, C. and B. Desruisseaux, "CalDAV Scheduling
+              Extensions to WebDAV", draft-desruisseaux-caldav-sched-08
+              (work in progress), August 2009.
+
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC3744]  Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
+              Distributed Authoring and Versioning (WebDAV)
+              Access Control Protocol", RFC 3744, May 2004.
+
+   [RFC4791]  Daboo, C., Desruisseaux, B., and L. Dusseault,
+              "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
+              March 2007.
+
+   [RFC4918]  Dusseault, L., "HTTP Extensions for Web Distributed
+              Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
+
+   [RFC5689]  Daboo, C., "Extended MKCOL for Web Distributed Authoring
+              and Versioning (WebDAV)", RFC 5689, September 2009.
+
+
+Appendix A.  Change History
+
+   Changes in -02:
+
+   1.  Removed read-write-shared access mode - now a server that does
+       not support shared scheduling should advertise that via a DAV
+       header
+
+
+Appendix B.  Change History
+
+   Changes in -01:
+
+   1.  Added CS:shared-url property
+
+   2.  Clarified that notifications are only required to be sent when
+       sharee status is changed
+
+
+
+Daboo & York                                                   [Page 30]
+
+                      CalDAV Sharing and Publishing         October 2010
+
+
+Authors' Addresses
+
+   Cyrus Daboo
+   Apple Inc.
+   1 Infinite Loop
+   Cupertino, CA  95014
+   USA
+
+   Email: cyrus at daboo.name
+   URI:   http://www.apple.com/
+
+
+   Eric York
+   Apple Inc.
+   1 Infinite Loop
+   Cupertino, CA  95014
+   USA
+
+   Email:
+   URI:   http://www.apple.com/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & York                                                   [Page 31]
+

Copied: CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.xml (from rev 6432, CalendarServer/trunk/doc/Extensions/caldav-sharing-02.xml)
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.xml	                        (rev 0)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/doc/Extensions/caldav-sharing-02.xml	2010-10-18 04:33:34 UTC (rev 6433)
@@ -0,0 +1,1111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet type="text/xsl" href="../rfc2629.xslt"?>
+<!DOCTYPE rfc SYSTEM 'rfc2629.dtd' [
+<!ENTITY rfc2119 PUBLIC '' 'bibxml/reference.RFC.2119.xml'>
+<!ENTITY rfc3744 PUBLIC '' 'bibxml/reference.RFC.3744.xml'>
+<!ENTITY rfc4791 PUBLIC '' 'bibxml/reference.RFC.4791.xml'>
+<!ENTITY rfc4918 PUBLIC '' 'bibxml/reference.RFC.4918.xml'>
+<!ENTITY rfc5689 PUBLIC '' 'bibxml/reference.RFC.5689.xml'>
+<!ENTITY I-D.desruisseaux-caldav-sched PUBLIC '' 'bibxml3/reference.I-D.desruisseaux-caldav-sched.xml'>
+]> 
+<?rfc toc="yes"?>
+<?rfc tocdepth="4"?>
+<?rfc strict="yes"?>
+<?rfc comments="yes"?>
+<?rfc inline="yes"?>
+<?rfc symrefs="yes"?>
+<?rfc sortrefs="yes"?>
+<?rfc compact="yes"?>
+<?rfc subcompact="no"?>
+<?rfc private="Calendar Server Extension"?>
+<rfc ipr="none" docName='caldav-sharing-02'>
+    <front>
+        <title abbrev="CalDAV Sharing and Publishing">Shared and Published Calendars in CalDAV</title> 
+        <author initials="C." surname="Daboo" fullname="Cyrus Daboo">
+            <organization abbrev="Apple Inc.">
+                Apple Inc.
+            </organization>
+            <address>
+                <postal>
+                    <street>1 Infinite Loop</street>
+                    <city>Cupertino</city>
+                    <region>CA</region>
+                    <code>95014</code> 
+                    <country>USA</country>
+                </postal>
+                <email>cyrus at daboo.name</email>
+                <uri>http://www.apple.com/</uri>
+            </address>
+        </author>
+        <author initials="E." surname="York" fullname="Eric York">
+            <organization abbrev="Apple Inc.">
+                Apple Inc.
+            </organization>
+            <address>
+                <postal>
+                    <street>1 Infinite Loop</street>
+                    <city>Cupertino</city>
+                    <region>CA</region>
+                    <code>95014</code> 
+                    <country>USA</country>
+                </postal>
+                <email></email>
+                <uri>http://www.apple.com/</uri>
+            </address>
+        </author>
+        <date/>
+        <abstract>
+            <t>
+                This specification defines an extension to CalDAV that enables the sharing of calendars between users on a CalDAV server.
+            </t>
+        </abstract>
+    </front>
+    <middle>
+        <section title='Introduction'>
+            <t>
+                <xref target="RFC4791">CalDAV</xref> provides a way for calendar users to store calendar data and exchange this data via scheduling operations. Based on the <xref target='RFC4918'>WebDAV</xref> protocol, it also includes the ability to manage access to calendar data via the <xref target='RFC3744'>WebDAV ACL</xref> extension.
+            </t>
+            <t>
+                <xref target='RFC3744'>WebDAV ACL</xref> provides a way to manage fine-grained access controls on WebDAV resources. Whilst this could be used directly to manage sharing of calendars, experience has shown that client developers are averse to using it due to its complexity. Instead a simpler process for sharing calendars is preferred.
+            </t>
+            <t>
+                This extension defines a way for individual calendar users to share calendars with other users. This is done via an "opt-in" process in which a sharing invite is sent from the sharer to a sharee, allowing the sharee to accept or decline. If the sharee accepts the sharing invite, the shared calendar is made available to them in their own calendar home collection (i.e., alongside their own personal calendars). HTTP POST operations are used to manage the sharing invitations and replies, and WebDAV properties are used to expose the state of shared calendars.
+            </t>
+        </section>
+
+        <!--<section title="Open Issues">
+            <t>
+                <list style="numbers">
+                    <t>
+                    </t>
+                </list>
+            </t>
+        </section>-->
+            
+        <section title='Conventions Used in This Document'>
+            <t>
+                The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in <xref target='RFC2119' />. 
+            </t>
+            <t>
+                When XML element types in the namespaces "DAV:" and "urn:ietf:params:xml:ns:caldav" are referenced in this document outside of the context of an XML fragment, the string "DAV:" and "CALDAV:" will be prefixed to the element type names respectively. 
+            </t>
+            <t>
+                The namespace "http://calendarserver.org/ns/" is used for XML elements defined in this specification.  When XML element types in that namespace are referenced in this document outside of the context of an XML fragment, the string "CS:" will be prefixed to the element type names. 
+            </t>
+            <t>Terms Used:
+                <list style='hanging'>
+                    <t hangText='Sharer'>A calendar user who is sharing a calendar with other calendar users.</t>
+                    <t hangText='Sharee'>A calendar user to whom a calendar has been shared.</t>
+                    <t hangText='Sharing Invite'>A message sent by a sharer to a sharee to indicate the status of a shared calendar.</t>
+                    <t hangText='Sharing Reply'>A message sent by a sharee to a sharer to indicate the status of a shared calendar.</t>
+                </list>
+            </t>
+        </section>
+         
+        <section title='Overview' anchor='overview'>
+            <t>
+                This section provides a basic overview of this protocol by way of a simple use case of a sharer sharing a calendar with a single sharee.
+            </t>
+            <t>
+                To share a calendar with another user, the sharer's client executes an HTTP POST request against the calendar collection resource for the calendar to be shared. The POST request body will contain details of the calendar user to whom the calendar is to be shared as well as the access right to be granted to them. If the request succeeds, a notification is sent to the sharee with details of the calendar being shared to them.
+            </t>
+            <t>
+                The sharer's client will show the notification to the sharee and present them with the choice to accept or decline the invitation to the shared calendar. If the sharee chooses to decline, then nothing changes for that sharee. If the sharee chooses to accept, then the server automatically creates a new calendar collection resource in the sharee's calendar home collection, and ensures that calendar provides a mapping to the actual shared calendar of the sharer. Thus the shared calendar is available to the sharee as just another calendar in their calendar home. The server enforces the appropriare access privileges for the sharee.
+            </t>
+            <t>
+                At any time, the sharer can inspect properties on the calendar collection being shared, and determine the accept/decline status of each sharee. Additional sharees can be added and existing ones removed. The access privileges for existing sharees can also be changed.
+            </t>
+            <t>
+            	Once a sharee has a shared calendar set to appear in their calendar home collection, they can remove it and decline the sharing invite by simply having their client issue an HTTP DELETE request on the shared calendar collection. That does not delete any calendar data, but rather simply removes the "link" to the sharer's calendar collection and sets the sharee's inviate status to declined.
+            </t>
+        </section>
+        
+        <section title="Notifications">
+            <t>
+                In order to facilitate the process of sharing invitations, this specification defines a new generic notification mechanism for CalDAV servers. When this feature is available, a <xref target="CS:notification-URL">CS:notification-URL</xref> property appears on principal resources for those principals who are able to receive notifications. That property specifies a single DAV:href element whose content refers to a WebDAV collection resource. Notification "messages" are deposited into this collection and can be retrieved by clients and acted on accordingly.
+            </t>
+            <t>
+                The notification collection referenced by the <xref target="CS:notification-URL">CS:notification-URL</xref> property MUST have a DAV:resourcetype property with DAV:collection and <xref target="CS:notification">CS:notification</xref> child elements. 
+            </t>
+            <t>
+                Notification "messages" are XML documents stored as resources in the notification collection. Each XML document contains a <xref target="CS:notification">CS:notification</xref> element as its root. The root element contains a <xref target="CS:dtstamp">CS:dtstamp</xref> element, and one additional element which represents the type of notification being conveyed in the message. That child element will typically contain additional content that describes the notification.
+            </t>
+            <t>
+                Each notification resource has a <xref target="CS:notificationtype">CS:notificationtype</xref> property which contains as its single child element an empty element that matches the child element of the notification resource XML document root. Any attributes on the child element in the XML document are also present in the property child element.
+            </t>
+            <t>
+                Notifications are automatically generated by the server (perhaps in response to a client action) with an appropriate resource stored in the notifications collection of the user to whom the notification is targeted. Clients SHOULD monitor the notification collection looking for new notification resources. When doing so, clients SHOULD look at the <xref target="CS:notificationtype">CS:notificationtype</xref> property to ensure that the notification is of a type that the client can handle. Once a client has handled the notification in whatever way is appropriate it SHOULD delete the notification resource. Servers MAY delete notification resources on their own if they determine that the notifications are no longer relevant or valid. Servers MAY coalesce notifications as appropriate.
+            </t>
+            <section title="Additional Principal Properties" anchor='principal-properties'>
+                <t>
+                    This section defines new properties for WebDAV principal resources as defined in <xref target="RFC3744">RFC3744</xref>. These properties are likely to be protected but the server MAY allow them to be written by appropriate users.
+                </t>
+                <section title="CS:notification-URL Property" anchor="CS:notification-URL">
+                  <t>
+                    <list style="hanging">
+                      <t hangText="Name:">notification-URL</t>
+                      <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                      <t hangText="Purpose:">Identify the URL of the notification collection owned by the associated principal resource.</t>
+                      <t hangText="Protected:">This property SHOULD be protected.</t>
+                      <t hangText="PROPFIND behavior:">This property SHOULD NOT be returned by a PROPFIND allprop request (as defined in Section 14.2 of <xref target="RFC4918"/>).</t>
+                      <t hangText="COPY/MOVE behavior:">This property value SHOULD be preserved in COPY and MOVE operations.</t>
+        
+                      <t hangText="Description:">This property is needed for a client to determine where the notification collection of the current user is located so that processing of notification messages can occur. If not present, then the associated calendar user is not enabled for notification messages on the server.</t>
+                      <t hangText="Definition:">
+                        <figure>
+                          <artwork><![CDATA[
+<!ELEMENT notification-URL (DAV:href)>]]></artwork>
+                        </figure>
+                      </t>
+                    </list>
+                  </t>
+                </section>
+            </section>
+            <section title="Properties on Notification Resources" anchor='notification-properties'>
+                <t>
+                    The following new WebDAV properties are defined for notification resources.
+                </t>
+                <section title="CS:notificationtype Property" anchor="CS:notificationtype">
+                  <t>
+                    <list style="hanging">
+                      <t hangText="Name:">notificationtype</t>
+                      <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                      <t hangText="Purpose:">Identify the type of notification of the corresponding resource.</t>
+                      <t hangText="Protected:">This property MUST be protected.</t>
+                      <t hangText="PROPFIND behavior:">This property SHOULD NOT be returned by a PROPFIND allprop request (as defined in Section 14.2 of <xref target="RFC4918"/>).</t>
+                      <t hangText="COPY/MOVE behavior:">This property value MUST be preserved in COPY and MOVE operations.</t>
+        
+                      <t hangText="Description:">This property allows a client, via a PROPFIND Depth:1 request, to quickly find notification messages that the client can handle in a notification collection. The single child element is the notification resource root element's child defining the notification itself. This element MUST be empty, though any attributes on the element in the notification resource MUST be present in the property element.</t>
+                      <t hangText="Definition:">
+                        <figure>
+                          <artwork><![CDATA[
+<!ELEMENT notificationtype (invite-notification | invite-reply)>
+<!-- Child elements are empty but will have appropriate attributes.
+     Any valid notification message child element can appear.-->]]></artwork>
+                        </figure>
+                      </t>
+                    </list>
+                  </t>
+                </section>
+            </section>
+        </section>
+
+        <section title="Shared Calendaring">
+            <section title="Feature Discovery">
+                <t>
+                    A server that supports the features described in this document MUST include "calendarserver-sharing" as a field in the DAV response header from an OPTIONS request on any resource that supports these features.
+                </t>
+            </section>
+            <section title="Additional Properties for Calendars" anchor='properties'>
+                <t>
+                    The following new or modified WebDAV properties are defined for calendar collections and used to view or manipulate shared calendar features.
+                </t>
+                <section title="DAV:resourcetype Property" anchor="DAV:resourcetype">
+                    <t>
+                        Calendar collections that are shared have addition elements listed in their DAV:resourcetype property in addition to DAV:collection and CALDAV:calendar.
+                        <list style="symbols">
+                            <t><xref target="CS:shared-owner">CS:shared-owner</xref>: used to indicate that the calendar is owned by the current user and is being shared by them.</t>
+                            <t><xref target="CS:shared">CS:shared</xref>: used to indicate that the calendar is owned by another user and is being shared to the current user.</t>
+                        </list>
+                    </t>
+                </section>
+                <section title="CS:invite Property" anchor="CS:invite">
+                  <t>
+                    <list style="hanging">
+                      <t hangText="Name:">invite</t>
+                      <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                      <t hangText="Purpose:">Used to show to whom a calendar has been shared.</t>
+                      <t hangText="Protected:">This property MUST be protected.</t>
+                      <t hangText="PROPFIND behavior:">This property SHOULD NOT be returned by a PROPFIND allprop request (as defined in Section 14.2 of <xref target="RFC4918"/>).</t>
+                      <t hangText="COPY/MOVE behavior:">This property value MUST be preserved in COPY and MOVE operations.</t>
+        
+                      <t hangText="Description:">This WebDAV property is present on a calendar collection resource that has been shared by the owner. It MUST NOT appear on the calendar collection resources of the sharees of the calendar. It provides a list of users to whom the calendar has been shared, along with the "status" of the sharing invites sent to each user.</t>
+                      <t hangText="Definition:">
+                        <figure>
+                          <artwork><![CDATA[
+<!ELEMENT invite (user*)>]]></artwork>
+                        </figure>
+                      </t>
+                    </list>
+                  </t>
+                </section>
+                <section title="CS:allowed-sharing-modes Property" anchor="CS:allowed-sharing-modes">
+                  <t>
+                    <list style="hanging">
+                      <t hangText="Name:">allowed-sharing-modes</t>
+                      <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                      <t hangText="Purpose:">Used to show which modes of sharing are supported on a calendar collection.</t>
+                      <t hangText="Protected:">This property MUST be protected.</t>
+                      <t hangText="PROPFIND behavior:">This property SHOULD NOT be returned by a PROPFIND allprop request (as defined in Section 14.2 of <xref target="RFC4918"/>).</t>
+                      <t hangText="COPY/MOVE behavior:">This property value MUST be preserved in COPY and MOVE operations.</t>
+        
+                      <t hangText="Description:">This WebDAV property is present on a calendar collection resource that can been shared or published. It provides a list of options indicating what sharing modes are allowed as per <xref target="allowed"/>.</t>
+                      <t hangText="Definition:">
+                        <figure>
+                          <artwork><![CDATA[
+<!ELEMENT allowed-sharing-modes
+          (can-be-shared?, can-be-published?)>]]></artwork>
+                        </figure>
+                      </t>
+                    </list>
+                  </t>
+                </section>
+                <section title="CS:shared-url Property" anchor="CS:shared-url">
+                  <t>
+                    <list style="hanging">
+                      <t hangText="Name:">shared-url</t>
+                      <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                      <t hangText="Purpose:">Indicates the URL of the owner's copy of a shared calendar.</t>
+                      <t hangText="Protected:">This property MUST be protected.</t>
+                      <t hangText="PROPFIND behavior:">This property SHOULD NOT be returned by a PROPFIND allprop request (as defined in Section 14.2 of <xref target="RFC4918"/>).</t>
+                      <t hangText="COPY/MOVE behavior:">This property value MUST be preserved in COPY and MOVE operations.</t>
+        
+                      <t hangText="Description:">This WebDAV property is present on a shared calendar collection resource that appears in a sharee's calendar home collection. Its content is a single DAV:href element whose value is the URL of the sharer's calendar being shared.</t>
+                      <t hangText="Definition:">
+                        <figure>
+                          <artwork><![CDATA[
+<!ELEMENT shared-url (DAV:href)>]]></artwork>
+                        </figure>
+                      </t>
+                    </list>
+                  </t>
+                </section>
+            </section>
+            <section title="Sharer Actions on Shared Calendars">
+                <section title="Creating a Shared Calendar">
+                    <t>
+                        To create a shared calendar, clients use the <xref target="RFC4791">MKCALENDAR</xref> or <xref target="RFC5689">extended MKCOL</xref> requests, and include a DAV:resourcetype property to be set upon creation. That property MUST contain DAV:collection, CALDAV:calendar and CS:shared-owner child elements to enable sharing.
+                    </t>
+                    <section title="Example: Successful MKCALENDAR Request">
+            
+                        <t>
+                          This example shows how the MKCALENDAR request is used to create a shared calendar collection. The response body is empty as the request completed successfully.
+                        </t>
+    
+                        <figure>
+                          <preamble>&gt;&gt; Request &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+MKCALENDAR /calendars/users/cyrus/shared/ HTTP/1.1
+Host: calendar.example.com
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<C:mkcalendar xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav"
+              xmlns:CS="http://calendarserver.org/ns/">
+  <D:set>
+    <D:prop>
+      <D:resourcetype>
+        <D:collection/>
+        <C:calendar/>
+        <CS:shared-owner/>
+      </D:resourcetype>
+    </D:prop>
+  </D:set>
+</C:mkcalendar>]]></artwork>
+                        </figure>
+                        <figure>
+                          <preamble>&gt;&gt; Response &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Date: Sat, 11 Nov 2006 09:32:12 GMT]]></artwork>
+                        </figure>
+                    </section>
+                    <section title="Example: Successful Extended MKCOL Request">
+            
+                        <t>
+                          This example shows how the extended MKCOL request is used to create a shared calendar collection. The response body is empty as the request completed successfully.
+                        </t>
+    
+                        <figure>
+                          <preamble>&gt;&gt; Request &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+MKCOL /calendars/users/cyrus/shared/ HTTP/1.1
+Host: calendar.example.com
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<D:mkcol xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav"
+              xmlns:CS="http://calendarserver.org/ns/">
+  <D:set>
+    <D:prop>
+      <D:resourcetype>
+        <D:collection/>
+        <C:calendar/>
+        <CS:shared-owner/>
+      </D:resourcetype>
+    </D:prop>
+  </D:set>
+</D:mkcol>]]></artwork>
+                        </figure>
+                        <figure>
+                          <preamble>&gt;&gt; Response &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Date: Sat, 11 Nov 2006 09:32:12 GMT]]></artwork>
+                        </figure>
+                    </section>
+                </section>
+                <section title="Sharing an Existing Calendar">
+                    <t>
+                        Sharing an existing calendar can be accomplished in two ways. One option is to use a PROPPATCH request to set the DAV:resourcetype property to include CS:shared-owner as a child element. Another option is to add sharee's directly to the calendar collection (as described in <xref target="sharee"/>) - that action MUST upgrade a non-shared calendar to a shared calendar when it completes successfully, assuming that such an upgrade is allowed as per <xref target="allowed"/>.
+                    </t>
+                    <section title="Example: Successful PROPPATCH Request">
+            
+                        <t>
+                          This example shows how the PROPPATCH request is used to upgrade to a shared calendar collection.
+                        </t>
+    
+                        <figure>
+                          <preamble>&gt;&gt; Request &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+PROPPATCH /calendars/users/cyrus/shared/ HTTP/1.1
+Host: calendar.example.com
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<D:propertyupdate xmlns:D="DAV:"
+              xmlns:C="urn:ietf:params:xml:ns:caldav"
+              xmlns:CS="http://calendarserver.org/ns/">
+  <D:set>
+    <D:prop>
+      <D:resourcetype>
+        <D:collection/>
+        <C:calendar/>
+        <CS:shared-owner/>
+      </D:resourcetype>
+    </D:prop>
+  </D:set>
+</D:propertyupdate>]]></artwork>
+                        </figure>
+                        <figure>
+                          <preamble>&gt;&gt; Response &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+HTTP/1.1 207 Multi-Status
+Date: Sat, 11 Nov 2006 09:32:12 GMT
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<D:multistatus xmlns:D="DAV:">
+  <D:response>
+    <D:href>/calendars/users/cyrus/shared/</D:href>
+    <D:propstat>
+      <D:prop>
+        <D:resourcetype/>
+      </D:prop>
+      <D:status>HTTP/1.1 200 OK</D:status>
+    </D:propstat>
+  </D:response>
+</D:multistatus>]]></artwork>
+                        </figure>
+                    </section>
+                </section>
+                <section title="Manipulating Sharees of a Shared Calendar" anchor="sharee">
+                    <t>
+                        The sharer of a shared calendar is able to manipulate the sharee list by issuing a POST request targeted at the shared calendar collection resource. The POST request MUST contain an XML document as its body with the root element being <xref target="CS:share">CS:share</xref>.
+                    </t>
+                    <t>
+                    	The <xref target="CS:share">CS:share</xref> element in the POST requests MUST contain one or more <xref target="CS:set">CS:set</xref> or <xref target="CS:remove">CS:remove</xref> elements. For each <xref target="CS:set">CS:set</xref> element, the server MUST add the specified sharee access to the shared calendar. For each <xref target="CS:remove">CS:remove</xref> element the server MUST remove the specified sharee access from the shared calendar. In each case the server MUST send a notification message to any sharees whose status is changed (added, modified or removed), indicating to them a change in status for the shared calendar. The server SHOULD NOT send notification messages to sharees whose status is unchanged.
+                    </t>
+                    <t>
+                    	Sharee's are identified via a DAV:href element whose value is either a principal-URL for a sharee hosted on the same server, a calendar user address or email address. In the case of the later two, the sharee might not be a user on the same server - though in that case how invitations are sent or access enabled is out of scope for this specification. A server MAY change the sharee's "address" to any suitable alternative that it might prefer when returning the list of sharees via the <xref target="CS:invite">CS:invite property</xref>.
+                    </t>
+                    <t>
+                    	The client MAY include a <xref target="CS:common-name">CS:common-name</xref> element in the <xref target="CS:set">CS:set</xref> element. When provided, the value represents the common name for the sharee, and is returned in the list of sharees via the <xref target="CS:invite">CS:invite property</xref>. The server MAY change this to a suitable alternative when it is able to match the sharee to a known user. If absent from the client request, the server SHOULD add a CS:common-name when it is able to match the sharee with a known user, and a common name for that user can be determined.
+                    </t>
+                    <t>
+                    	When the sharee list on a shared calendar is changed, the server MUST send notifications to each sharee to update them on their current sharing status. This is accomplished by sending a <xref target="CS:invite-notification">CS:invite-notification</xref> notification to each sharee.
+                    </t>
+                    <section title="Example: Successful Sharee Add Request">
+            
+                        <t>
+                          This example shows how to add a single sharee (with calendar user address "mailto:eric at example.com") to a shared calendar with CS:read-write access.
+                        </t>
+    
+                        <figure>
+                          <preamble>&gt;&gt; Request &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+POST /calendars/users/cyrus/shared/ HTTP/1.1
+Host: calendar.example.com
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:"
+              xmlns:CS="http://calendarserver.org/ns/">
+  <CS:set>
+    <D:href>mailto:eric at example.com</D:href>
+    <CS:common-name>Eric York</CS:common-name>
+    <CS:summary>Shared workspace</CS:summary>
+    <CS:read-write />
+  </CS:set>
+</CS:share>]]></artwork>
+                        </figure>
+                        <figure>
+                          <preamble>&gt;&gt; Response &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Date: Sat, 11 Nov 2006 09:32:12 GMT]]></artwork>
+                        </figure>
+                    </section>
+                    <section title="Example: Successful Multiple Sharee Change Request">
+            
+                        <t>
+                          This example shows how multiple sharee's can be manipulated in a single request. The sharee with calendar user address "mailto:eric at example.com" has their access downgraded to CS:read, whilst another sharee is removed from the access list entirely.
+                        </t>
+    
+                        <figure>
+                          <preamble>&gt;&gt; Request &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+POST /calendars/users/cyrus/shared/ HTTP/1.1
+Host: calendar.example.com
+Content-Type: application/xml; charset="utf-8"
+Content-Length: xxxx
+
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:"
+              xmlns:CS="http://calendarserver.org/ns/">
+  <CS:set>
+    <D:href>mailto:eric at example.com</D:href>
+    <CS:summary>Shared workspace</CS:summary>
+    <CS:read-write />
+  </CS:set>
+  <CS:remove>
+    <D:href>mailto:wilfredo at example.com</D:href>
+  </CS:remove>
+</CS:share>]]></artwork>
+                        </figure>
+                        <figure>
+                          <preamble>&gt;&gt; Response &lt;&lt;</preamble>
+                          <artwork><![CDATA[
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Date: Sat, 11 Nov 2006 09:32:12 GMT]]></artwork>
+                        </figure>
+                    </section>
+                </section>
+            </section>
+            <section title="Sharee Actions on Shared Calendars">
+                <section title="Replying to a Sharing Invite">
+                	<t>
+                		When a sharee is invited to a shared calendar they can accept or decline the invite by issuing a POST request to the sharee's calendar home collection resource. The POST request MUST contain an XML document as its body with the root element being <xref target="CS:invite-reply">CS:invite-reply</xref>.
+                	</t>
+                	<t>
+                		The <xref target="CS:invite-reply">CS:invite-reply</xref> element in the POST request specifies the sharee who is replying in the DAV:href element, the accept or decline action via the CS:invite-accepted or CS:invite-declined elements, the URL of the shared calendar in the CS:hosturl element, the unique identifier of the invite to which it is a reply in the CS:in-reply-to element, and an optional CS:summary element.
+                	</t>
+                	<t>
+                		The response to a POST request that accepts a shared calendar invite MUST be an XML document containing <xref target="CS:shared-as">CS:shared-as</xref> as its root element. That root element contains a single DAV:href element whose content is the URI of the shared calendar in the sharee's calendar home created by the invite acceptance.
+                	</t>
+                	<t>
+                        When the sharee replies to an invite, the server SHOULD send a notification to the sharer to update them on the change in the sharee state.  This is accomplished by sending a <xref target="CS:invite-reply">CS:invite-reply</xref> notification to the sharer.
+                	</t>
+                </section>
+                <section title="Removing a Shared Calendar">
+                	<t>
+                		To remove a shared calendar from a sharee's calendar home collection a DELETE request is targeted at the shared calendar URI. When such a request is received the server MUST remove the shared calendar from the sharee's calendar home and automatically update the sharee's status in the sharer's calendar's CS:invite property.
+                	</t>
+                </section>
+            </section>
+            <section title="General Considerations">
+                <section title="Access Levels">
+                	<t>
+                		Two levels of access ca be granted by a sharer to any sharee. These are governed by the CS:access element used in the CS:invite/CS:user element that specifies a shared user invite. CS:access contains a single empty element that defines the type of access granted:
+                		<list style="hanging">
+                		<t hangText="CS:read">
+                		    When present this indicates that sharees can read calendar data but cannot change it.
+                		</t>
+                		<t hangText="CS:read-write">
+                		    When present this indicates that sharees can read and write calendar data.
+                		</t>
+                		</list>
+                	</t>
+                </section>
+                <section title="Allowing or Disallowing Sharing" anchor="allowed">
+                	<t>
+                		Servers MAY support calendar sharing on a per-calendar basis - e.g., they could treat some calendars as always private (cannot be shared) or always public (always shared). As a result clients need a way to determine which calendar could be shared so they can enable or disable sharing options on a per-calendar basis.
+                	</t>
+                	<t>
+                		This specification adds a <xref target="CS:allowed-sharing-modes">CS:allowed-sharing-modes</xref> WebDAV property which servers can return on calendar collection resources. This property contains XML elements that describe which sharing or publishing capabilities can be supported by the corresponding calendar collection:
+                		<list>
+							<t><xref target="CS:can-be-shared">CS:can-be-shared</xref>: when present indicates that the calendar collection can be shared. When not present, the calendar collection cannot be shared.</t>
+							<t><xref target="CS:can-be-published">CS:can-be-published</xref>: when present indicates that the calendar collection can be published. When not present, the calendar collection cannot be published.</t>
+						</list>                		
+                	</t>
+                	<t>
+                		When not present on a calendar collection, sharing or publishing of that calendar is not allowed. Clients SHOULD NOT attempt to use requests to enable sharing or publishing targeted at those calendar collections.
+                	</t>
+                </section>
+                <section title="Per-user WebDAV Properties">
+                	<t>
+                		Servers MUST support "per-user" WebDAV properties on shared calendar collections and MAY support them on calendar object resources within shared calendar collections. A "per-user" WebDAV property is one whose value can be set and retrieved independently by each user with appropriate access rights. e.g., user "A" changes the DAV:displayname property on a shared calendar in their calendar home to "My calendar", and user "B" changes the same property to "Shared" on the same shared calendar in their calendar home. When each user retrieves the property value they will see their own last stored value and not the value of the other user.
+                	</t>
+                	<t>
+                		For shared calendars, the server MUST allow all users to write "per-user" WebDAV properties on the shared calendar collection and MAY allow property writes on calendar object resources within the shared calendar collection. This is required even in the case where the sharee has been granted read access only (i.e., the ability to change calendar data is disallowed). This requirement ensures that sharees can always change "personal" properties such as calendar colors and display names.
+                	</t>
+                	<t>
+                		Servers MUST treat the following properties as "per-user":
+                		<list>
+                			<t>DAV:displayname</t>
+                			<t>CALDAV:calendar-description</t>
+                			<t>CALDAV:schedule-calendar-transp</t>
+                			<t>ICAL:calendar-color</t>
+                		</list>
+                	</t>
+                	<t>
+                		Servers MAY treat any dead property as per-user.
+                	</t>
+                	<t>
+                		Servers MUST NOT treat live properties as per-user.
+                	</t>
+                </section>
+                <section title="Per-user Calendar Data" anchor="per-user-data">
+                	<t>
+                		Servers MUST support "per-user" calendar data in calendar object resources stored in shared calendars. This allows each sharee and the sharer to store their own alarms and free busy transparency status without "interfering" with other users who also have access to the same calendar object resources.
+                	</t>
+                	<t>
+                		For calendaring object resources in shared calendar collections, the server MUST treat the following iCalendar data objects as per-user:
+                		<list>
+                			<t>TRANSP property</t>
+                			<t>VALARM component</t>
+                		</list>
+                	</t>
+                	<t>
+                		Servers MAY treat any non-standard X- iCalendar properties as per-user.
+                	</t>
+                	<t>
+                		When handling per-user data in recurring components, servers SHOULD eliminate overridden instances when returning iCalendar data to clients in the case where there are no differences between the overridden component and the instance that could be derived from the "master" recurrence component. For example, consider a daily recurring event, Monday through Friday, initially defined without any overridden instances, that is in a shared calendar. If user "A" overrides the Tuesday instance and adds their own "VALARM" component only, then when user "A" later retrieves the data again they would see that overridden instance, but when user "B" does so, they would not. This ensures that each user sees the most "compact" representation of the calendar data.
+                	</t>
+                </section>
+                <section title="Scheduling">
+                	<t>
+                		<xref target="I-D.desruisseaux-caldav-sched">CalDAV Scheduling</xref> defines how a CalDAV server carries out scheduling operations when calendar object resources are created, modified or deleted and include "ORGANIZER" and "ATTENDEE" iCalendar properties.
+                	</t>
+                	<t>
+                		When calendar object resources are created, modified or deleted in shared calendars by sharees, the following restrictions apply:
+                		<list style="numbers">
+                			<t>The "ORGANIZER" iCalendar property value in the iCalendar data MUST match a calendar user address of the sharer (owner) of the shared calendar. The DAV:owner WebDAV property MUST be present on a shared calendar and MUST provide a reference to a principal-URL of the sharer (owner) of the shared calendar. Clients can use this value to determine what the allowed "ORGANIZER" iCalendar property values are. The server MUST reject any attempt by a sharee to create an iCalendar component with an "ORGANIZER" property value other than the sharer (owner) of the shared calendar.</t>
+                			<t>The server MUST reject any attempt by a sharee to MOVE a calendar object resource in a shared calendar to some other collection.</t>
+                			<t>When a sharee is listed as an Attendee in a calendar object resource in a shared calendar, and write access is granted, the sharee is allowed to change not only iCalendar data related to the Organizer, but also data related to the Attendee. i.e., a sharee can change their own participation status on the "ATTENDEE" iCalendar property referring to them. Additionally, if the sharee is not listed as an Attendee, and write access is granted, the sharee can add themselves as an Attendee.</t>
+                			<t>The default calendar collection defined in Section 6.3 of <xref target="I-D.desruisseaux-caldav-sched"/> MUST NOT be a calendar shared to the corresponding calendar user.</t>
+                		</list>
+                	</t>
+                	<t>
+                		Following are additional considerations for scheduling with shared calendars:
+                		<list style="numbers">
+                			<t>A scheduled iCalendar component could appear in more than one calendar collection within a sharee's calendar home if the sharee is an Attendee and the Organizer or other Attendees have shared a calendar with the sharee that includes their copies of the iCalendar component. It is important to note that the scheduled component in the shared calendar could have different access rights than the one in the sharee's owned calendar.</t>
+                			<t>A scheduled iCalendar component appearing in a sharee's shared calendar could include the sharee as an Attendee. For recurring events, it is possible for the sharee to only be listed as an Attendee in some instances, as opposed to all. Clients will need to be aware of this when allowing sharee's to set their own participation status.</t>
+                		</list>
+                	</t>
+                	<t>
+                		In addition, when a shared calendar is first accepted by a sharee, the server SHOULD set the CALDAV:schedule-calendar-transp property to the value CALDAV:transparent to ensure newly accepted shared calendars do not contribute to the sharee's freebusy time until the sharee explicitly requests it.
+                	</t>
+                </section>
+            </section>
+        </section>
+
+        <section title='XML Element Definitions'>
+            <section title="CS:shared-owner" anchor="CS:shared-owner">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">shared-owner</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Used to indicate that a calendar is being shared by the owner.</t>
+                    <t hangText="Description:">This property appears in the DAV:resourcetype property on the calendar collection resource shared by a sharer. See <xref target="properties"/>.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT shared-owner EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:shared" anchor="CS:shared">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">shared</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Used to indicate that a calendar is being shared to a sharee.</t>
+                    <t hangText="Description:">This property appears in the DAV:resourcetype property on a calendar collection resource that is shared to a sharee and appears in the sharee's calendar home collection. See <xref target="properties"/>.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT shared EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:can-be-shared" anchor="CS:can-be-shared">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">can-be-shared</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Used to indicate that a calendar can be shared.</t>
+                    <t hangText="Description:">This element indicates that a calendar can be shared with other users. See <xref target="CS:allowed-sharing-modes"/></t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT can-be-shared EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:can-be-published" anchor="CS:can-be-published">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">can-be-published</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Used to indicate that a calendar can be published.</t>
+                    <t hangText="Description:">This element indicates that a calendar can be published to anyone. See <xref target="CS:allowed-sharing-modes"/></t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT can-be-published EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:user" anchor="CS:user">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">user</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Used to show status of sharing invites sent to sharees.</t>
+                    <t hangText="Description:">This element provides the "status" of a sharing invite sent to a particular user. See <xref target="CS:invite"/>.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT user (DAV:href, common-name?, (invite-noresponse |
+                invite-accepted | invite-declined | invite-invalid),
+                access, summary?)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-noresponse">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-noresponse</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sharing invite status.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:user">CS:user</xref> element, this element is used to indicate that the sharee has never replied to the corresponding sharing invite. When used in a <xref target="CS:invite-notification">CS:invite-notification</xref> element, this element is used to indicate to the sharee that a sharing reply is needed.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-noresponse EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-deleted">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-deleted</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sharing invite status.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:invite-notification">CS:invite-notification</xref> element, this element is used to indicate to the sharee that a shared calendar has been unshared by the sharer.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-deleted EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-accepted">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-accepted</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sharing invite status.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:user">CS:user</xref> element, this element is used to indicate that the sharee has accepted the corresponding sharing invite. When used in a <xref target="CS:invite-notification">CS:invite-notification</xref> element, this element is used to indicate to the sharee that the sharing invite is an update for one they previously accepted.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-accepted EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-declined">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-declined</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sharing invite status.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:user">CS:user</xref> element, this element is used to indicate that the sharee has declined the corresponding sharing invite. When used in a <xref target="CS:invite-notification">CS:invite-notification</xref> element, this element is used to indicate to the sharee that the sharing invite is an update for one they previously declined.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-declined EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-invalid">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-invalid</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sharing invite status.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:user">CS:user</xref> element, this element is used to indicate that the corresponding sharee is not a valid calendar user known to the server.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-invalid EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:access">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">access</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Shared calendar access level.</t>
+                    <t hangText="Description:">When used in a <xref target="CS:user">CS:user</xref> element, this element is used to indicate the sharing access level granted to the corresponding sharee.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-invalid (read | read-write)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:read">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">read</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Shared calendar access level privilege.</t>
+                    <t hangText="Description:">Indicates that the access level granted only allows sharees to read data in the shared calendar (though they can write <xref target="per-user-data">per-user data</xref>).</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT read EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:read-write">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">read-write</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Shared calendar access level privilege.</t>
+                    <t hangText="Description:">Indicates that the access level granted allows sharees to read and write all data in the shared calendar, with the exception of components that would trigger scheduling.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT read-write EMPTY>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:summary">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">summary</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Summary or title of shared calendar.</t>
+                    <t hangText="Description:">A brief description of a shared calendar. This can be used by sharers to communicate the nature of a shared calendar to sharees, as well as used by sharees to indicate back to the sharer how each sharee is refering to the shared calendar.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT summary (#PCDATA)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-notification" anchor="CS:invite-notification">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-notification</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">A notification used as a shared calendar invite.</t>
+                    <t hangText="Description:">Defines a notification message sent automatically by the server when a sharer adds, changes or removes a sharee from a shared calendar. The DAV:href element specifies the calendar user address of the sharee to whom the message was sent.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-notification (uid, DAV:href,
+                               (invite-noresponse | invite-deleted |
+                                invite-accepted | invite-declined),
+                               access, hosturl, organizer, summary?>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:uid">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">uid</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Unique identifier.</t>
+                    <t hangText="Description:">A unique identifier for an invitation to a shared calendar.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT uid (#PCDATA)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:hosturl">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">hosturl</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Identifies the source URL of a shared calendar.</t>
+                    <t hangText="Description:">Contains a single DAV:href element that refers to the source of a shared calendar - i.e., the URL of the calendar shared by the sharer.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT hosturl (DAV:href)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:organizer">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">organizer</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Identifies the sharer of a shared calendar.</t>
+                    <t hangText="Description:">Contains a single DAV:href element that identifies the calendar user address of the sharer of a shared calendar, and an optional CS:common-name element that matches that user.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT organizer (DAV:href, CS:common-name?)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:common-name" anchor="CS:common-name">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">common-name</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">The common name of a sharer or sharee.</t>
+                    <t hangText="Description:">The common name is optionally provided by a client when adding a sharee and optionally included (or modified) by the server when returning results for sharers or sharees and in notifications.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT common-name (#PCDATA)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:invite-reply" anchor="CS:invite-reply">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">invite-reply</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">A notification used as a reply to a shared calendar invite.</t>
+                    <t hangText="Description:">Defines a notification message sent automatically by the server when a sharee replies to a shared calendar invite. The DAV:href element specifies the calendar user address of the sharee to whom the original invite message was sent.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT invite-reply (DAV:href,
+                        (invite-accepted | invite-declined),
+                        hosturl, in-reply-to, summary?>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:in-reply-to">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">in-reply-to</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Unique identifier.</t>
+                    <t hangText="Description:">Specifies the unique identifier of the inviate message that this notification message is a reply to.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT in-reply-to (#PCDATA)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:notification" anchor="CS:notification">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">notification</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Notification message root element.</t>
+                    <t hangText="Description:">The root element used in notification resources.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT notification (CS:dtstamp,
+                        (invite-notification | invite-reply)>
+<!-- Any notification type element can appear after CS:dtstamp,
+     this specification defines only the two listed above -->]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:dtstamp" anchor="CS:dtstamp">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">dtstamp</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Date-time stamp.</t>
+                    <t hangText="Description:">Contains the date-time stamp corresponding to the creation of a notification message.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT dtstamp (#PCDATA)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:share" anchor="CS:share">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">share</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Describes changes to sharees.</t>
+                    <t hangText="Description:">The root element used in POST requests on calendars by sharers to manipulate the sharee list of a shared calendar.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT share (set | remove)*>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:set" anchor="CS:set">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">set</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Sets access for a sharee.</t>
+                    <t hangText="Description:">Used to add or modify sharee access to a shared calendar. The specified access to the shared calendar is given to the sharee.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT set (DAV:href, common-name?, summary?,
+               (read | read-write)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:remove" anchor="CS:remove">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">remove</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Removes access for a sharee.</t>
+                    <t hangText="Description:">Used to remove sharee access to a shared calendar. All access to the shared calendar is removed for the sharee.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT remove (DAV:href)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+            <section title="CS:shared-as" anchor="CS:shared-as">
+                <t>
+                  <list style="hanging">
+                    <t hangText="Name:">shared-as</t>
+                    <t hangText="Namespace:">http://calendarserver.org/ns/</t>
+                    <t hangText="Purpose:">Identifies a shared calendar.</t>
+                    <t hangText="Description:">Returned by the server for a POST request by a sharee accepting a shared calendar invite. The DAV:href element specifies the URI of the calendar created by the acceptance.</t>
+                    <t hangText="Definition:">
+                      <figure>
+                        <artwork><![CDATA[
+<!ELEMENT shared-as (DAV:href)>]]></artwork>
+                      </figure>
+                    </t>
+                  </list>
+                </t>
+            </section>
+        </section>
+
+        <section title='Security Considerations'>
+            <t>
+                Per-user WebDAV properties and iCalendar data MUST only be accessible by the user that created them.
+            </t>
+            <t>
+                Alarms set by the sharer SHOULD NOT be propagated to sharees by default. Clients SHOULD NOT automatically enable triggering of alarms on shared calendars that have just been accepted without confirmation by the user.
+            </t>
+            <t>
+            	TBD
+            </t>
+        </section>
+        <section title='IANA Considerations'>
+            <t>
+                This document does not require any actions on the part of IANA.
+            </t>
+        </section>
+        <section title='Acknowledgments'>
+            <t>
+                This specification is the result of discussions between the Apple calendar server and client teams.
+            </t>
+        </section>
+    </middle>
+    <back>
+        <references title='Normative References'>
+            &rfc2119;
+            &rfc3744;
+            &rfc4791;
+            &rfc4918;
+            &rfc5689;
+            &I-D.desruisseaux-caldav-sched; 
+        </references>
+<!--
+<references title='Informative References'>
+</references>
+-->
+        <section title='Change History'>
+            <t>Changes in -02:
+                <list style='numbers'>
+                    <t>Removed read-write-shared access mode - now a server that does not support shared scheduling should advertise that via a DAV header</t>
+                </list>
+            </t>
+        </section>
+        <section title='Change History'>
+            <t>Changes in -01:
+                <list style='numbers'>
+                    <t>Added CS:shared-url property</t>
+                    <t>Clarified that notifications are only required to be sent when sharee status is changed</t>
+                </list>
+            </t>
+        </section>
+    </back>
+</rfc>

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-srv-caldav.txt
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-srv-caldav.txt	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-srv-caldav.txt	2010-10-18 04:33:34 UTC (rev 6433)
@@ -3,80 +3,84 @@
 
 Network Working Group                                           C. Daboo
 Internet-Draft                                                Apple Inc.
-Intended status: Standards Track                         October 4, 2009
-Expires: April 7, 2010
+Updates: 4791,CardDAV-RFC-to-be                       September 16, 2010
+(if approved)
+Intended status: Standards Track
+Expires: March 20, 2011
 
 
-      Use of SRV records for locating CalDAV and CardDAV services
-                       draft-daboo-srv-caldav-01
+                  Locating CalDAV and CardDAV services
+                       draft-daboo-srv-caldav-10
 
+Abstract
+
+   This specification describes how DNS SRV records, DNS TXT records and
+   well-known URIs can be used together or separately to locate
+   Calendaring Extensions to WebDAV (CalDAV) or vCard Extensions to
+   WebDAV (CardDAV) services.
+
 Status of This Memo
 
-   This Internet-Draft is submitted to IETF in full conformance with the
+   This Internet-Draft is submitted in full conformance with the
    provisions of BCP 78 and BCP 79.
 
    Internet-Drafts are working documents of the Internet Engineering
-   Task Force (IETF), its areas, and its working groups.  Note that
-   other groups may also distribute working documents as Internet-
-   Drafts.
+   Task Force (IETF).  Note that other groups may also distribute
+   working documents as Internet-Drafts.  The list of current Internet-
+   Drafts is at http://datatracker.ietf.org/drafts/current/.
 
    Internet-Drafts are draft documents valid for a maximum of six months
    and may be updated, replaced, or obsoleted by other documents at any
    time.  It is inappropriate to use Internet-Drafts as reference
    material or to cite them other than as "work in progress."
 
-   The list of current Internet-Drafts can be accessed at
-   http://www.ietf.org/ietf/1id-abstracts.txt.
+   This Internet-Draft will expire on March 20, 2011.
 
-   The list of Internet-Draft Shadow Directories can be accessed at
-   http://www.ietf.org/shadow.html.
-
-   This Internet-Draft will expire on April 7, 2010.
-
 Copyright Notice
 
-   Copyright (c) 2009 IETF Trust and the persons identified as the
+   Copyright (c) 2010 IETF Trust and the persons identified as the
    document authors.  All rights reserved.
 
    This document is subject to BCP 78 and the IETF Trust's Legal
-   Provisions Relating to IETF Documents in effect on the date of
-   publication of this document (http://trustee.ietf.org/license-info).
-   Please review these documents carefully, as they describe your rights
-   and restrictions with respect to this document.
+   Provisions Relating to IETF Documents
+   (http://trustee.ietf.org/license-info) in effect on the date of
+   publication of this document.  Please review these documents
+   carefully, as they describe your rights and restrictions with respect
+   to this document.  Code Components extracted from this document must
+   include Simplified BSD License text as described in Section 4.e of
+   the Trust Legal Provisions and are provided without warranty as
 
-Abstract
 
-   This specification describes how SRV records and well-known URIs can
-   be used to locate Calendaring Extensions to WebDAV (CalDAV) or vCard
-   Extensions to WebDAV (CardDAV) services.
 
+Daboo                    Expires March 20, 2011                 [Page 1]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
-Daboo                     Expires April 7, 2010                 [Page 1]
-
-Internet-Draft               SRV for CalDAV                 October 2009
+   described in the Simplified BSD License.
 
-
 Table of Contents
 
-   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . . . 3
-   2.  Conventions Used in This Document . . . . . . . . . . . . . . . 3
-   3.  CalDAV SRV Service Types  . . . . . . . . . . . . . . . . . . . 4
-   4.  CalDAV and CardDAV Service Well-Known URI . . . . . . . . . . . 4
-     4.1.  Example: well-known URI as context path . . . . . . . . . . 4
-     4.2.  Example: well-known URI redirects to actual context
-           path  . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
-   5.  Client "Bootstrapping" Guidelines . . . . . . . . . . . . . . . 5
-   6.  Security Considerations . . . . . . . . . . . . . . . . . . . . 6
-   7.  IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 6
-     7.1.  caldav Well-Known URI Registration  . . . . . . . . . . . . 7
-     7.2.  carddav Well-Known URI Registration . . . . . . . . . . . . 7
-   8.  Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 7
-   9.  References  . . . . . . . . . . . . . . . . . . . . . . . . . . 7
-     9.1.  Normative References  . . . . . . . . . . . . . . . . . . . 7
-     9.2.  Informative References  . . . . . . . . . . . . . . . . . . 8
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  4
+   3.  CalDAV SRV Service Labels  . . . . . . . . . . . . . . . . . .  4
+   4.  CalDAV and CardDAV Service TXT Records . . . . . . . . . . . .  4
+   5.  CalDAV and CardDAV Service Well-Known URI  . . . . . . . . . .  5
+     5.1.  Example: well-known URI redirects to actual context
+           path . . . . . . . . . . . . . . . . . . . . . . . . . . .  5
+   6.  Client "Bootstrapping" Procedures  . . . . . . . . . . . . . .  5
+   7.  Guidance for Service Providers . . . . . . . . . . . . . . . .  8
+   8.  Security Considerations  . . . . . . . . . . . . . . . . . . .  9
+   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . .  9
+     9.1.  caldav Well-Known URI Registration . . . . . . . . . . . . 10
+     9.2.  carddav Well-Known URI Registration  . . . . . . . . . . . 10
+     9.3.  SRV Service Label Registration . . . . . . . . . . . . . . 10
+   10. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 10
+   11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 10
+     11.1. Normative References . . . . . . . . . . . . . . . . . . . 10
+     11.2. Informative References . . . . . . . . . . . . . . . . . . 12
    Appendix A.  Change History (to be removed prior to
-                publication as an RFC) . . . . . . . . . . . . . . . . 9
+                publication as an RFC)  . . . . . . . . . . . . . . . 13
 
 
 
@@ -104,33 +108,32 @@
 
 
 
-
-
-
-
-Daboo                     Expires April 7, 2010                 [Page 2]
+Daboo                    Expires March 20, 2011                 [Page 2]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
 1.  Introduction
 
-   [RFC2782] defines a DNS-based service discovery protocol that has
-   been widely adopted as a means of locating particular services within
-   a local area network and beyond, using SRV RR records.
-
-   [RFC4791] defines the CalDAV Calendar Access protocol, based on HTTP
+   [RFC4791] defines the CalDAV calendar access protocol, based on HTTP
    [RFC2616], for accessing calendar data stored on a server.  CalDAV
    clients need to be able to discover appropriate CalDAV servers within
    their local area network and at other domains, e.g., to minimize the
-   need for end users to know specific details such as hostname and port
-   for their servers.
+   need for end users to know specific details such as the fully
+   qualified domain name (FQDN) and port number for their servers.
 
-   [I-D.ietf-vcarddav-carddav] defines the CardDAV vCard Access protocol
-   based on HTTP [RFC2616], for accessing contact data stored on a
-   server.  As with CalDAV, clients also need to be able to discover
-   CardDAV servers.
+   [I-D.ietf-vcarddav-carddav] defines the CardDAV address book access
+   protocol based on HTTP [RFC2616], for accessing contact data stored
+   on a server.  As with CalDAV, clients also need to be able to
+   discover CardDAV servers.
 
+   [RFC2782] defines a DNS-based service discovery protocol that has
+   been widely adopted as a means of locating particular services within
+   a local area network and beyond, using DNS SRV Resource Records
+   (RRs).  This has been enhanced to provide additional service meta-
+   data by use of DNS TXT Resource Records as per
+   [I-D.cheshire-dnsext-dns-sd].
+
    This specification defines new SRV service types for the CalDAV
    protocol, and gives an example of how clients can use this together
    with other protocol features to enable simple client configuration.
@@ -138,51 +141,52 @@
    [I-D.ietf-vcarddav-carddav].
 
    Another issue with CalDAV or CardDAV service discovery is that the
-   service may not be located at the "root" URI of the HTTP server
-   hosting it.  For example, if CalDAV is implemented as a "servlet" in
-   a web server "container", the servlet "context path" might be
+   service might not be located at the "root" URI of the HTTP server
+   hosting it.  Thus a client needs to be able to determine the complete
+   path component of the Request-URI to use in HTTP requests: the
+   "context path".  For example, if CalDAV is implemented as a "servlet"
+   in a web server "container", the servlet "context path" might be
    "/caldav/".  So the URI for the CalDAV service would be, e.g.,
    "http://caldav.example.com/caldav/" rather than
-   "http://caldav.example.com/".  SRV records by themselves only provide
-   a hostname and port for the service, not a path.  Since the client
+   "http://caldav.example.com/".  SRV RRs by themselves only provide a
+   FQDN and port number for the service, not a path.  Since the client
    "bootstrapping" process requires initial access to the "context path"
    of the service, there needs to be a simple way for clients to also
    discover what that path is.
 
    This specification makes use of the "well known URI" feature
-   [I-D.nottingham-site-meta] of HTTP servers to provide a well known
-   URI for CalDAV or CardDAV services that clients can make use of.  The
-   well known URI will point to a resource on the server that might be
-   the actual "context path" of the CalDAV or CardDAV service, or it
-   might simply be a "stub" resource that provides a redirect to the
-   actual "context path".
+   [RFC5785] of HTTP servers to provide a well known URI for CalDAV or
+   CardDAV services that clients can make use of.  The well known URI
+   will point to a resource on the server that is simply a "stub"
+   resource that provides a redirect to the actual "context path"
+   resource representing the service endpoint.
 
-2.  Conventions Used in This Document
 
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
 
 
-
-Daboo                     Expires April 7, 2010                 [Page 3]
+Daboo                    Expires March 20, 2011                 [Page 3]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
+2.  Conventions Used in This Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
    document are to be interpreted as described in [RFC2119].
 
-3.  CalDAV SRV Service Types
+3.  CalDAV SRV Service Labels
 
-   This specification adds two service types for use with SRV records:
+   This specification adds two SRV service labels for use with CalDAV:
 
-   caldav:  Identifies a CalDAV server that uses HTTP without transport
+   _caldav:  Identifies a CalDAV server that uses HTTP without transport
       layer security ([RFC2818]).
 
-   caldavs:  Identifies a CalDAV server that uses HTTP with transport
+   _caldavs:  Identifies a CalDAV server that uses HTTP with transport
       layer security ([RFC2818]).
 
-   Clients SHOULD honor "TTL", "Priority" and "Weight" values in the SRV
-   records, as described by [RFC2782].
+   Clients MUST honor "Priority" and "Weight" values in the SRV RRs, as
+   described by [RFC2782].
 
    Example: service record for server without transport layer security
 
@@ -192,152 +196,316 @@
 
        _caldavs._tcp    SRV 0 1 443 calendar.example.com.
 
-4.  CalDAV and CardDAV Service Well-Known URI
+4.  CalDAV and CardDAV Service TXT Records
 
-   Two "well-known" URIs are registered by this specification for CalDAV
-   and CardDAV services, "caldav" and "carddav" respectively (see
-   Section 7).  These URIs point to a resource that the client can use
-   as the "context path" for the service they are trying to use.  The
-   actual service could be located at that specific path.  Alternatively
-   the server MAY redirect HTTP requests for that resource (using the
-   "301 Moved Permanently" status response) to the actual "context
-   path".  Clients MUST handle HTTP redirects on the well-known URI.
+   When SRV RRs are used to advertise CalDAV and CardDAV services, it is
+   also convenient to be able to specify a "context path" in the DNS to
+   be retrieved at the same time.  To enable that, this specification
+   uses a TXT RR that follows the syntax defined in Section 6 of
+   [I-D.cheshire-dnsext-dns-sd] and defines a "path" key for use in that
+   record.  The value of the key MUST be the actual "context path" to
+   the corresponding service on the server.
 
-4.1.  Example: well-known URI as context path
+   A site might provide TXT records in addition to SRV records for each
+   service.  When present, clients MUST use the "path" value as the
+   "context path" for the service in HTTP requests.  When not present,
+   clients use the ".well-known" URI approach described next.
 
-   A CalDAV server has a "context path" that is the same as the well-
-   known URI, so the client will use "/.well-known/caldav" as the path
-   for its "bootstrapping" process after it has first found the hostname
-   and port via an SRV lookup.
+   Example: text record for service with transport layer security
 
-4.2.  Example: well-known URI redirects to actual context path
+       _caldavs._tcp    TXT path=/caldav
 
+
+
+
+
+
+Daboo                    Expires March 20, 2011                 [Page 4]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+5.  CalDAV and CardDAV Service Well-Known URI
+
+   Two ".well-known" URIs are registered by this specification for
+   CalDAV and CardDAV services, "caldav" and "carddav" respectively (see
+   Section 9).  These URIs point to a resource that the client can use
+   as the initial "context path" for the service they are trying to
+   connect to.  The server MUST redirect HTTP requests for that resource
+   to the actual "context path" using one of the available mechanisms
+   provided by HTTP (e.g., using a 301, 303, 307 response).  Clients
+   MUST handle HTTP redirects on the ".well-known" URI.  Servers MUST
+   NOT locate the actual CalDAV or CardDAV service endpoint at the
+   ".well-known" URI as per Section 1.1 of [RFC5785].
+
+   Servers SHOULD set an appropriate Cache-Control header value (as per
+   Section 14.9 of [RFC2616]) in the redirect response to ensure caching
+   occurs or does not occur as needed, or as required by the type of
+   response generated.  For example, if it is anticipated that the
+   location of the redirect might change over time, then a "no-cache"
+   value would be used.
+
+   To facilitate "context path's" that might differ from user to user,
+   the server MAY require authentication when a client tries to access
+   the ".well-known" URI (i.e., the server would return a 401 status
+   response to the unauthenticated request from the client, then return
+   the redirect response only after a successful authentication by the
+   client).
+
+5.1.  Example: well-known URI redirects to actual context path
+
    A CalDAV server has a "context path" that is "/servlet/caldav".  The
    client will use "/.well-known/caldav" as the path for its
-   "bootstrapping" process after it has first found the hostname and
-   port via an SRV lookup.  When the client makes its initial HTTP
-   request against "/.well-known/caldav", the server would issue an HTTP
+   "bootstrapping" process after it has first found the FQDN and port
+   number via an SRV lookup or via manual entry of information by the
+   user which the client can parse suitable information from.  When the
+   client makes an HTTP request against "/.well-known/caldav", the
+   server would issue an HTTP redirect response with a Location response
+   header using the path "/servlet/caldav".  The client would then
+   "follow" this redirect to the new resource and continue making HTTP
+   requests there to complete its "bootstrapping" process.
 
+6.  Client "Bootstrapping" Procedures
 
+   This section describes a procedure that CalDAV or CardDAV clients
+   SHOULD use to do their initial configuration based on minimal user
+   input.  The goal is to determine an http: or https: URI that
+   describes the full path to the user's principal-URL [RFC3744].
 
-Daboo                     Expires April 7, 2010                 [Page 4]
+
+
+
+
+Daboo                    Expires March 20, 2011                 [Page 5]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
-   301 redirect response with a Location response header using the path
-   "/servlet/caldav".  The client would then "follow" this redirect to
-   the new resource and continue making HTTP requests there to complete
-   its "bootstrapping" process.
+   1.  Processing user input:
 
-5.  Client "Bootstrapping" Guidelines
+       *  For a CalDAV server:
 
-   This section describes a procedure that CalDAV or CardDAV clients MAY
-   use to do their initial configuration based on minimal user input.
+          +  Minimal input from a user would consist of a calendar user
+             address and a password.  A calendar user address is defined
+             by iCalendar [RFC5545] to be a URI [RFC3986].  Provided a
+             user identifier and a domain name can be extracted from the
+             URI, this simple "bootstrap" configuration can be done.
 
-   For a CalDAV server, minimal input from a user would consist of a
-   calendar user address.  A calendar user address is defined by
-   iCalendar [RFC5545] to be a URI [RFC3986].  Provided a user
-   identifier and a domain name can be extracted from the URI, this
-   simple "bootstrap" configuration can be done.
+          +  If the calendar user address is a "mailto:" [RFC2368] URI,
+             the "mailbox" portion of the URI is examined and the
+             "local-part" and "domain" portions extracted.
 
-   If the calendar user address is a "mailto:" [RFC2368] URI, the
-   "mailbox" portion of the URI is examined and the "local-part" and
-   "domain" portions extracted.  The "local-part" is used for the user
-   identifier and the "domain" is used as the service domain.
+          +  If the calendar user address is an "http:" [RFC2616] or
+             "https:" [RFC2818] URI, the "userinfo" and "host" portion
+             of the URI [RFC3986] is extracted.
 
-   If the calendar user address is an "http:" [RFC2616] or "https:"
-   [RFC2818] URI, the "userinfo" and "host" portion of the URI is
-   extracted.  The "userinfo" is used for the user identifier and the
-   "host" is used as the service domain.
+       *  For a CardDAV server:
 
-   For a CardDAV server, minimal input from a user would consist of
-   their email address [RFC5322] for the domain where the CardDAV
-   service is hosted.  The "mailbox" portion of the email address is
-   examined and the "local-part" and "domain" portions extracted.  The
-   "local-part" is used for the user identifier and the "domain" is used
-   as the service domain.
+          +  Minimal input from a user would consist of their email
+             address [RFC5322] for the domain where the CardDAV service
+             is hosted, and a password.  The "mailbox" portion of the
+             email address is examined and the "local-part" and "domain"
+             portions extracted.
 
-   Once the user identifier and service domain have been extracted, the
-   following is done:
+   2.  Determination of service FQDN and port number:
 
-   1.  An SRV lookup for _caldavs._tcp (for CalDAV) or _carddavs._tcp
-       (for CardDAV) is done against the extracted service domain.
+       *  An SRV lookup for _caldavs._tcp (for CalDAV) or _carddavs._tcp
+          (for CardDAV) is done with the extracted "domain" as the
+          service domain.
 
-   2.  If no result is found for that, the client can try _caldav._tcp
-       (for CalDAV) or _carddav._tcp (for CardDAV) provided non-SSL
-       connections are appropriate.
+       *  If no result is found, the client can try _caldav._tcp (for
+          CalDAV) or _carddav._tcp (for CardDAV) provided non-SSL
+          connections are appropriate.
 
-   3.  If an SRV record is returned the client extracts the server host
-       name and port number.
+       *  If an SRV record is returned, the client extracts the target
+          FQDN and port number.  In the case of multiple SRV records
+          returned, the client MUST use the priority and weight fields
+          in the record to determine which one to pick (as per
+          [RFC2782]).
 
-   4.  The client does an authenticated "PROPFIND" [RFC4791] request
-       using the user identifier, host name and port number and a
+       *  If an SRV record is not found, the client will need to prompt
+          the user to enter the FQDN and port number information
+          directly, or use some other heuristic, for example using the
+          extracted "domain" as the FQDN and default HTTPS or HTTP port
+          numbers.  In this situation clients MUST first attempt an HTTP
+          connection with transport layer security.
 
 
 
-Daboo                     Expires April 7, 2010                 [Page 5]
+Daboo                    Expires March 20, 2011                 [Page 6]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
-       request URI of "/.well-known/caldav" (for CalDAV) or "/.well-
-       known/carddav" (for CardDAV).  The body of the request should
-       include the DAV:current-user-principal [RFC5397] property as one
-       of the properties to return.  Note that clients MUST properly
-       handle HTTP redirect responses for the request.
+   3.  Determination of initial "context path":
 
-   5.  If the server returns a 404 Not Found HTTP status response to the
-       request on the well-known URI, clients MAY try repeating the
-       request on the "root" URI "/".
+       *  When an SRV lookup is done and a valid SRV record returned,
+          the client MUST also query for a corresponding TXT record and
+          check for the presence of a "path" key in its response.  If
+          present, the value of the "path" key is used for the initial
+          "context path".
 
-   6.  If the DAV:current-user-principal property is returned on the
-       initial request, the client uses that value for the principal-URI
-       of the authenticated user.  With that, it can do a "PROPFIND" on
-       the principal-URI and discover additional properties for
-       configuration.
+       *  When an initial "context path" has not been determined from a
+          TXT record, the initial "context path" is taken to be "/.well-
+          known/caldav" (for CalDAV) or "/.well-known/carddav" (for
+          CardDAV).
 
-   7.  If the DAV:current-user-principal property is not returned, then
-       the client will need to request the principal-URI path from the
-       user in order to continue with configuration.
+       *  If the initial "context path" derived from a TXT record
+          generates HTTP errors when targeted by requests, the client
+          SHOULD repeat its bootstrap procedure using the appropriate
+          ".well-known" URI instead.
 
-6.  Security Considerations
+   4.  Determination of user identifier:
 
+       *  The client will need to make authenticated HTTP requests to
+          the service.  Typically a "user identifier" is required for
+          some form of user/password authentication.  When a user
+          identifier is required, clients MUST first use the "mailbox"
+          portion of the calendar user address provided by the user in
+          the case of a "mailto:" address, and if that results in an
+          authentication failure, SHOULD fall back to using the "local-
+          part" extracted from the "mailto:" address.  For an "http:" or
+          "https:" calendar user address, the "userinfo" portion is used
+          as the user identifier for authentication.  This is in line
+          with the guidance outlined in Section 7.  If these user
+          identifiers result in authentication failure, the client
+          SHOULD prompt the user for a valid identifier.
+
+   5.  Connecting to the service:
+
+       *  Subsequent to configuration, the client will make HTTP
+          requests to the service.  When using "_caldavs" or "_carddavs"
+          services, a transport layer security negotiation is done
+          immediately upon connection.  The client MUST do certificate
+          verification using the procedure outlined in Section 4 of
+          [I-D.saintandre-tls-server-id-check] in regard to verification
+          with an SRV RR as the starting point.
+
+       *  The client does a "PROPFIND" [RFC4918] request with the
+          request URI set to the initial "context path".  The body of
+          the request SHOULD include the DAV:current-user-principal
+          [RFC5397] property as one of the properties to return.  Note
+
+
+
+Daboo                    Expires March 20, 2011                 [Page 7]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+          that clients MUST properly handle HTTP redirect responses for
+          the request.  The server will use the HTTP authentication
+          procedure outlined in [RFC2617] or use some other appropriate
+          authentication schemes to authenticate the user.
+
+       *  If the server returns a 404 Not Found HTTP status response to
+          the request on the initial "context path", clients MAY try
+          repeating the request on the "root" URI "/" or prompt the user
+          for a suitable path.
+
+       *  If the DAV:current-user-principal property is returned on the
+          request, the client uses that value for the principal-URL of
+          the authenticated user.  With that, it can execute a
+          "PROPFIND" request on the principal-URL and discover
+          additional properties for configuration (e.g., calendar or
+          address book "home" collections).
+
+       *  If the DAV:current-user-principal property is not returned,
+          then the client will need to request the principal-URL path
+          from the user in order to continue with configuration.
+
+   Once a successful account discovery step has been done, clients
+   SHOULD cache the service details that were successfully used (user
+   identity, principal-URL with full scheme/host/port details), and re-
+   use those when connecting again at a later time.
+
+   If a subsequent connection attempt fails, or authentication fails
+   persistently, clients SHOULD re-try the SRV lookup and account
+   discovery to "refresh" the cached data.
+
+7.  Guidance for Service Providers
+
+   Service providers wanting to offer CalDAV or CardDAV services that
+   can be configured by clients using SRV records need to follow certain
+   procedures to ensure proper operation.
+
+   o  CalDAV or CardDAV servers SHOULD be configured to allow
+      authentication with calendar user addresses (just taking the
+      "mailbox" portion of any "mailto:" URI) or email addresses
+      respectively, or "user identifiers" extracted from them.  In the
+      former case, the addresses MUST NOT conflict with other forms of
+      permitted user login name.  In the latter case, the extracted
+      "user identifiers" need to be unique across the server and MUST
+      NOT conflict with any login name on the server.
+
+   o  Servers MUST force authentication for "PROPFIND" requests that
+      retrieve the DAV:current-user-principal property to ensure that
+      the value of the DAV:current-user-principal property returned
+
+
+
+Daboo                    Expires March 20, 2011                 [Page 8]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+      corresponds to the principal-URL of the user making the request.
+
+   o  If the service provider uses transport layer security, the service
+      provider MUST ensure a certificate is installed that can be
+      verified by clients using the procedure outlined in Section 4 of
+      [I-D.saintandre-tls-server-id-check] in regard to verification
+      with an SRV RR as the starting point.
+
+   o  Install the appropriate SRV records for the offered services.
+      Optionally include TXT records.
+
+8.  Security Considerations
+
    Clients that support transport layer security as defined by [RFC2818]
-   SHOULD try the "caldavs" or "carddavs" services first before trying
-   the "caldav" or "carddav" services respectively.  If a user has
+   SHOULD try the "_caldavs" or "_carddavs" services first before trying
+   the "_caldav" or "_carddav" services respectively.  If a user has
    explicitly requested a connection with transport layer security, the
-   client MUST NOT use any service information returned for the "caldav"
-   or "carddav" services.  Clients MUST follow the certificate
-   verification process specified in
+   client MUST NOT use any service information returned for the
+   "_caldav" or "_carddav" services.  Clients MUST follow the
+   certificate verification process specified in
    [I-D.saintandre-tls-server-id-check].
 
-   A malicious attacker with access to the DNS server data can
-   potentially cause clients to connect to any server chosen by the
-   attacker.  In the absence of a secure DNS option, clients SHOULD
-   check that the host name returned in the SRV record matches the
-   original service domain that was queried.  If the host is not in the
-   queried domain, clients SHOULD verify with the user that the SRV host
-   name is suitable for use before executing any CalDAV or CardDAV
-   requests against the host.
+   A malicious attacker with access to the DNS server data, or able to
+   get spoofed answers cached in a recursive resolver, can potentially
+   cause clients to connect to any server chosen by the attacker.  In
+   the absence of a secure DNS option, clients SHOULD check that the
+   target FQDN returned in the SRV record matches the original service
+   domain that was queried.  If the target FQDN is not in the queried
+   domain, clients SHOULD verify with the user that the SRV target FQDN
+   is suitable for use before executing any connections to the host.
+   Alternatively, if transport layer security is being used for the
+   service, clients MUST use the procedure outlined in Section 4 of
+   [I-D.saintandre-tls-server-id-check] to verify the service.
 
-7.  IANA Considerations
+   Implementations of TLS [RFC5246], used as the basis for transport
+   layer security ([RFC2818]), typically support multiple versions of
+   the protocol as well as the older Secure Sockets Layer (SSL)
+   protocol.  Because of known security vulnerabilities, clients and
+   servers MUST NOT request, offer, or use SSL 2.0.  See Appendix E.2 of
+   [RFC5246] for further details.
 
-   This document defines two "well-known" URIs using the registration
-   procedure and template from Section 5.1 of
-   [I-D.nottingham-site-meta].
+9.  IANA Considerations
 
+   This document defines two ".well-known" URIs using the registration
+   procedure and template from Section 5.1 of [RFC5785].
 
 
 
 
 
-Daboo                     Expires April 7, 2010                 [Page 6]
+
+Daboo                    Expires March 20, 2011                 [Page 9]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
-7.1.  caldav Well-Known URI Registration
+9.1.  caldav Well-Known URI Registration
 
    URI suffix:  caldav
 
@@ -347,7 +515,7 @@
 
    Related information:  See also [RFC4791].
 
-7.2.  carddav Well-Known URI Registration
+9.2.  carddav Well-Known URI Registration
 
    URI suffix:  carddav
 
@@ -357,45 +525,51 @@
 
    Related information:  See also [I-D.ietf-vcarddav-carddav].
 
-8.  Acknowledgments
+9.3.  SRV Service Label Registration
 
+   Service labels have been registered according to
+   <http://www.dns-sd.org/ServiceTypes.html> [1] and will be
+   incorporated into IANA once a new registry is available there.
+
+10.  Acknowledgments
+
    This specification was suggested by discussion that took place within
    the Calendaring and Scheduling Consortium's CalDAV Technical
-   Committee.  The authors thank the participants of that group for
-   their input.  The "bootstrapping" process is based on diagrams
-   developed by Wilfredo Sanchez.
+   Committee.  The author thanks the following for their contributions:
+   Stuart Cheshire, Bernard Desruisseaux, Eran Hammer-Lahav, Helge Hess,
+   Arnaud Quillaud, Wilfredo Sanchez, and Joe Touch.
 
-9.  References
+11.  References
 
-9.1.  Normative References
+11.1.  Normative References
 
+   [I-D.cheshire-dnsext-dns-sd]          Cheshire, S. and M. Krochmal,
+                                         "DNS-Based Service Discovery",
+                                         draft-cheshire-dnsext-dns-sd-06
+                                         (work in progress), March 2010.
+
    [I-D.ietf-vcarddav-carddav]           Daboo, C., "vCard Extensions to
                                          WebDAV (CardDAV)",
-                                         draft-ietf-vcarddav-carddav-09
+                                         draft-ietf-vcarddav-carddav-10
                                          (work in progress),
-                                         September 2009.
+                                         November 2009.
 
-   [I-D.nottingham-site-meta]            Nottingham, M. and E. Hammer-
-                                         Lahav, "Defining Well-Known
-                                         URIs",
-                                         draft-nottingham-site-meta-03
-                                         (work in progress),
-                                         September 2009.
 
-   [I-D.saintandre-tls-server-id-check]  Saint-Andre, P., Zeilenga, K.,
-                                         and J. Hodges, "Server Identity
-                                         Verification in Application
 
-
-
-Daboo                     Expires April 7, 2010                 [Page 7]
+Daboo                    Expires March 20, 2011                [Page 10]
 
-Internet-Draft               SRV for CalDAV                 October 2009
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
 
 
-                                         Protocols", draft-saintandre-
-                                         tls-server-id-check-02 (work in
-                                         progress), October 2009.
+   [I-D.saintandre-tls-server-id-check]  Saint-Andre, P. and J. Hodges,
+                                         "Representation and
+                                         Verification of Domain-Based
+                                         Application Service Identity in
+                                         Certificates Used with
+                                         Transport Layer Security", draf
+                                         t-saintandre-tls-server-id-
+                                         check-09 (work in progress),
+                                         August 2010.
 
    [RFC2119]                             Bradner, S., "Key words for use
                                          in RFCs to Indicate Requirement
@@ -413,6 +587,14 @@
                                          Transfer Protocol -- HTTP/1.1",
                                          RFC 2616, June 1999.
 
+   [RFC2617]                             Franks, J., Hallam-Baker, P.,
+                                         Hostetler, J., Lawrence, S.,
+                                         Leach, P., Luotonen, A., and L.
+                                         Stewart, "HTTP Authentication:
+                                         Basic and Digest Access
+                                         Authentication", RFC 2617,
+                                         June 1999.
+
    [RFC2782]                             Gulbrandsen, A., Vixie, P., and
                                          L. Esibov, "A DNS RR for
                                          specifying the location of
@@ -422,6 +604,21 @@
    [RFC2818]                             Rescorla, E., "HTTP Over TLS",
                                          RFC 2818, May 2000.
 
+   [RFC3744]                             Clemm, G., Reschke, J., Sedlar,
+                                         E., and J. Whitehead, "Web
+                                         Distributed Authoring and
+                                         Versioning (WebDAV)
+                                         Access Control Protocol",
+
+
+
+Daboo                    Expires March 20, 2011                [Page 11]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+                                         RFC 3744, May 2004.
+
    [RFC3986]                             Berners-Lee, T., Fielding, R.,
                                          and L. Masinter, "Uniform
                                          Resource Identifier (URI):
@@ -433,34 +630,171 @@
                                          Extensions to WebDAV (CalDAV)",
                                          RFC 4791, March 2007.
 
-9.2.  Informative References
+   [RFC4918]                             Dusseault, L., "HTTP Extensions
+                                         for Web Distributed Authoring
+                                         and Versioning (WebDAV)",
+                                         RFC 4918, June 2007.
 
+   [RFC5246]                             Dierks, T. and E. Rescorla,
+                                         "The Transport Layer Security
+                                         (TLS) Protocol Version 1.2",
+                                         RFC 5246, August 2008.
+
    [RFC5322]                             Resnick, P., Ed., "Internet
                                          Message Format", RFC 5322,
                                          October 2008.
 
    [RFC5397]                             Sanchez, W. and C. Daboo,
                                          "WebDAV Current Principal
+                                         Extension", RFC 5397,
+                                         December 2008.
 
+   [RFC5785]                             Nottingham, M. and E. Hammer-
+                                         Lahav, "Defining Well-Known
+                                         Uniform Resource Identifiers
+                                         (URIs)", RFC 5785, April 2010.
 
+11.2.  Informative References
 
-Daboo                     Expires April 7, 2010                 [Page 8]
-
-Internet-Draft               SRV for CalDAV                 October 2009
-
-
-                                         Extension", RFC 5397,
-                                         December 2008.
-
    [RFC5545]                             Desruisseaux, B., "Internet
                                          Calendaring and Scheduling Core
                                          Object Specification
                                          (iCalendar)", RFC 5545,
                                          September 2009.
 
+URIs
+
+   [1]  <http://www.dns-sd.org/ServiceTypes.html>
+
+
+
+Daboo                    Expires March 20, 2011                [Page 12]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
 Appendix A.  Change History (to be removed prior to publication as an
              RFC)
 
+   Changes in -09:
+
+   1.  IESG Review: minor editorial changes.
+
+   2.  GenART Review: minor editorial changes.
+
+   3.  GenART Review: "guideline" -> "procedure".
+
+   4.  GenART Review: "port" -> "port number".
+
+   5.  GenART Review: added definition of "context path".
+
+   6.  GenART Review: clarified OPTIONAL nature of suggested client
+       procedure.
+
+   7.  GenART Review: clarified that TXT lookup is an additional query.
+
+   8.  IESG Review: now allow any HTTP redirect response, not just 301.
+
+   9.  IESG Review: added text on cache interaction with redirect.
+
+   Changes in -10:
+
+   1.  AD Review: make client procedure a SHOULD.
+
+   Changes in -08:
+
+   1.  Clarify that email address is a valid input in Section 7 for
+       CardDAV.
+
+   2.  Clarified aspects of DAV:current-user-principal handling for
+       servers.
+
+   3.  Added additional text to indicate TXT being used in abstract and
+       introduction.
+
+   Changes in -07:
+
+   1.  Add password to required minimal user input
+
+   2.  Section 3 -> Section 4 of server-id check draft.
+
+   Changes in -06:
+
+
+
+
+
+Daboo                    Expires March 20, 2011                [Page 13]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+   1.  Last call comments: Revised title, abstract and text to indicate
+       that SRV and .well-known can be done separately.
+
+   2.  Revised IANA section to use dns-sd registry for now.
+
+   3.  Added optional TXT RR with path key for service context path in
+       the DNS
+
+   4.  Re-organized client bootstrap to take account of TXT and to call-
+       out the different "phases" involved via a numbered list.
+
+   Changes in -05:
+
+   1.  AD Review: Added "Updates" for 4791 and CardDAV.
+
+   2.  AD Review: Changed SHOULD to MUST for honoring priority and
+       weight.
+
+   3.  AD Review: Added additional reference to 3986 when talking about
+       userinfo/host portions of the URI.
+
+   4.  AD Review: Changed section reference for tls-server-id-check
+       draft.
+
+   5.  AD Review: Changed should to SHOULD when describing PROPFIND
+       request and made 5397 normative.
+
+   6.  AD Review: Made 3744 and 5322 normative references.
+
+   7.  AD Review: Added IANA SRV registration request.
+
+   Changes in -04:
+
+   1.  Added addition text to client guidelines indicating that clients
+       cache the discovery details and can re-do discovery if
+       connections later fail.
+
+   2.  Changed principal-URI to principal-URL.
+
+   Changes in -03:
+
+   1.  Updated to RFC 5785 reference.
+
+   2.  Added SSL v2 restriction from srv-email document added after IESG
+       review.
+
+   3.  Tweaked client/server guidelines to better match HTTP challenge/
+       response authentication mechanism.
+
+
+
+Daboo                    Expires March 20, 2011                [Page 14]
+
+Internet-Draft          SRV for CalDAV & CardDAV          September 2010
+
+
+   Changes in -02:
+
+   1.  Re-organized introduction.
+
+   2.  Brought terminology into line with srv-email document which has
+       been through last call.
+
+   3.  Brought security section into line with srv-email document which
+       has been through last call.
+
    Changes in -01:
 
    1.  Added discovery of CardDAV service.
@@ -500,5 +834,7 @@
 
 
 
-Daboo                     Expires April 7, 2010                 [Page 9]
+
+
+Daboo                    Expires March 20, 2011                [Page 15]
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-webdav-sync.txt
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-webdav-sync.txt	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/doc/RFC/draft-daboo-webdav-sync.txt	2010-10-18 04:33:34 UTC (rev 6433)
@@ -4,12 +4,12 @@
 Network Working Group                                           C. Daboo
 Internet-Draft                                               Apple, Inc.
 Intended status: Standards Track                             A. Quillaud
-Expires: May 22, 2010                                   Sun Microsystems
-                                                       November 18, 2009
+Expires: April 8, 2011                                            Oracle
+                                                         October 5, 2010
 
 
                  Collection Synchronization for WebDAV
-                       draft-daboo-webdav-sync-02
+                       draft-daboo-webdav-sync-04
 
 Abstract
 
@@ -27,48 +27,43 @@
 
 Status of This Memo
 
-   This Internet-Draft is submitted to IETF in full conformance with the
+   This Internet-Draft is submitted in full conformance with the
    provisions of BCP 78 and BCP 79.
 
    Internet-Drafts are working documents of the Internet Engineering
-   Task Force (IETF), its areas, and its working groups.  Note that
-   other groups may also distribute working documents as Internet-
-   Drafts.
+   Task Force (IETF).  Note that other groups may also distribute
+   working documents as Internet-Drafts.  The list of current Internet-
+   Drafts is at http://datatracker.ietf.org/drafts/current/.
 
    Internet-Drafts are draft documents valid for a maximum of six months
    and may be updated, replaced, or obsoleted by other documents at any
    time.  It is inappropriate to use Internet-Drafts as reference
    material or to cite them other than as "work in progress."
 
-   The list of current Internet-Drafts can be accessed at
-   http://www.ietf.org/ietf/1id-abstracts.txt.
+   This Internet-Draft will expire on April 8, 2011.
 
-   The list of Internet-Draft Shadow Directories can be accessed at
-   http://www.ietf.org/shadow.html.
+Copyright Notice
 
-   This Internet-Draft will expire on May 22, 2010.
+   Copyright (c) 2010 IETF Trust and the persons identified as the
+   document authors.  All rights reserved.
 
-Copyright Notice
+   This document is subject to BCP 78 and the IETF Trust's Legal
+   Provisions Relating to IETF Documents
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 1]
+Daboo & Quillaud          Expires April 8, 2011                 [Page 1]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
-   Copyright (c) 2009 IETF Trust and the persons identified as the
-   document authors.  All rights reserved.
-
-   This document is subject to BCP 78 and the IETF Trust's Legal
-   Provisions Relating to IETF Documents
    (http://trustee.ietf.org/license-info) in effect on the date of
    publication of this document.  Please review these documents
    carefully, as they describe your rights and restrictions with respect
    to this document.  Code Components extracted from this document must
    include Simplified BSD License text as described in Section 4.e of
    the Trust Legal Provisions and are provided without warranty as
-   described in the BSD License.
+   described in the Simplified BSD License.
 
    This document may contain material from IETF Documents or IETF
    Contributions published or made publicly available before November
@@ -108,44 +103,53 @@
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 2]
-
-Internet-Draft                 WebDAV Sync                 November 2009
 
 
-Table of Contents
 
-   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
-   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  3
-   3.  Open Issues  . . . . . . . . . . . . . . . . . . . . . . . . .  4
-   4.  WebDAV Synchronization . . . . . . . . . . . . . . . . . . . .  4
-     4.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  4
-     4.2.  DAV:sync-collection report . . . . . . . . . . . . . . . .  5
-     4.3.  Types of changes reported  . . . . . . . . . . . . . . . .  7
-       4.3.1.  New resource . . . . . . . . . . . . . . . . . . . . .  7
-       4.3.2.  Modified resource  . . . . . . . . . . . . . . . . . .  7
-       4.3.3.  Removed resource . . . . . . . . . . . . . . . . . . .  7
-     4.4.  Example: Initial DAV:sync-collection REPORT  . . . . . . .  8
-     4.5.  Example: DAV:sync-collection Report with token . . . . . . 10
-   5.  DAV:sync-token Property  . . . . . . . . . . . . . . . . . . . 11
-   6.  XML Element Definitions  . . . . . . . . . . . . . . . . . . . 12
-     6.1.  DAV:sync-collection XML Element  . . . . . . . . . . . . . 12
-     6.2.  DAV:sync-token XML Element . . . . . . . . . . . . . . . . 12
-     6.3.  DAV:multistatus XML Element  . . . . . . . . . . . . . . . 13
-     6.4.  DAV:sync-response XML Element  . . . . . . . . . . . . . . 13
-   7.  Security Considerations  . . . . . . . . . . . . . . . . . . . 14
-   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 14
-   9.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 14
-   10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 14
-     10.1. Normative References . . . . . . . . . . . . . . . . . . . 14
-     10.2. Informative References . . . . . . . . . . . . . . . . . . 14
-   Appendix A.  Change History (to be removed prior to
-                publication as an RFC)  . . . . . . . . . . . . . . . 15
 
 
+Daboo & Quillaud          Expires April 8, 2011                 [Page 2]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
+Table of Contents
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  4
+   3.  WebDAV Synchronization . . . . . . . . . . . . . . . . . . . .  5
+     3.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  5
+     3.2.  DAV:sync-collection Report . . . . . . . . . . . . . . . .  6
+     3.3.  Depth behavior . . . . . . . . . . . . . . . . . . . . . .  7
+     3.4.  Types of Changes Reported on Initial Synchronization . . .  8
+     3.5.  Types of Changes Reported on Subsequent
+           Synchronizations . . . . . . . . . . . . . . . . . . . . .  8
+       3.5.1.  Changed Resource . . . . . . . . . . . . . . . . . . .  8
+       3.5.2.  Removed Resource . . . . . . . . . . . . . . . . . . .  9
+     3.6.  Truncation of Results  . . . . . . . . . . . . . . . . . .  9
+     3.7.  Limiting Results . . . . . . . . . . . . . . . . . . . . . 10
+     3.8.  Example: Initial DAV:sync-collection Report  . . . . . . . 11
+     3.9.  Example: DAV:sync-collection Report with Token . . . . . . 12
+     3.10. Example: Initial DAV:sync-collection Report with
+           Truncation . . . . . . . . . . . . . . . . . . . . . . . . 15
+     3.11. Example: Initial DAV:sync-collection Report with Limit . . 16
+     3.12. Example: DAV:sync-collection Report with Unsupported
+           Limit  . . . . . . . . . . . . . . . . . . . . . . . . . . 18
+     3.13. Example: Depth:infinity initial DAV:sync-collection
+           Report . . . . . . . . . . . . . . . . . . . . . . . . . . 18
+   4.  DAV:sync-token Property  . . . . . . . . . . . . . . . . . . . 21
+   5.  XML Element Definitions  . . . . . . . . . . . . . . . . . . . 21
+     5.1.  DAV:sync-collection XML Element  . . . . . . . . . . . . . 22
+     5.2.  DAV:sync-token XML Element . . . . . . . . . . . . . . . . 22
+     5.3.  DAV:multistatus XML Element  . . . . . . . . . . . . . . . 22
+   6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 23
+   7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 23
+   8.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 23
+   9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 23
+     9.1.  Normative References . . . . . . . . . . . . . . . . . . . 23
+     9.2.  Informative References . . . . . . . . . . . . . . . . . . 24
+   Appendix A.  Change History (to be removed prior to
+                publication as an RFC)  . . . . . . . . . . . . . . . 24
 
 
 
@@ -160,13 +164,9 @@
 
 
 
-
-
-
-
-Daboo & Quillaud          Expires May 22, 2010                  [Page 3]
+Daboo & Quillaud          Expires April 8, 2011                 [Page 3]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
 1.  Introduction
@@ -220,9 +220,9 @@
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 4]
+Daboo & Quillaud          Expires April 8, 2011                 [Page 4]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
    When an XML element type in the "DAV:" namespace is referenced in
@@ -232,29 +232,10 @@
    This document inherits, and sometimes extends, DTD productions from
    Section 14 of [RFC4918].
 
-3.  Open Issues
+3.  WebDAV Synchronization
 
-   1.  We are extending the multistatus response element in a
-       significant way.  The DAV:sync-response differs from a regular
-       DAV:response because, in the case of a created or modified
-       resource, it contains both a DAV:status (201 for created, 200 for
-       modified) and a DAV:propstat.  The DAV:response on the other hand
-       contains either a DAV:status or a DAV:propstat but not both.
-       Shall we define a DAV:multisyncstatus response element instead of
-       overloading DAV:multistatus ?
+3.1.  Overview
 
-   2.  Do clients really need to be notified that a resource was created
-       versus modified ?  They should be able to figure that out by
-       looking at the state of their current cache.  If this information
-       is not necessary, the response would not need to contain a DAV:
-       status along with the DAV:propstat.  This would allow the use of
-       a regular multistatus (simply extended with a sync-token
-       element).
-
-4.  WebDAV Synchronization
-
-4.1.  Overview
-
    One way to synchronize data between two entities is to use some form
    of synchronization token.  The token defines the state of the data
    being synchronized at a particular point in time.  It can then be
@@ -274,196 +255,320 @@
    The server also returns a new token representing the new state at the
    time the report was run.
 
-
-
-Daboo & Quillaud          Expires May 22, 2010                  [Page 5]
-
-Internet-Draft                 WebDAV Sync                 November 2009
-
-
-   Typically the first time a client connects to the server it will need
-   to be informed of the entire state of the collection (i.e., a full
-   list of all resources that are currently contained in the
+   Typically, the first time a client connects to the server it will
+   need to be informed of the entire state of the collection (i.e., a
+   full list of all resources that are currently contained in the
    collection).  That is done by the client sending an empty token value
    to the server.  This indicates to the server that a full listing is
-   required.  As an alternative, the client may choose to do its first
+   required.
+
+   As an alternative, the client might choose to do its first
    synchronization using some other mechanism on the collection (e.g.
    some other form of batch resource information retrieval such as
    PROPFIND, SEARCH [RFC5323], or specialized REPORTs such as those
    defined in CalDAV [RFC4791] and CardDAV [I-D.ietf-vcarddav-carddav])
    and ask for the DAV:sync-token property to be returned.  This
-   property (defined in Section 5) contains the same token that can be
+   property (defined in Section 4) contains the same token that can be
    used later on to issue a DAV:sync-collection report.
 
-   In some cases a server may only wish to maintain a limited amount of
-   history about changes to a collection.  In that situation it will
+   In some cases a server might only wish to maintain a limited amount
+   of history about changes to a collection.  In that situation it will
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                 [Page 5]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
    return an error to the client when the client presents a token that
    is "out of date".  At that point the client has to fall back to
    synchronizing the entire collection by re-running the report request
-   using an empty token value.  ACL changes may also cause a token to
-   become invalid.
+   using an empty token value.
 
-4.2.  DAV:sync-collection report
+3.2.  DAV:sync-collection Report
 
-   This specification defines the DAV:sync-collection report.
+   If the DAV:sync-collection report is implemented by a WebDAV server,
+   then the server MUST list the report in the "DAV:supported-report-
+   set" property on any collection supporting synchronization.
 
-   If this report is implemented by a WebDAV server, then the server
-   MUST list the report in the "DAV:supported-report-set" property on
-   any collection supporting synchronization.
-
    To implement the behavior for this report a server needs to keep
-   track of changes to any resources in a collection.  This includes
-   noting the addition of new resources, changes to existing resources
-   and removal of resources (where "removal" could be the result of a
-   DELETE or MOVE WebDAV request).  Only internal members of the
-   collection (as defined in [RFC4918]) are to be considered.  The
-   server will track each change and provide a synchronization "token"
-   to the client that describes the state of the server at a specific
-   point in time.  This "token" is returned as part of the response to
-   the "sync-collection" report.  Clients include the last token they
-   got from the server in the next "sync-collection" report that they
-   execute and the server provides the changes from the previous state,
-   represented by the token, to the current state, represented by the
-   new token returned.
+   track of changes to any member resources in a collection (as defined
+   in Section 3 of [RFC4918]).  This includes noting the addition of new
+   resources, changes to existing resources and removal of resources.
+   The server will track each change and provide a synchronization
+   "token" to the client that describes the state of the server at a
+   specific point in time.  This "token" is returned as part of the
+   response to the "sync-collection" report.  Clients include the last
+   token they got from the server in the next "sync-collection" report
+   that they execute and the server provides the changes from the
+   previous state, represented by the token, to the current state,
+   represented by the new token returned.
 
    The synchronization token itself is an "opaque" string - i.e., the
-   actual string data has no specific meaning or syntax.  A simple
-   implementation of such a token would be a numeric counter that counts
+   actual string data has no specific meaning or syntax.  For example, a
+   simple implementation of such a token could be a numeric counter that
+   counts each change as it occurs and relates that change to the
+   specific object that changed.
 
-
-
-Daboo & Quillaud          Expires May 22, 2010                  [Page 6]
-
-Internet-Draft                 WebDAV Sync                 November 2009
-
-
-   each change as it occurs and relates that change to the specific
-   object that changed.
-
    Marshalling:
 
-      The request URI MUST be a collection.  The request body MUST be a
-      DAV:sync-collection XML element (see Section 6.1), which MUST
-      contain one DAV:sync-token XML element, and optionally a DAV:
-      propstat XML element.
+      The request URI MUST identify a collection.  The request body MUST
+      be a DAV:sync-collection XML element (see Section 5.1), which MUST
+      contain one DAV:sync-token XML element, and one DAV:prop XML
+      element, and MAY contain a DAV:limit XML element.
 
-      The request MUST include a Depth header with a value of "1".
+      The request MUST include a Depth header with a value of "1" or
+      "infinity".
 
       The response body for a successful request MUST be a DAV:
       multistatus XML element, which MUST contain one DAV:sync-token
-      element in addition to any DAV:sync-response elements.
-
-      The response body for a successful DAV:sync-collection report
-      request MUST contain a DAV:sync-response element for each resource
+      element in addition to one DAV:response element for each resource
       that was created, has changed or been deleted since the last
       synchronization operation as specified by the DAV:sync-token
       provided in the request.  A given resource MUST appear only once
       in the response.
 
-      The DAV:status element in each DAV:sync-response element is used
-      to indicate how the resource may have changed:
 
-         A status code of '201 Created' is used to indicate resources
-         that are new.
 
-         A status code of '200 OK' is used to indicate resources that
-         have changed.
 
-         A status code of '404 Not Found' is used to indicate resources
-         that have been removed.
+Daboo & Quillaud          Expires April 8, 2011                 [Page 6]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
-      The conditions under which each type of change may occur is
-      further described in Section 4.3.
 
+      The content of each DAV:response element differs depending on how
+      the resource was altered:
+
+         For resources that have changed (i.e., are new or have been
+         modified) the DAV:response MUST contain at least one DAV:
+         propstat element and MUST NOT contain any DAV:status element.
+
+         For resources that have been removed, the DAV:response MUST
+         contain one DAV:status with a value set to '404 Not Found' and
+         MUST NOT contain any DAV:propstat element.
+
+         For child collection resources that are unable to support the
+         DAV:sync-collection report, the DAV:response MUST contain one
+         DAV:status with a value set to '405 Method Not Allowed' and
+         MUST NOT contain any DAV:propstat element.
+
+      The conditions under which each type of change can occur is
+      further described in Section 3.5.
+
    Preconditions:
 
       (DAV:valid-sync-token): The DAV:sync-token element value MUST map
       to a valid token previously returned by the server.  A token may
       become invalid as the result of being "out of date" (out of the
       range of change history maintained by the server), or for other
-      reasons (e.g. collection deleted, then recreated, ACL changes,
-      etc...).
+      reasons (e.g. collection deleted, then recreated, access control
+      changes, etc...).
 
    Postconditions:
 
+      (DAV:number-of-matches-within-limits): The number of changes
+      reported in the response must fall within the client specified
+      limit.  This condition might be triggered if a client requests a
+      limit on the number of responses (as per Section 3.7) but the
+      server is unable to truncate the result set at or below that
+      limit.
 
+3.3.  Depth behavior
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 7]
+   The DAV:sync-collection report supports both Depth:1 and Depth:
+   infinity request headers.
+
+   o  When the client specifies Depth:1, only additions, changes or
+      removals of immediate children of the collection specified as the
+      request URI are reported.
+
+   o  When the client specifies Depth:infinity, additions, changes or
+      removals of any child resource of the collection specified as the
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                 [Page 7]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
-      None.
+      request URI are reported, provided child collections themselves
+      also support the DAV:sync-collection report.
 
-4.3.  Types of changes reported
+   o  DAV:sync-token values returned by the server are not specific to
+      the value of the Depth header used in the request.  As such
+      clients MAY use a DAV:sync-token value from a request with one
+      Depth value for a similar request with a different Depth value,
+      however the utility of this is limited.
 
-   Three types of resource state changes can be returned by the DAV:
-   sync-collection report (new, modified, removed).  This section
-   further defines under which condition each of them shall be used.  It
-   also clarifies the case where a resource may have undergone multiple
-   changes in between two synchronizations.
+   Note that when a server supports Depth:infinity reports, it might not
+   be possible to synchronize some child collections within the
+   collection targeted by the report.  In such cases the server is
+   REQUIRED to return a DAV:response with status '405 Method Not
+   Allowed' to inform the client that alternative methods have to be
+   used to synchronize the contents of those collections.  The 405
+   response MUST be sent once, when the collection is first reported to
+   the client.
 
-4.3.1.  New resource
+3.4.  Types of Changes Reported on Initial Synchronization
 
-   A resource MUST be reported as new if it has been mapped directly
-   under the target collection since the request sync token was
+   When the DAV:sync-collection request contains an empty DAV:sync-token
+   element, the server MUST return all members of the collection (taking
+   account of Depth header requirements as per Section 3.3, and optional
+   truncation of results set as per Section 3.6) and it MUST NOT return
+   any removed resources.  All types of resource (collection or non-
+   collection) MUST be reported.
+
+3.5.  Types of Changes Reported on Subsequent Synchronizations
+
+   When the DAV:sync-collection request contains a valid value for the
+   DAV:sync-token element, two types of resource state changes can be
+   returned (changed or removed).  This section defines what triggers
+   each of these to be returned.  It also clarifies the case where a
+   resource may have undergone multiple changes between two
+   synchronization report requests.  In all cases, the Depth header
+   requirements as per Section 3.3, and optional truncation of results
+   set as per Section 3.6, are taken into account by the server.
+
+3.5.1.  Changed Resource
+
+   A resource MUST be reported as changed if it has been mapped as an
+   member of the target collection since the request sync-token was
    generated.  This includes resources that have been mapped as the
-   result of a COPY, MOVE or BIND ([I-D.ietf-webdav-bind]) operation.
-   This also includes collection resources that have been created.
+   result of a COPY, MOVE or BIND [RFC5842] request.  All types of
+   resource (collection or non-collection) MUST be reported.
 
    In the case where a mapping between a resource and the target
    collection was removed, then a new mapping with the same URI created,
-   the new resource MUST be reported as new, while the old resource MUST
-   NOT be reported as removed.  For example, if a resource was deleted,
-   then recreated using the same URI, it should be reported as a new
-   resource only.
 
-   A resource MAY be reported as new if the user issuing the request was
-   granted access to this resource, due to access control changes.
 
-4.3.2.  Modified resource
 
-   A resource MUST be reported as modified if it is not reported as new
-   and if its entity tag value (defined in [RFC2616]) has changed since
-   the request sync token was generated.  In other words, the new
-   resource change indicator takes precedence over the modified resource
-   change indicator.
+Daboo & Quillaud          Expires April 8, 2011                 [Page 8]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
-   Collection resources MUST NOT be returned as modified.  Instead
-   clients are expected to synchronize changes in child collection
-   resources on an individual basis.
 
-4.3.3.  Removed resource
+   the new resource MUST be reported as changed while the old resource
+   MUST NOT be reported as removed.  For example, if a resource was
+   deleted, then recreated using the same URI, it should be reported as
+   a changed resource only.
 
+   A resource MUST be reported as changed if its entity tag value
+   (defined in Section 3.11 of [RFC2616]) has changed since the request
+   sync-token was generated.
+
+   A resource MAY be reported as changed if the user issuing the request
+   was granted access to this resource, due to access control changes.
+
+   Collection resources MUST be returned as changed if they have an
+   entity tag associated with them and that entity tag changes.  There
+   is no guarantee that changes to members of a collection will result
+   in a change in any entity tag of that collection, so clients cannot
+   rely on a series of Depth:1 reports at multiple levels to track all
+   changes within a collection.  Instead Depth:infinity has to be used.
+
+3.5.2.  Removed Resource
+
    A resource MUST be reported as removed if its mapping under the
-   target collection has been removed since the request sync token was
+   target collection has been removed since the request sync-token was
    generated, and it has not been re-mapped since it was removed.  This
    includes resources that have been unmapped as the result of a MOVE or
-   UNBIND ([I-D.ietf-webdav-bind]) operation.  This also includes
-   collection resources that have been removed.
+   UNBIND [RFC5842] operation.  This also includes collection resources
+   that have been removed, including ones that themselves do not support
+   the DAV:sync-collection report.
 
+   If a resource was created (and possibly modified), then removed
+   between two synchronization report requests, it MUST be reported as
+   removed.  This ensures that a client that creates a resource is
+   informed of the removal of the resource, if the removal occurs before
+   the client has had a chance to request a synchronization report.
 
+   A resource MAY be reported as removed if the user issuing the request
+   no longer has access to this resource, due to access control changes.
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 8]
+   For a Depth:infinity report where a collection is removed, the server
+   MUST NOT report the removal of any resources that are members of the
+   removed collection.  Clients MUST assume that if a collection is
+   reported as being removed, then all internal members of that
+   collection have also been removed.
+
+3.6.  Truncation of Results
+
+   A server MAY limit the number of resources in a response, for
+   example, to limit the amount of work expended in processing a
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                 [Page 9]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
-   If a resource was created (and possibly modified), then removed in
-   between two synchronizations, it MUST NOT be reported as new,
-   modified or removed.
+   request, or as the result of an explicit limit set by the client.  If
+   the result set is truncated, the response MUST use status code 207,
+   return a DAV:multistatus response body, and indicate a status of 507
+   (Insufficient Storage) for the request URI.  That DAV:response
+   element SHOULD include a DAV:error element with the DAV:number-of-
+   matches-within-limits precondition, as defined in [RFC3744] (Section
+   9.2).  DAV:response elements for all the changes being reported are
+   also included.
 
-   A resource MAY be reported as removed if the user issuing the request
-   has no longer access to this resource, due to access control changes.
+   When truncation occurs, the DAV:sync-token value returned in the
+   response MUST represent the correct state for the partial set of
+   changes returned.  That allows the client to use the returned DAV:
+   sync-token to fetch the next set of changes.  In this way the client
+   can effectively "page" through the entire set of changes in a
+   consistent manner.
 
-4.4.  Example: Initial DAV:sync-collection REPORT
+   Clients MUST handle the 507 status on the request-URI in the response
+   to the report.
 
+   For example, consider a server that records changes using a
+   monotonically increasing integer to represent a "revision number" and
+   uses that quantity as the DAV:sync-token value.  Assume the last DAV:
+   sync-token used by the client was "10", and since then 15 additional
+   changes have occurred.  If the client executes a DAV:sync-collection
+   request with a DAV:sync-token of "10", without a limit the server
+   would return 15 DAV:response elements and a DAV:sync-token with value
+   "25".  But if the server choose to limit responses to at most 10
+   changes, then it would return only 10 DAV:response elements and a
+   DAV:sync-token with value "20", together with an addition DAV:
+   response element for the request-URI with a status code of 507.
+   Subsequently, the client can re-issue the request with the DAV:sync-
+   token value returned from the server and fetch the remaining 5
+   changes.
+
+3.7.  Limiting Results
+
+   A client can limit the number of results returned by the server
+   through use of the DAV:limit element ([RFC5323], Section 5.17) in the
+   request body.  This is useful when clients have limited space or
+   bandwidth for the results.  If a server is unable to truncate the
+   result at or below the requested number, then it MUST fail the
+   request with a DAV:number-of-matches-within-limits post-condition
+   error.  When the results can be correctly limited by the server, the
+   server MUST follow the rules above for indicating a result set
+   truncation to the client.
+
+
+
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 10]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
+3.8.  Example: Initial DAV:sync-collection Report
+
    In this example, the client is making its first synchronization
    request to the server, so the DAV:sync-token element in the request
-   is empty.  It also asks for the DAV:getetag property.  The server
-   responds with the items currently in the targeted collection
-   (indicating that they are 'new' via the '201 Created' status code).
-   The current synchronization token is also returned.
+   is empty.  It also asks for the DAV:getetag property and for a
+   proprietary property.  The server responds with the items currently
+   in the targeted collection.  The current synchronization token is
+   also returned.
 
    >> Request <<
 
@@ -477,34 +582,153 @@
    <?xml version="1.0" encoding="utf-8" ?>
    <D:sync-collection xmlns:D="DAV:">
      <D:sync-token/>
-     <D:prop>
+     <D:prop xmlns:R="urn:ns.example.com:boxschema">
        <D:getetag/>
+       <R:bigbox/>
      </D:prop>
    </D:sync-collection>
 
 
+   >> Response <<
 
 
+   HTTP/1.1 207 Multi-Status
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
 
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:">
+     <D:response>
+     <D:href
+   >http://webdav.example.com/home/cyrusdaboo/test.doc</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00001-abcd1"</D:getetag>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema">
+           <R:BoxType>Box type A</R:BoxType>
+         </R:bigbox>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
 
 
 
+Daboo & Quillaud          Expires April 8, 2011                [Page 11]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >http://webdav.example.com/home/cyrusdaboo/vcard.vcf</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00002-abcd1"</D:getetag>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     <D:propstat>
+       <D:prop>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
+       </D:prop>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >http://webdav.example.com/home/cyrusdaboo/calendar.ics</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00003-abcd1"</D:getetag>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     <D:propstat>
+       <D:prop>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
+       </D:prop>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:propstat>
+     </D:response>
+     <D:sync-token>1234</D:sync-token>
+   </D:multistatus>
 
 
+3.9.  Example: DAV:sync-collection Report with Token
 
+   In this example, the client is making a synchronization request to
+   the server and is using the DAV:sync-token element returned from the
+   last report it ran on this collection.  The server responds, listing
+   the items that have been added, changed or removed.  The (new)
+   current synchronization token is also returned.
 
 
 
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                  [Page 9]
+Daboo & Quillaud          Expires April 8, 2011                [Page 12]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
+   >> Request <<
+
+
+   REPORT /home/cyrusdaboo/ HTTP/1.1
+   Host: webdav.example.com
+   Depth: 1
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:sync-collection xmlns:D="DAV:">
+     <D:sync-token>1234</D:sync-token>
+     <D:prop xmlns:R="urn:ns.example.com:boxschema">
+       <D:getetag/>
+       <R:bigbox/>
+     </D:prop>
+   </D:sync-collection>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 13]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
    >> Response <<
 
 
@@ -514,60 +738,61 @@
 
    <?xml version="1.0" encoding="utf-8" ?>
    <D:multistatus xmlns:D="DAV:">
-     <D:sync-response>
+     <D:response>
      <D:href
-   >http://webdav.example.com/home/cyrusdaboo/test.doc</D:href>
-     <D:status>HTTP/1.1 201 Created</D:status>
+   >http://webdav.example.com/home/cyrusdaboo/file.xml</D:href>
      <D:propstat>
        <D:prop>
-         <D:getetag>"00001-abcd1"</D:getetag>
+         <D:getetag>"00004-abcd1"</D:getetag>
        </D:prop>
        <D:status>HTTP/1.1 200 OK</D:status>
      </D:propstat>
-     </D:sync-response>
-     <D:sync-response>
+     <D:propstat>
+       <D:prop>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
+       </D:prop>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
      <D:href
    >http://webdav.example.com/home/cyrusdaboo/vcard.vcf</D:href>
-     <D:status>HTTP/1.1 201 Created</D:status>
      <D:propstat>
        <D:prop>
-         <D:getetag>"00002-abcd1"</D:getetag>
+         <D:getetag>"00002-abcd2"</D:getetag>
        </D:prop>
        <D:status>HTTP/1.1 200 OK</D:status>
      </D:propstat>
-     </D:sync-response>
-     <D:sync-response>
-     <D:href
-   >http://webdav.example.com/home/cyrusdaboo/calendar.ics</D:href>
-     <D:status>HTTP/1.1 201 Created</D:status>
      <D:propstat>
        <D:prop>
-         <D:getetag>"00003-abcd1"</D:getetag>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
        </D:prop>
-       <D:status>HTTP/1.1 200 OK</D:status>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
      </D:propstat>
-     </D:sync-response>
-     <D:sync-token>1234</D:sync-token>
+     </D:response>
+     <D:response>
+     <D:href
+   >http://webdav.example.com/home/cyrusdaboo/test.doc</D:href>
+     <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:response>
+     <D:sync-token>1238</D:sync-token>
    </D:multistatus>
 
 
 
-
-
-
-
-Daboo & Quillaud          Expires May 22, 2010                 [Page 10]
+Daboo & Quillaud          Expires April 8, 2011                [Page 14]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
-4.5.  Example: DAV:sync-collection Report with token
+3.10.  Example: Initial DAV:sync-collection Report with Truncation
 
-   In this example, the client is making a synchronization request to
-   the server and is using the DAV:sync-token element returned from the
-   last report it ran on this collection.  The server responds listing
-   the items that have been added, changed or removed.  The (new)
-   current synchronization token is also returned.
+   In this example, the client is making its first synchronization
+   request to the server, so the DAV:sync-token element in the request
+   is empty.  It also asks for the DAV:getetag property.  The server
+   responds with the items currently in the targeted collection, but
+   truncated at two items.  The synchronization token for the truncated
+   result set is returned.
 
    >> Request <<
 
@@ -580,7 +805,7 @@
 
    <?xml version="1.0" encoding="utf-8" ?>
    <D:sync-collection xmlns:D="DAV:">
-     <D:sync-token>1234</D:sync-token>
+     <D:sync-token/>
      <D:prop>
        <D:getetag/>
      </D:prop>
@@ -611,10 +836,9 @@
 
 
 
-
-Daboo & Quillaud          Expires May 22, 2010                 [Page 11]
+Daboo & Quillaud          Expires April 8, 2011                [Page 15]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
    >> Response <<
@@ -626,53 +850,295 @@
 
    <?xml version="1.0" encoding="utf-8" ?>
    <D:multistatus xmlns:D="DAV:">
-     <D:sync-response>
+     <D:response>
      <D:href
-   >http://webdav.example.com/home/cyrusdaboo/file.xml</D:href>
-     <D:status>HTTP/1.1 201 Created</D:status>
+   >http://webdav.example.com/home/cyrusdaboo/test.doc</D:href>
      <D:propstat>
        <D:prop>
-         <D:getetag>"00004-abcd1"</D:getetag>
+         <D:getetag>"00001-abcd1"</D:getetag>
        </D:prop>
        <D:status>HTTP/1.1 200 OK</D:status>
      </D:propstat>
-     </D:sync-response>
-     <D:sync-response>
+     </D:response>
+     <D:response>
      <D:href
    >http://webdav.example.com/home/cyrusdaboo/vcard.vcf</D:href>
-     <D:status>HTTP/1.1 200 OK</D:status>
      <D:propstat>
        <D:prop>
-         <D:getetag>"00002-abcd2"</D:getetag>
+         <D:getetag>"00002-abcd1"</D:getetag>
        </D:prop>
        <D:status>HTTP/1.1 200 OK</D:status>
      </D:propstat>
-     </D:sync-response>
-     <D:sync-response>
+     </D:response>
+     <D:response>
+       <D:href
+   >http://webdav.example.com/home/cyrusdaboo/</D:href>
+       <D:status>HTTP/1.1 507 Insufficient Storage</D:status>
+       <D:error><D:number-of-matches-within-limits/></D:error>
+     </D:response>
+     <D:sync-token>1233</D:sync-token>
+   </D:multistatus>
+
+
+3.11.  Example: Initial DAV:sync-collection Report with Limit
+
+   In this example, the client is making its first synchronization
+   request to the server, so the DAV:sync-token element in the request
+   is empty.  It requests a limit of 1 for the responses returned by the
+   server.  It also asks for the DAV:getetag property.  The server
+   responds with the items currently in the targeted collection, but
+   truncated at one item.  The synchronization token for the truncated
+   result set is returned.
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 16]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
+   >> Request <<
+
+
+   REPORT /home/cyrusdaboo/ HTTP/1.1
+   Host: webdav.example.com
+   Depth: 1
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:sync-collection xmlns:D="DAV:">
+     <D:sync-token/>
+     <D:limit>
+       <D:nresults>1</D:nresults>
+     </D:limit>
+     <D:prop>
+       <D:getetag/>
+     </D:prop>
+   </D:sync-collection>
+
+
+   >> Response <<
+
+
+   HTTP/1.1 207 Multi-Status
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:">
+     <D:response>
      <D:href
    >http://webdav.example.com/home/cyrusdaboo/test.doc</D:href>
-     <D:status>HTTP/1.1 404 Not Found</D:status>
-     </D:sync-response>
-     <D:sync-token>1238</D:sync-token>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00001-abcd1"</D:getetag>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+       <D:href
+   >http://webdav.example.com/home/cyrusdaboo/</D:href>
+       <D:status>HTTP/1.1 507 Insufficient Storage</D:status>
+       <D:error><D:number-of-matches-within-limits/></D:error>
+     </D:response>
+     <D:sync-token>1232</D:sync-token>
    </D:multistatus>
 
 
-5.  DAV:sync-token Property
 
-   Name:  sync-token
+Daboo & Quillaud          Expires April 8, 2011                [Page 17]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
-   Namespace:  DAV:
 
+3.12.  Example: DAV:sync-collection Report with Unsupported Limit
 
+   In this example, the client is making a synchronization request to
+   the server with a valid DAV:sync-token element value.  It requests a
+   limit of 100 for the responses returned by the server.  It also asks
+   for the DAV:getetag property.  The server is unable to limit the
+   results to the maximum specified by the client, so it responds with a
+   507 status code and appropriate post-condition error code.
 
+   >> Request <<
 
 
+   REPORT /home/cyrusdaboo/ HTTP/1.1
+   Host: webdav.example.com
+   Depth: 1
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
 
-Daboo & Quillaud          Expires May 22, 2010                 [Page 12]
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:sync-collection xmlns:D="DAV:">
+     <D:sync-token>1232</D:sync-token>
+     <D:limit>
+       <D:nresults>100</D:nresults>
+     </D:limit>
+     <D:prop>
+       <D:getetag/>
+     </D:prop>
+   </D:sync-collection>
+
+
+   >> Response <<
+
+
+   HTTP/1.1 507 Insufficient Storage
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:error xmlns:D="DAV:">
+     <D:number-of-matches-within-limits/>
+   </D:error>
+
+
+3.13.  Example: Depth:infinity initial DAV:sync-collection Report
+
+   In this example, the client is making its first synchronization
+   request to the server, so the DAV:sync-token element in the request
+   is empty, and it is using Depth:infinity.  It also asks for the DAV:
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 18]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
+   getetag property and for a proprietary property.  The server responds
+   with the items currently in the targeted collection.  The current
+   synchronization token is also returned.
+
+   The collection /home/cyrusdaboo/collection1/ exists and has one child
+   resource which is also reported.  The collection /home/cyrusdaboo/
+   collection2/ exists but has no child resources.  The collection
+   /home/cyrusdaboo/shared/ is returned with a 405 status indicating
+   that a collection exists but it is unable to report on changes within
+   it in the scope of the current Depth:infinity report.  Instead the
+   client can try a DAV:sync-collection report directly on the
+   collection URI.
+
+   >> Request <<
+
+
+   REPORT /home/cyrusdaboo/ HTTP/1.1
+   Host: webdav.example.com
+   Depth: 1
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:sync-collection xmlns:D="DAV:">
+     <D:sync-token/>
+     <D:prop xmlns:R="urn:ns.example.com:boxschema">
+       <D:getetag/>
+       <R:bigbox/>
+     </D:prop>
+   </D:sync-collection>
+
+
+   >> Response <<
+
+
+   HTTP/1.1 207 Multi-Status
+   Content-Type: text/xml; charset="utf-8"
+   Content-Length: xxxx
+
+   <?xml version="1.0" encoding="utf-8" ?>
+   <D:multistatus xmlns:D="DAV:">
+     <D:response>
+     <D:href
+   >/home/cyrusdaboo/collection1/</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00001-abcd1"</D:getetag>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema">
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 19]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
+           <R:BoxType>Box type A</R:BoxType>
+         </R:bigbox>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >/home/cyrusdaboo/collection1/test.doc</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00001-abcd1"</D:getetag>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema">
+           <R:BoxType>Box type A</R:BoxType>
+         </R:bigbox>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >/home/cyrusdaboo/collection2/</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00002-abcd1"</D:getetag>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     <D:propstat>
+       <D:prop>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
+       </D:prop>
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >/home/cyrusdaboo/calendar.ics</D:href>
+     <D:propstat>
+       <D:prop>
+         <D:getetag>"00003-abcd1"</D:getetag>
+       </D:prop>
+       <D:status>HTTP/1.1 200 OK</D:status>
+     </D:propstat>
+     <D:propstat>
+       <D:prop>
+         <R:bigbox xmlns:R="urn:ns.example.com:boxschema"/>
+       </D:prop>
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 20]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
+       <D:status>HTTP/1.1 404 Not Found</D:status>
+     </D:propstat>
+     </D:response>
+     <D:response>
+     <D:href
+   >/home/cyrusdaboo/shared/</D:href>
+     <D:status>HTTP/1.1 405 Method Not Allowed</D:status>
+     </D:response>
+     <D:sync-token>1234</D:sync-token>
+   </D:multistatus>
+
+
+4.  DAV:sync-token Property
+
+   Name:  sync-token
+
+   Namespace:  DAV:
+
    Purpose:  Contains the value of the synchronization token as it would
       be returned by a DAV:sync-collection report.
 
@@ -690,7 +1156,7 @@
       contains the value of the synchronization token as it would be
       returned by a DAV:sync-collection report on that resource at the
       same point in time.  It SHOULD NOT be returned by a PROPFIND DAV:
-      allprop request (as defined in [RFC4918]).
+      allprop request (as defined in Section 14.2 of [RFC4918]).
 
    Definition:
 
@@ -698,37 +1164,40 @@
    <!ELEMENT sync-token #PCDATA>
 
 
-6.  XML Element Definitions
+5.  XML Element Definitions
 
-6.1.  DAV:sync-collection XML Element
 
-   Name:  sync-collection
 
-   Namespace:  DAV:
 
-   Purpose:  WebDAV report used to synchronize data between client and
-      server.
 
-   Description:  See Section 4.
 
 
+Daboo & Quillaud          Expires April 8, 2011                [Page 21]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
-   <!ELEMENT sync-collection (sync-token, DAV:prop?)>
 
+5.1.  DAV:sync-collection XML Element
 
-6.2.  DAV:sync-token XML Element
+   Name:  sync-collection
 
+   Namespace:  DAV:
 
+   Purpose:  WebDAV report used to synchronize data between client and
+      server.
 
+   Description:  See Section 3.
 
 
 
+   <!ELEMENT sync-collection (sync-token, DAV:limit?, DAV:prop)>
 
-Daboo & Quillaud          Expires May 22, 2010                 [Page 13]
-
-Internet-Draft                 WebDAV Sync                 November 2009
+   <!-- DAV:limit defined in RFC 5323, Section 5.17 -->
+   <!-- DAV:prop defined in RFC 4918, Section 14.18 -->
 
 
+5.2.  DAV:sync-token XML Element
+
    Name:  sync-token
 
    Namespace:  DAV:
@@ -736,14 +1205,14 @@
    Purpose:  The synchronization token provided by the server and
       returned by the client.
 
-   Description:  See Section 4.
+   Description:  See Section 3.
 
 
 
    <!ELEMENT sync-token CDATA>
 
 
-6.3.  DAV:multistatus XML Element
+5.3.  DAV:multistatus XML Element
 
    Name:  multistatus
 
@@ -752,57 +1221,48 @@
    Purpose:  Extends the DAV:multistatus element to include
       synchronization details.
 
-   Description:  See Section 4.
+   Description:  See Section 3.
 
 
 
-   <!ELEMENT multistatus ((DAV:response*, DAV:responsedescription?) |
-                (DAV:sync-response*, DAV:sync-token,
-                 DAV:responsedescription?))>
 
 
-6.4.  DAV:sync-response XML Element
 
-   Name:  sync-response
+Daboo & Quillaud          Expires April 8, 2011                [Page 22]
+
+Internet-Draft                 WebDAV Sync                  October 2010
 
-   Namespace:  DAV:
 
-   Purpose:  Contains the synchronization results returned by the
-      server.
+   <!ELEMENT multistatus (DAV:response*, DAV:responsedescription?,
+                          sync-token?) >
 
-   Description:  See Section 4.
+   <!-- DAV:multistatus originally defined in RFC 4918, Section 14.16
+        but overridden here to add the DAV:sync-token element -->
+   <!-- DAV:response defined in RFC 4918, Section 14.24 -->
+   <!-- DAV:responsedescription defined in RFC 4918, Section 14.25 -->
 
 
+6.  Security Considerations
 
-   <!ELEMENT sync-response (DAV:href, DAV:status, DAV:propstat?)>
-
-
-
-
-
-Daboo & Quillaud          Expires May 22, 2010                 [Page 14]
-
-Internet-Draft                 WebDAV Sync                 November 2009
-
-
-7.  Security Considerations
-
    This extension does not introduce any new security concerns than
    those already described in HTTP and WebDAV.
 
-8.  IANA Considerations
+7.  IANA Considerations
 
    This document does not require any actions on the part of IANA.
 
-9.  Acknowledgments
+8.  Acknowledgments
 
    The following individuals contributed their ideas and support for
    writing this specification: Bernard Desruisseaux, Mike Douglass, Ciny
-   Joy and Julian Reschke.
+   Joy, Andrew McMillan, Julian Reschke, and Wilfredo Sanchez.  We would
+   like to thank the Calendaring and Scheduling Consortium for
+   facilitating interoperability testing for early implementations of
+   this specification.
 
-10.  References
+9.  References
 
-10.1.  Normative References
+9.1.  Normative References
 
    [RFC2119]                    Bradner, S., "Key words for use in RFCs
                                 to Indicate Requirement Levels", BCP 14,
@@ -814,51 +1274,95 @@
                                 Protocol -- HTTP/1.1", RFC 2616,
                                 June 1999.
 
+   [RFC3744]                    Clemm, G., Reschke, J., Sedlar, E., and
+                                J. Whitehead, "Web Distributed Authoring
+                                and Versioning (WebDAV)
+                                Access Control Protocol", RFC 3744,
+                                May 2004.
+
    [RFC4918]                    Dusseault, L., "HTTP Extensions for Web
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 23]
+
+Internet-Draft                 WebDAV Sync                  October 2010
+
+
                                 Distributed Authoring and Versioning
                                 (WebDAV)", RFC 4918, June 2007.
 
-   [W3C.REC-xml-20081126]       Sperberg-McQueen, C., Yergeau, F., Bray,
-                                T., Paoli, J., and E. Maler, "Extensible
-                                Markup Language (XML) 1.0 (Fifth
-                                Edition)", World Wide Web Consortium
-                                Recommendation REC-xml-20081126,
-                                November 2008, <http://www.w3.org/TR/
-                                2008/REC-xml-20081126>.
+   [RFC5323]                    Reschke, J., Reddy, S., Davis, J., and
+                                A. Babich, "Web Distributed Authoring
+                                and Versioning (WebDAV) SEARCH",
+                                RFC 5323, November 2008.
 
-10.2.  Informative References
+   [W3C.REC-xml-20081126]       Paoli, J., Yergeau, F., Bray, T.,
+                                Sperberg-McQueen, C., and E. Maler,
+                                "Extensible Markup Language (XML) 1.0
+                                (Fifth Edition)", World Wide Web
+                                Consortium Recommendation REC-xml-
+                                20081126, November 2008, <http://
+                                www.w3.org/TR/2008/REC-xml-20081126>.
 
+9.2.  Informative References
+
    [I-D.ietf-vcarddav-carddav]  Daboo, C., "vCard Extensions to WebDAV
                                 (CardDAV)",
                                 draft-ietf-vcarddav-carddav-10 (work in
                                 progress), November 2009.
 
+   [RFC4791]                    Daboo, C., Desruisseaux, B., and L.
+                                Dusseault, "Calendaring Extensions to
+                                WebDAV (CalDAV)", RFC 4791, March 2007.
 
+   [RFC5842]                    Clemm, G., Crawford, J., Reschke, J.,
+                                and J. Whitehead, "Binding Extensions to
+                                Web Distributed Authoring and Versioning
+                                (WebDAV)", RFC 5842, April 2010.
 
+Appendix A.  Change History (to be removed prior to publication as an
+             RFC)
 
-Daboo & Quillaud          Expires May 22, 2010                 [Page 15]
+   Changes in -04:
+
+   1.  Depth:infinity support added.
+
+   2.  Collection resources are now reported as changed if they have a
+       valid entity tag associated with them.
+
+   Changes in -03:
+
+   1.  Changed D:propstat to D:prop in marshalling.
+
+   2.  Added request for dead property in examples.
+
+
+
+
+Daboo & Quillaud          Expires April 8, 2011                [Page 24]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
-   [I-D.ietf-webdav-bind]       Clemm, G., Crawford, J., Reschke, J.,
-                                and J. Whitehead, "Binding Extensions to
-                                Web Distributed Authoring and Versioning
-                                (WebDAV)", draft-ietf-webdav-bind-26
-                                (work in progress), September 2009.
+   3.  Made D:prop mandatory in request so that D:response always
+       contains at least one D:propstat as per WebDAV definition.
 
-   [RFC4791]                    Daboo, C., Desruisseaux, B., and L.
-                                Dusseault, "Calendaring Extensions to
-                                WebDAV (CalDAV)", RFC 4791, March 2007.
+   4.  Removed DAV:status from response when resource is created/
+       modified, thus allowing to get rid of DAV:sync-response in favor
+       of a regular DAV:response.  As a consequence, there is no longer
+       any difference in the report between created and modified
+       resources.
 
-   [RFC5323]                    Reschke, J., Reddy, S., Davis, J., and
-                                A. Babich, "Web Distributed Authoring
-                                and Versioning (WebDAV) SEARCH",
-                                RFC 5323, November 2008.
+   5.  Resource created, then removed between 2 sync MUST be returned as
+       removed.
 
-Appendix A.  Change History (to be removed prior to publication as an
-             RFC)
+   6.  Added ability for server to truncate results and indicate such to
+       the client.
 
+   7.  Added ability for client to request the server to limit the
+       result set.
+
    Changes in -02:
 
    1.  Added definition of sync-token WebDAV property.
@@ -892,9 +1396,9 @@
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                 [Page 16]
+Daboo & Quillaud          Expires April 8, 2011                [Page 25]
 
-Internet-Draft                 WebDAV Sync                 November 2009
+Internet-Draft                 WebDAV Sync                  October 2010
 
 
 Authors' Addresses
@@ -910,13 +1414,13 @@
 
 
    Arnaud Quillaud
-   Sun Microsystems
+   Oracle Corporation
    180, Avenue de l'Europe
    Saint Ismier cedex,   38334
    France
 
-   EMail: arnaud.quillaud at sun.com
-   URI:   http://www.sun.com/
+   EMail: arnaud.quillaud at oracle.com
+   URI:   http://www.oracle.com/
 
 
 
@@ -948,5 +1452,5 @@
 
 
 
-Daboo & Quillaud          Expires May 22, 2010                 [Page 17]
-
\ No newline at end of file
+Daboo & Quillaud          Expires April 8, 2011                [Page 26]
+

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/run
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/run	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/run	2010-10-18 04:33:34 UTC (rev 6433)
@@ -149,15 +149,15 @@
 
   # If we've been asked to read a configuration key, just read it and exit.
   if [ -n "${read_key}" ]; then
-    conf_read_key "${read_key}";
+    "${caldav}/bin/calendarserver_config" "${read_key}";
     exit $?;
   fi;
 
   if "${kill}" || "${restart}"; then
     # mimic logic of 'fullServerPath' from twistedcaldav/config.py to find the pid file
-    pidfile="$(conf_read_key "PIDFile")";
-    serverroot="$(conf_read_key "ServerRoot")";
-    runroot="$(conf_read_key "RunRoot")";
+    pidfile="$("${caldav}/bin/calendarserver_config" "PIDFile")";
+    serverroot="$("${caldav}/bin/calendarserver_config" "ServerRoot")";
+    runroot="$("${caldav}/bin/calendarserver_config" "RunRoot")";
     # examine first character of $pidfile
     if ( [ "${pidfile:0:1}" == "/" ] || [ "${pidfile:0:1}" == "." ]; ) then
         pidfile=$pidfile;

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh	2010-10-18 04:33:34 UTC (rev 6433)
@@ -29,20 +29,6 @@
   fi;
 }
 
-# Read a configuration key from the configuration plist file and print it to
-# stdout.
-conf_read_key ()
-{
-  local key="$1"; shift;
-
-  local xpath="xpath";
-
-  # FIXME: This only works for simple values (no arrays, dicts)
-  tr '\n' ' ' < "${config}"                                                 \
-    | ${xpath} "/plist/dict/*[preceding-sibling::key[1]='${key}'" 2> /dev/null \
-    | sed -n 's|^<[^<][^<]*>\([^<]*\)</[^<][^<]*>.*$|\1|p';
-}
-
 # Initialize all the global state required to use this library.
 init_build () {
         verbose="";

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twext/web2/dav/resource.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twext/web2/dav/resource.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twext/web2/dav/resource.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -711,6 +711,7 @@
         # First find all depth 1 children
         names1= []
         namesDeep = []
+        collections1 = []
         if names:
             for name in names:
                 (names1 if name.rstrip("/").find("/") == -1 else namesDeep).append(name.rstrip("/"))
@@ -722,10 +723,12 @@
         basepath = request.urlForResource(self)
         childnames = list((yield self.listChildren()))
         for childname in childnames:
-            if names1 and childname not in names1:
-                continue
             childpath = joinURL(basepath, urllib.quote(childname))
             child = (yield request.locateChildResource(self, childname))
+            if child.isCollection():
+                collections1.append((child, childpath + "/"))
+            if names and childname not in names1:
+                continue
             if child is None:
                 children.append((None, childpath + "/"))
             else:
@@ -748,7 +751,6 @@
 
         # Now determine whether each ace satisfies privileges
         #print aclmap
-        allowed_collections = []
         for items in aclmap.itervalues():
             checked = (yield self.checkACLPrivilege(
                 request, items[0], items[1], privileges, inherited_aces
@@ -757,8 +759,6 @@
                 for resource, url in items[2]:
                     if okcallback:
                         okcallback(resource, url)
-                    if resource.isCollection():
-                        allowed_collections.append((resource, url))
             else:
                 if badcallback:
                     for resource, url in items[2]:
@@ -771,15 +771,15 @@
                 collection, name = name.split("/", 1)
                 child_collections.setdefault(collection, []).append(name)
 
-            for collection, url in allowed_collections:
-                collection_name = collection.name()
+            for collection, url in collections1:
+                collection_name = url.split("/")[-2]
                 if collection_name in child_collections:
                     collection_inherited_aces = (
                         yield collection.inheritedACEsforChildren(request)
                     )
                     yield collection.findChildrenFaster(
                         depth, request, okcallback, badcallback,
-                        child_collections[collection_name], privileges,
+                        child_collections[collection_name] if names else None, privileges,
                         inherited_aces=collection_inherited_aces
                     )
                 

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directory/principal.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directory/principal.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -848,7 +848,7 @@
             addresses.add(uri)
             if config.HTTPPort:
                 addresses.add("http://%s:%s%s" % (config.ServerHostName, config.HTTPPort, uri))
-            if config.SSLPort:
+            if config.EnableSSL and config.SSLPort:
                 addresses.add("https://%s:%s%s" % (config.ServerHostName, config.SSLPort, uri))
 
         return addresses

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directorybackedaddressbook.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directorybackedaddressbook.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/directorybackedaddressbook.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -25,6 +25,7 @@
 from twext.python.log import Logger
 from twext.web2 import responsecode
 from twext.web2.dav import davxml
+from twext.web2.dav.element.extensions import SyncCollection
 from twext.web2.dav.resource import TwistedACLInheritable
 from twext.web2.http import HTTPError, StatusResponse
 
@@ -34,6 +35,8 @@
 from twistedcaldav.config import config
 from twistedcaldav.resource import CalDAVResource
 
+import uuid
+
 log = Logger()
 
 
@@ -113,9 +116,23 @@
            ),
         )
 
+    def supportedReports(self):
+        result = super(DirectoryBackedAddressBookResource, self).supportedReports()
+        if config.EnableSyncReport:
+            # Not supported on the directory backed address book
+            result.remove(davxml.Report(SyncCollection(),))
+        return result
+
     def resourceType(self):
         return davxml.ResourceType.directory
 
+    def resourceID(self):
+        if self.directory:
+            resource_id = uuid.uuid5(uuid.UUID("5AAD67BF-86DD-42D7-9161-6AF977E4DAA3"), self.directory.baseGUID).urn
+        else:
+            resource_id = "tag:unknown"
+        return resource_id
+
     def isDirectoryBackedAddressBookCollection(self):
         return True
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/mail.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/mail.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/mail.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -360,7 +360,7 @@
 
     data = str(calendar)
 
-    if config.SSLPort:
+    if config.EnableSSL:
         useSSL = True
         port = config.SSLPort
     else:
@@ -597,7 +597,7 @@
 
         rootResource = getRootResource(config,
             (
-                ("inbox", IMIPInvitationInboxResource, (mailer,), "basic"),
+                ("inbox", IMIPInvitationInboxResource, (mailer,), "digest"),
             )
         )
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/method/report_sync_collection.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/method/report_sync_collection.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/method/report_sync_collection.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -106,7 +106,7 @@
     # the child resource loop and supply those to the checkPrivileges on each child.
     filteredaces = (yield self.inheritedACEsforChildren(request))
 
-    changed, removed, newtoken = yield self.whatchanged(sync_collection.sync_token, depth)
+    changed, removed, notallowed, newtoken = yield self.whatchanged(sync_collection.sync_token, depth)
 
     # Now determine which valid resources are readable and which are not
     ok_resources = []
@@ -146,6 +146,10 @@
         href = davxml.HRef.fromString(joinURL(request.uri, name))
         responses.append(davxml.StatusResponse(davxml.HRef.fromString(href), davxml.Status.fromResponseCode(responsecode.NOT_FOUND)))
     
+    for name in notallowed:
+        href = davxml.HRef.fromString(joinURL(request.uri, name))
+        responses.append(davxml.StatusResponse(davxml.HRef.fromString(href), davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
+    
     if not hasattr(request, "extendedLogItems"):
         request.extendedLogItems = {}
     request.extendedLogItems["responses"] = len(responses)

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/notify.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/notify.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/notify.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -80,30 +80,7 @@
     "getXMPPSettings",
 ]
 
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-# FIXME:
-# Temporarily ignore digest auth as it's broken for local accounts
-
-NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl'
-
-from twisted.words.protocols.jabber import sasl
-def get_mechanisms(xs):
-    """
-    Parse the SASL feature to extract the available mechanism names.
-    """
-    mechanisms = []
-    for element in xs.features[(NS_XMPP_SASL, 'mechanisms')].elements():
-        if element.name == 'mechanism':
-            mechanism = str(element)
-            if mechanism != "DIGEST-MD5":
-                mechanisms.append(str(element))
-
-    return mechanisms
-
-sasl.get_mechanisms = get_mechanisms
-
-
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Classes used within calendarserver itself
 #

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/resource.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/resource.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -76,8 +76,9 @@
 from twistedcaldav.ical import allowedComponents
 from twistedcaldav.icaldav import ICalDAVResource, ICalendarPrincipalResource
 from twistedcaldav.linkresource import LinkResource
-from twistedcaldav.notify import getPubSubConfiguration, getPubSubPath,\
-    getPubSubXMPPURI, getPubSubHeartbeatURI, getPubSubAPSConfiguration
+from twistedcaldav.notify import (getPubSubConfiguration, getPubSubPath,
+    getPubSubXMPPURI, getPubSubHeartbeatURI, getPubSubAPSConfiguration,
+    getNodeCacher)
 from twistedcaldav.sharing import SharedCollectionMixin, SharedHomeMixin
 from twistedcaldav.vcard import Component as vComponent
 
@@ -1339,11 +1340,11 @@
             revision = 0
 
         try:
-            changed, removed = yield self._indexWhatChanged(revision, depth)
+            changed, removed, notallowed = yield self._indexWhatChanged(revision, depth)
         except SyncTokenValidException:
             raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "valid-sync-token")))
 
-        returnValue((changed, removed, current_token))
+        returnValue((changed, removed, notallowed, current_token))
 
     def _indexWhatChanged(self, revision, depth):
         # Now handled directly by newstore
@@ -2056,8 +2057,8 @@
         """
         Always get quota root value from config.
 
-        @return: a C{int} containing the maximum allowed bytes if this collection
-            is quota-controlled, or C{None} if not quota controlled.
+        @return: a C{int} containing the maximum allowed bytes if this
+            collection is quota-controlled, or C{None} if not quota controlled.
         """
         return config.UserQuota if config.UserQuota != 0 else None
 
@@ -2068,14 +2069,17 @@
             result.append(davxml.Report(SyncCollection(),))
         return result
 
-    def _indexWhatChanged(self, revision, depth):
-        # The newstore implementation supports this directly
-        return self._newStoreHome.resourceNamesSinceToken(revision, depth)
+    def _mergeSyncTokens(self, hometoken, notificationtoken):
+        """
+        Merge two sync tokens, choosing the higher revision number of the two,
+        but keeping the home resource-id intact.
+        """
+        homekey, homerev = hometoken.split("#", 1)
+        notrev = notificationtoken.split("#", 1)[1]
+        if int(notrev) > int(homerev):
+            hometoken = "%s#%s" % (homekey, notrev,)
+        return hometoken
 
-    def getSyncToken(self):
-        # The newstore implementation supports this directly
-        return self._newStoreHome.syncToken()
-
     def canShare(self):
         raise NotImplementedError
 
@@ -2123,6 +2127,7 @@
         self.propagateTransaction(similar)
         returnValue(similar)
 
+
     def makeRegularChild(self, name):
         raise NotImplementedError
 
@@ -2139,6 +2144,7 @@
         returnValue(children)
 
 
+    @inlineCallbacks
     def readProperty(self, property, request):
         if type(property) is tuple:
             qname = property
@@ -2180,35 +2186,54 @@
                         )
                     )
 
-                return succeed(customxml.PubSubPushTransportsProperty(*children))
+                returnValue(customxml.PubSubPushTransportsProperty(*children))
 
 
             else:
-                return succeed(customxml.PubSubPushTransportsProperty())
+                returnValue(customxml.PubSubPushTransportsProperty())
 
         if qname == (customxml.calendarserver_namespace, "pushkey"):
             notifierID = self._newStoreHome.notifierID()
             if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
                 pubSubConfiguration = getPubSubConfiguration(config)
                 nodeName = getPubSubPath(notifierID, pubSubConfiguration)
-                return succeed(customxml.PubSubXMPPPushKeyProperty(nodeName))
+
+                # Create the pubsub node so client has something to subscribe
+                # to
+                try:
+                    (yield getNodeCacher().waitForNode(
+                        self._newStoreHome._notifier, nodeName))
+                except NodeCreationException, e:
+                    self.log_warn(e)
+
+                returnValue(customxml.PubSubXMPPPushKeyProperty(nodeName))
             else:
-                return succeed(customxml.PubSubXMPPPushKeyProperty())
+                returnValue(customxml.PubSubXMPPPushKeyProperty())
 
 
         if qname == (customxml.calendarserver_namespace, "xmpp-uri"):
             notifierID = self._newStoreHome.notifierID()
             if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
                 pubSubConfiguration = getPubSubConfiguration(config)
-                return succeed(customxml.PubSubXMPPURIProperty(
+
+                # Create the pubsub node so client has something to subscribe
+                # to
+                nodeName = getPubSubPath(notifierID, pubSubConfiguration)
+                try:
+                    (yield getNodeCacher().waitForNode(
+                        self._newStoreHome._notifier, nodeName))
+                except NodeCreationException, e:
+                    self.log_warn(e)
+
+                returnValue(customxml.PubSubXMPPURIProperty(
                     getPubSubXMPPURI(notifierID, pubSubConfiguration)))
             else:
-                return succeed(customxml.PubSubXMPPURIProperty())
+                returnValue(customxml.PubSubXMPPURIProperty())
 
         elif qname == (customxml.calendarserver_namespace, "xmpp-heartbeat-uri"):
             pubSubConfiguration = getPubSubConfiguration(config)
             if pubSubConfiguration['enabled']:
-                return succeed(
+                returnValue(
                     customxml.PubSubHeartbeatProperty(
                         customxml.PubSubHeartbeatURIProperty(
                             getPubSubHeartbeatURI(pubSubConfiguration)
@@ -2219,17 +2244,17 @@
                     )
                 )
             else:
-                return succeed(customxml.PubSubHeartbeatURIProperty())
+                returnValue(customxml.PubSubHeartbeatURIProperty())
 
         elif qname == (customxml.calendarserver_namespace, "xmpp-server"):
             pubSubConfiguration = getPubSubConfiguration(config)
             if pubSubConfiguration['enabled']:
-                return succeed(customxml.PubSubXMPPServerProperty(
+                returnValue(customxml.PubSubXMPPServerProperty(
                     pubSubConfiguration['xmpp-server']))
             else:
-                return succeed(customxml.PubSubXMPPServerProperty())
+                returnValue(customxml.PubSubXMPPServerProperty())
 
-        return super(CommonHomeResource, self).readProperty(property, request)
+        returnValue((yield super(CommonHomeResource, self).readProperty(property, request)))
 
     ##
     # ACL
@@ -2411,6 +2436,55 @@
 
         return davxml.ACL(*aces)
 
+
+    @inlineCallbacks
+    def getSyncToken(self):
+        # The newstore implementation supports this directly
+        caltoken = yield self._newStoreHome.syncToken()
+
+        if config.Sharing.Enabled and config.Sharing.Calendars.Enabled:
+            notificationtoken = yield (yield self.getChild("notification")).getSyncToken()
+
+            # Merge tokens
+            caltoken = self._mergeSyncTokens(caltoken, notificationtoken)
+
+        returnValue(caltoken)
+
+
+    @inlineCallbacks
+    def _indexWhatChanged(self, revision, depth):
+        # The newstore implementation supports this directly
+        changed, deleted = yield self._newStoreHome.resourceNamesSinceToken(
+            revision, depth
+        )
+        notallowed = []
+
+        # Need to insert some addition items on first sync
+        if revision == 0:
+            changed.append("outbox/")
+
+            if config.FreeBusyURL.Enabled:
+                changed.append("freebusy")
+
+            if config.Sharing.Enabled and config.Sharing.Calendars.Enabled:
+                changed.append("notification/")
+
+            # Dropbox is never synchronized
+            if config.EnableDropBox:
+                notallowed.append("dropbox/")
+
+        # Add in notification changes
+        if config.Sharing.Enabled and config.Sharing.Calendars.Enabled:
+            noti_changed, noti_deleted, noti_notallowed = yield (yield self.getChild("notification"))._indexWhatChanged(revision, depth)
+
+            changed.extend([joinURL("notification", name) for name in noti_changed])
+            deleted.extend([joinURL("notification", name) for name in noti_deleted])
+            notallowed.extend([joinURL("notification", name) for name in noti_notallowed])
+
+        returnValue((changed, deleted, notallowed))
+
+
+
 class AddressBookHomeResource (CommonHomeResource):
     """
     Address book home collection resource.
@@ -2478,6 +2552,48 @@
         returnValue(similar)
 
 
+    @inlineCallbacks
+    def getSyncToken(self):
+        # The newstore implementation supports this directly
+        adbktoken = yield self._newStoreHome.syncToken()
+
+        if config.Sharing.Enabled and config.Sharing.AddressBooks.Enabled and not config.Sharing.Calendars.Enabled:
+            notifcationtoken = yield (yield self.getChild("notification")).getSyncToken()
+            
+            # Merge tokens
+            adbkkey, adbkrev = adbktoken.split("#", 1)
+            notrev = notifcationtoken.split("#", 1)[1]
+            if int(notrev) > int(adbkrev):
+                adbktoken = "%s#%s" % (adbkkey, notrev,)
+
+        returnValue(adbktoken)
+
+
+    @inlineCallbacks
+    def _indexWhatChanged(self, revision, depth):
+        # The newstore implementation supports this directly
+        changed, deleted = yield self._newStoreHome.resourceNamesSinceToken(
+            revision, depth
+        )
+        notallowed = []
+
+        # Need to insert some addition items on first sync
+        if revision == 0:
+            if config.Sharing.Enabled and config.Sharing.AddressBooks.Enabled and not config.Sharing.Calendars.Enabled:
+                changed.append("notification/")
+
+        # Add in notification changes
+        if config.Sharing.Enabled and config.Sharing.AddressBooks.Enabled and not config.Sharing.Calendars.Enabled:
+            noti_changed, noti_deleted, noti_notallowed = yield (yield self.getChild("notification"))._indexWhatChanged(revision, depth)
+
+            changed.extend([joinURL("notification", name) for name in noti_changed])
+            deleted.extend([joinURL("notification", name) for name in noti_deleted])
+            notallowed.extend([joinURL("notification", name) for name in noti_notallowed])
+
+        returnValue((changed, deleted, notallowed))
+
+
+
 class GlobalAddressBookResource (ReadOnlyResourceMixIn, CalDAVResource):
     """
     Global address book. All we care about is making sure permissions are setup.

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/implicit.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/implicit.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -19,7 +19,6 @@
 
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twext.web2 import responsecode
-from twext.web2.dav import davxml
 from twext.web2.dav.util import joinURL
 from twext.web2.dav.util import parentForURL
 from twext.web2.http import HTTPError
@@ -330,29 +329,23 @@
     @inlineCallbacks
     def extractCalendarData(self):
         
-        # Get the originator who is the authenticated user
-        # TODO: the originator actually needs to be the owner of the calendar collection not the authenticated
-        # principal, who might be a proxy or admin
+        # Get the originator who is the owner of the calendar resource being modified
         self.originatorPrincipal = None
         self.originator = ""
-        authz_principal = self.resource.currentPrincipal(self.request).children[0]
-        if isinstance(authz_principal, davxml.HRef):
-            originatorPrincipalURL = str(authz_principal)
-            if originatorPrincipalURL:
-                self.originatorPrincipal = (yield self.request.locateResource(originatorPrincipalURL))
-                if not isinstance(self.originatorPrincipal, DirectoryCalendarPrincipalResource):
-                    log.error("Originator '%s' is not enabled for calendaring" % (originatorPrincipalURL,))
-                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "invalid-originator")))
+        if self.resource:
+            self.originatorPrincipal = (yield self.resource.ownerPrincipal(self.request))
+            if not isinstance(self.originatorPrincipal, DirectoryCalendarPrincipalResource):
+                log.error("Originator '%s' is not enabled for calendaring" % (self.originatorPrincipal,))
+                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "invalid-originator")))
+    
+            # Pick the first mailto cu address or the first other type
+            for item in self.originatorPrincipal.calendarUserAddresses():
+                if not self.originator:
+                    self.originator = item
+                if item.startswith("mailto:"):
+                    self.originator = item
+                    break
 
-                if self.originatorPrincipal:
-                    # Pick the first mailto cu address or the first other type
-                    for item in self.originatorPrincipal.calendarUserAddresses():
-                        if not self.originator:
-                            self.originator = item
-                        if item.startswith("mailto:"):
-                            self.originator = item
-                            break
-
         # Get the ORGANIZER and verify it is the same for all components
         try:
             self.organizer = self.calendar.validOrganizerForScheduling()

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/processing.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/processing.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -444,7 +444,12 @@
             # Just try again to get the lock
             reactor.callLater(2.0, self.sendAttendeeAutoReply, *(calendar, resource, partstat))
         else:
+            # inNewTransaction wipes out the remembered resource<-> URL mappings in the
+            # request object but we need to be able to map the actual reply resource to its
+            # URL when doing auto-processing, so we have to sneak that mapping back in here.
             txn = yield resource.inNewTransaction(self.request)
+            self.request._rememberResource(resource, resource._url)
+
             try:
                 # Send out a reply
                 log.debug("ImplicitProcessing - recipient '%s' processing UID: '%s' - auto-reply: %s" % (self.recipient.cuaddr, self.uid, partstat))
@@ -632,6 +637,7 @@
         # Get a resource for the new item
         newchildURL = joinURL(collURL, name)
         newchild = yield self.request.locateResource(newchildURL)
+        newchild._url = newchildURL
         
         # Now write it to the resource
         from twistedcaldav.method.put_common import StoreCalendarObjectResource

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/scheduler.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/scheduler.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -506,14 +506,6 @@
             if inboxURL is None:
                 log.err("Could not find inbox for originator: %s" % (self.originator,))
                 raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "originator-allowed")))
-        
-            # Verify that Originator matches the authenticated user, but not if this is a server
-            # generated request
-            if not self.internal_request:
-                authn_principal = self.resource.currentPrincipal(self.request)
-                if davxml.Principal(davxml.HRef(originatorPrincipal.principalURL())) != authn_principal:
-                    log.err("Originator: %s does not match authorized user: %s" % (self.originator, authn_principal.children[0],))
-                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "originator-allowed")))
 
             self.originator = LocalCalendarUser(self.originator, originatorPrincipal)
 

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/test/test_implicit.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/test/test_implicit.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/scheduling/test/test_implicit.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -18,7 +18,6 @@
 import twistedcaldav.test.util
 from twistedcaldav.scheduling.implicit import ImplicitScheduler
 from dateutil.tz import tzutc
-from twext.web2.dav import davxml
 import datetime
 
 class Implicit (twistedcaldav.test.util.TestCase):
@@ -747,15 +746,9 @@
             ),
         )
 
-        class TestResource(object):
-            def currentPrincipal(self, request):
-                return davxml.Principal(davxml.Unauthenticated)
-
-        resource = TestResource()
-
         for description, calendar1, calendar2, result in data:
             scheduler = ImplicitScheduler()
-            scheduler.resource = resource
+            scheduler.resource = None
             scheduler.request = None
             scheduler.oldcalendar = Component.fromString(calendar1)
             scheduler.calendar = Component.fromString(calendar2)

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/stdconfig.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/stdconfig.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -982,6 +982,8 @@
 
 def _updateCompliance(configDict):
 
+    if not (configDict.EnableCalDAV or configDict.EnableCardDAV):
+        log.warn("Neither 'EnableCalDAV' nor 'EnableCardDAV' are set to True")
 
     if configDict.EnableCalDAV:
         if configDict.Scheduling.CalDAV.OldDraftCompatibility:

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/storebridge.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/twistedcaldav/storebridge.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -246,15 +246,21 @@
             self._invitesDB = self._newStoreCalendar.retrieveOldInvites()
         return self._invitesDB
 
+
     def exists(self):
         # FIXME: tests
         return True
 
 
+    @inlineCallbacks
     def _indexWhatChanged(self, revision, depth):
         # The newstore implementation supports this directly
-        return self._newStoreCalendar.resourceNamesSinceToken(revision)
+        returnValue(
+            (yield self._newStoreCalendar.resourceNamesSinceToken(revision))
+            + ([],)
+        )
 
+
     @classmethod
     def transform(cls, self, calendar, home):
         """
@@ -448,6 +454,8 @@
     def isCollection(self):
         return False
 
+    def exists(self):
+        return False
 
     def http_GET(self, request):
         return NOT_FOUND
@@ -551,7 +559,8 @@
     def accessControlList(self, *a, **kw):
         """
         All principals identified as ATTENDEEs on the event for this dropbox
-        may read all its children. Also include proxies of ATTENDEEs.
+        may read all its children. Also include proxies of ATTENDEEs. Ignore
+        unknown attendees.
         """
         originalACL = yield super(
             CalendarObjectDropbox, self).accessControlList(*a, **kw)
@@ -565,6 +574,9 @@
             principal = self.principalForCalendarUserAddress(
                 calendarUserAddress
             )
+            if principal is None:
+                continue
+
             principalURL = principal.principalURL()
             writePrivileges = [
                 davxml.Privilege(davxml.Read()),
@@ -1373,15 +1385,21 @@
             self._invitesDB = self._newStoreAddressBook.retrieveOldInvites()
         return self._invitesDB
 
+
     def exists(self):
         # FIXME: tests
         return True
 
 
+    @inlineCallbacks
     def _indexWhatChanged(self, revision, depth):
         # The newstore implementation supports this directly
-        return self._newStoreAddressBook.resourceNamesSinceToken(revision)
+        returnValue(
+            (yield self._newStoreAddressBook.resourceNamesSinceToken(revision))
+            + ([],)
+        )
 
+
     @classmethod
     def transform(cls, self, addressbook, home):
         """
@@ -1978,6 +1996,9 @@
         self._initializeWithNotifications(notifications, home)
 
 
+    def name(self):
+        return "notification"
+
     @inlineCallbacks
     def listChildren(self):
         l = []
@@ -1988,11 +2009,18 @@
     def isCollection(self):
         return True
 
+
     def getSyncToken(self):
         return self._newStoreNotifications.syncToken()
 
+
+    @inlineCallbacks
     def _indexWhatChanged(self, revision, depth):
-        return self._newStoreNotifications.resourceNamesSinceToken(revision)
+        # The newstore implementation supports this directly
+        returnValue(
+            (yield self._newStoreNotifications.resourceNamesSinceToken(revision))
+            + ([],)
+        )
 
 
     def addNotification(self, request, uid, xmltype, xmldata):

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/base/datastore/subpostgres.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/txdav/base/datastore/subpostgres.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/txdav/base/datastore/subpostgres.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -257,6 +257,13 @@
         self.dataStoreDirectory = dataStoreDirectory
         self.resetSchema = resetSchema
 
+        # In order to delay a shutdown until database initialization has
+        # completed, our stopService( ) examines the delayedShutdown flag.
+        # If True, we wait on the shutdownDeferred to fire before proceeding.
+        # The deferred gets fired once database init is complete.
+        self.delayedShutdown = False # set to True when in critical code
+        self.shutdownDeferred = None # the actual deferred
+
         # Options from config
         self.databaseName = databaseName
         self.logFile = logFile
@@ -283,7 +290,26 @@
         self.monitor = None
         self.openConnections = []
 
+    def activateDelayedShutdown(self):
+        """
+        Call this when starting database initialization code to protect against
+        shutdown.
 
+        Sets the delayedShutdown flag to True so that if reactor shutdown
+        commences, the shutdown will be delayed until deactivateDelayedShutdown
+        is called.
+        """
+        self.delayedShutdown = True
+
+    def deactivateDelayedShutdown(self):
+        """
+        Call this when database initialization code has completed so that the
+        reactor can shutdown.
+        """
+        self.delayedShutdown = False
+        if self.shutdownDeferred:
+            self.shutdownDeferred.callback(None)
+
     def produceConnection(self, label="<unlabeled>", databaseName=None):
         """
         Produce a DB-API 2.0 connection pointed at this database.
@@ -339,7 +365,7 @@
 
         try:
             createDatabaseCursor.execute(
-                "create database %s" % (self.databaseName)
+                "create database %s with encoding 'UTF8'" % (self.databaseName)
             )
         except:
             execSchema = False
@@ -359,9 +385,10 @@
         connection = self.produceConnection()
         cursor = connection.cursor()
 
-        self.subServiceFactory(self.produceConnection).setServiceParent(self)
+        if self.shutdownDeferred is None:
+            # Only continue startup if we've not begun shutdown
+            self.subServiceFactory(self.produceConnection).setServiceParent(self)
 
-
     def pauseMonitor(self):
         """
         Pause monitoring.  This is a testing hook for when (if) we are
@@ -418,14 +445,17 @@
         self.monitor = monitor
         def gotReady(result):
             self.ready()
+            self.deactivateDelayedShutdown()
         def reportit(f):
             log.err(f)
+            self.deactivateDelayedShutdown()
         self.monitor.completionDeferred.addCallback(
             gotReady).addErrback(reportit)
 
 
     def startService(self):
         MultiService.startService(self)
+        self.activateDelayedShutdown()
         clusterDir = self.dataStoreDirectory.child("cluster")
         workingDir = self.dataStoreDirectory.child("working")
         env = self.env = os.environ.copy()
@@ -450,7 +480,7 @@
             dbInited = Deferred()
             reactor.spawnProcess(
                 CapturingProcessProtocol(dbInited, None),
-                initdb, [initdb], env, workingDir.path,
+                initdb, [initdb, "-E", "UTF8"], env, workingDir.path,
                 uid=self.uid, gid=self.gid,
             )
             def doCreate(result):
@@ -462,10 +492,16 @@
         """
         Stop all child services, then stop the subprocess, if it's running.
         """
-        d = MultiService.stopService(self)
+
+        if self.delayedShutdown:
+            # We're still in the process of initializing the database, so
+            # delay shutdown until the shutdownDeferred fires.
+            d = self.shutdownDeferred = Deferred()
+            d.addCallback(lambda ignored: MultiService.stopService(self))
+        else:
+            d = MultiService.stopService(self)
+
         def superStopped(result):
-            # Probably want to stop and wait for startup if that hasn't
-            # completed yet...
             monitor = _PostgresMonitor()
             pg_ctl = which("pg_ctl")[0]
             reactor.spawnProcess(monitor, pg_ctl,


Property changes on: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394
/CalendarServer/trunk/txdav/caldav/datastore/index_file.py:6369-6396
   + /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394
/CalendarServer/trunk/txdav/caldav/datastore/index_file.py:6369-6432


Property changes on: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394
/CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py:6369-6396
   + /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394
/CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py:6369-6432


Property changes on: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394
/CalendarServer/trunk/txdav/carddav/datastore/index_file.py:6369-6396
   + /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394
/CalendarServer/trunk/txdav/carddav/datastore/index_file.py:6369-6432


Property changes on: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
/CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py:6369-6396
   + /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6368
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
/CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py:6369-6432

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -439,6 +439,7 @@
         self._resourceID = resourceID
         self._shares = None
         self._children = {}
+        self._sharedChildren = {}
         self._notifier = notifier
 
         # Needed for REVISION/BIND table join
@@ -487,28 +488,58 @@
         returnValue(x)
 
 
-    @inlineCallbacks
     def listChildren(self):
         """
         Retrieve the names of the children in this home.
 
         @return: an iterable of C{str}s.
         """
+        return self._listChildren(owned=True)
+
+
+    def listSharedChildren(self):
+        """
+        Retrieve the names of the children in this home.
+
+        @return: an iterable of C{str}s.
+        """
+        return self._listChildren(owned=False)
+
+
+    @inlineCallbacks
+    def _listChildren(self, owned):
+        """
+        Retrieve the names of the children in this home.
+
+        @return: an iterable of C{str}s.
+        """
         # FIXME: not specified on the interface or exercised by the tests, but
         # required by clients of the implementation!
-        rows = yield self._txn.execSQL(
-            "select %(column_RESOURCE_NAME)s from %(name)s where "
-            "%(column_HOME_RESOURCE_ID)s = %%s "
-            "and %(column_BIND_MODE)s = %%s " % self._bindTable,
-            # Right now, we only show owned calendars.
-            [self._resourceID, _BIND_MODE_OWN]
-        )
+        if owned:
+            rows = yield self._txn.execSQL("""
+                select %(column_RESOURCE_NAME)s from %(name)s
+                where
+                  %(column_HOME_RESOURCE_ID)s = %%s and
+                  %(column_BIND_MODE)s = %%s
+                """ % self._bindTable,
+                [self._resourceID, _BIND_MODE_OWN]
+            )
+        else:
+            rows = yield self._txn.execSQL("""
+                select %(column_RESOURCE_NAME)s from %(name)s
+                where
+                  %(column_HOME_RESOURCE_ID)s = %%s and
+                  %(column_BIND_MODE)s != %%s and
+                  %(column_RESOURCE_NAME)s is not null
+                """ % self._bindTable,
+                [self._resourceID, _BIND_MODE_OWN]
+            )
+
         names = [row[0] for row in rows]
         returnValue(names)
 
 
     @memoized('name', '_children')
-    @inlineCallbacks
     def childWithName(self, name):
         """
         Retrieve the child with the given C{name} contained in this
@@ -517,12 +548,67 @@
         @param name: a string.
         @return: an L{ICalendar} or C{None} if no such child exists.
         """
-        data = yield self._txn.execSQL(
-            "select %(column_RESOURCE_ID)s from %(name)s where "
-            "%(column_RESOURCE_NAME)s = %%s and %(column_HOME_RESOURCE_ID)s = %%s "
-            "and %(column_BIND_MODE)s = %%s" % self._bindTable,
-            [name, self._resourceID, _BIND_MODE_OWN]
-        )
+        return self._childWithName(name, owned=True)
+
+    @memoized('name', '_sharedChildren')
+    def sharedChildWithName(self, name):
+        """
+        Retrieve the shared child with the given C{name} contained in this
+        home. Return a child object with this home and the name.
+
+        IMPORTANT: take care when using this. Shared calendars should normally
+        be accessed through the owner home collection, not the sharee home collection.
+        The only reason for access through sharee home is to do some housekeeping
+        for maintaining the revisions database to show shared calendars appearing and
+        disappearing in the sharee home.
+
+        @param name: a string.
+        @return: an L{ICalendar} or C{None} if no such child
+            exists.
+        """
+        return self._childWithName(name, owned=False)
+
+
+    @inlineCallbacks
+    def _childWithName(self, name, owned):
+        """
+        Retrieve the child with the given C{name} contained in this
+        home.
+
+        @param name: a string.
+        @return: an L{ICalendar} or C{None} if no such child
+            exists.
+        """
+        
+        if owned:
+            data = yield self._txn.execSQL("""
+                select %(column_RESOURCE_ID)s from %(name)s
+                where
+                  %(column_RESOURCE_NAME)s = %%s and
+                  %(column_HOME_RESOURCE_ID)s = %%s and
+                  %(column_BIND_MODE)s = %%s
+                """ % self._bindTable,
+                [
+                    name,
+                    self._resourceID,
+                    _BIND_MODE_OWN
+                ]
+            )
+        else:
+            data = yield self._txn.execSQL("""
+                select %(column_RESOURCE_ID)s from %(name)s
+                where
+                  %(column_RESOURCE_NAME)s = %%s and
+                  %(column_HOME_RESOURCE_ID)s = %%s and
+                  %(column_BIND_MODE)s != %%s
+                """ % self._bindTable,
+                [
+                    name,
+                    self._resourceID,
+                    _BIND_MODE_OWN
+                ]
+            )
+
         if not data:
             returnValue(None)
         resourceID = data[0][0]
@@ -604,35 +690,48 @@
     def syncToken(self):
         revision = (yield self._txn.execSQL(
             """
-            select max(%(column_REVISION)s) from %(name)s
-            where %(column_HOME_RESOURCE_ID)s = %%s
-            """ % self._revisionsTable,
-            [self._resourceID,]
+            select max(%(REV:column_REVISION)s) from %(REV:name)s
+            where %(REV:column_RESOURCE_ID)s in (
+              select %(BIND:column_RESOURCE_ID)s from %(BIND:name)s 
+              where %(BIND:column_HOME_RESOURCE_ID)s = %%s
+            ) or (
+              %(REV:column_HOME_RESOURCE_ID)s = %%s and
+              %(REV:column_RESOURCE_ID)s is null
+            )
+            """ % self._revisionBindJoinTable,
+            [self._resourceID, self._resourceID,]
         ))[0][0]
         returnValue("%s#%s" % (self._resourceID, revision))
 
 
     @inlineCallbacks
     def resourceNamesSinceToken(self, token, depth):
+
         results = [
             (
                 path if path else (collection if collection else ""),
                 name if name else "",
-                deleted
+                wasdeleted
             )
-            for path, collection, name, deleted in
+            for path, collection, name, wasdeleted in
             (yield self._txn.execSQL("""
                 select %(BIND:column_RESOURCE_NAME)s, %(REV:column_COLLECTION_NAME)s, %(REV:column_RESOURCE_NAME)s, %(REV:column_DELETED)s
                 from %(REV:name)s
-                left outer join %(BIND:name)s on (%(REV:name)s.%(REV:column_RESOURCE_ID)s = %(BIND:name)s.%(BIND:column_RESOURCE_ID)s)
-                where %(REV:column_REVISION)s > %%s and %(REV:name)s.%(REV:column_HOME_RESOURCE_ID)s = %%s
+                left outer join %(BIND:name)s on (
+                  %(BIND:name)s.%(BIND:column_HOME_RESOURCE_ID)s = %%s and
+                  %(REV:name)s.%(REV:column_RESOURCE_ID)s = %(BIND:name)s.%(BIND:column_RESOURCE_ID)s
+                )
+                where 
+                  %(REV:column_REVISION)s > %%s and 
+                  %(REV:name)s.%(REV:column_HOME_RESOURCE_ID)s = %%s
                 """ % self._revisionBindJoinTable,
-                [token, self._resourceID],
+                [self._resourceID, token, self._resourceID],
             ))
         ]
         
         deleted = []
         deleted_collections = set()
+        changed_collections = set()
         for path, name, wasdeleted in results:
             if wasdeleted:
                 if token:
@@ -644,7 +743,51 @@
         for path, name, wasdeleted in results:
             if path not in deleted_collections:
                 changed.append("%s/%s" % (path, name,))
+                if not name:
+                    changed_collections.add(path)
         
+        # Now deal with shared collections
+        shares = yield self.listSharedChildren()
+        for sharename in shares:
+            sharetoken = 0 if sharename in changed_collections else token
+            shareID = (yield self._txn.execSQL("""
+                select %(column_RESOURCE_ID)s from %(name)s
+                where
+                  %(column_RESOURCE_NAME)s = %%s and
+                  %(column_HOME_RESOURCE_ID)s = %%s and
+                  %(column_BIND_MODE)s != %%s
+                """ % self._bindTable,
+                [
+                    sharename,
+                    self._resourceID,
+                    _BIND_MODE_OWN
+                ]
+            ))[0][0]
+            results = [
+                (
+                    sharename,
+                    name if name else "",
+                    wasdeleted
+                )
+                for name, wasdeleted in
+                (yield self._txn.execSQL("""
+                    select %(column_RESOURCE_NAME)s, %(column_DELETED)s
+                    from %(name)s
+                    where %(column_REVISION)s > %%s and %(column_RESOURCE_ID)s = %%s
+                    """ % self._revisionsTable,
+                    [sharetoken, shareID],
+                )) if name
+            ]
+
+            for path, name, wasdeleted in results:
+                if wasdeleted:
+                    if sharetoken:
+                        deleted.append("%s/%s" % (path, name,))
+            
+            for path, name, wasdeleted in results:
+                changed.append("%s/%s" % (path, name,))
+        
+        
         changed.sort()
         deleted.sort()
         returnValue((changed, deleted))
@@ -898,11 +1041,19 @@
     def syncToken(self):
         revision = (yield self._txn.execSQL(
             """
-            select %(column_REVISION)s from %(name)s
-            where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
+            select max(%(column_REVISION)s) from %(name)s
+            where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is not null
             """ % self._revisionsTable,
             [self._resourceID,]
         ))[0][0]
+        if revision is None:
+            revision = (yield self._txn.execSQL(
+                """
+                select %(column_REVISION)s from %(name)s
+                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
+                """ % self._revisionsTable,
+                [self._resourceID,]
+            ))[0][0]
         returnValue(("%s#%s" % (self._resourceID, revision,)))
 
 
@@ -993,7 +1144,8 @@
             [self._home._resourceID, self._resourceID,]
         )
 
-        # Then adjust collection entry to deleted state
+        # Then adjust collection entry to deleted state (do this for all entries with this collection's
+        # resource-id so that we deal with direct shares which are not normally removed thorugh an unshare
         yield self._txn.execSQL("""
             update %(name)s
             set (%(column_RESOURCE_ID)s, %(column_REVISION)s, %(column_DELETED)s)
@@ -1030,28 +1182,14 @@
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
+        elif action == "update":
             yield self._txn.execSQL("""
                 update %(name)s
                 set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID,]
-            )
-        elif action == "update":
-            yield self._txn.execSQL("""
-              ;  update %(name)s
-                set (%(column_REVISION)s) = (%%s)
                 where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
-            yield self._txn.execSQL("""
-                update %(name)s
-                set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID,]
-            )
         elif action == "insert":
             # Note that an "insert" may happen for a resource that previously existed and then
             # was deleted. In that case an entry in the REVISIONS table still exists so we have to
@@ -1079,13 +1217,6 @@
                     """ % self._revisionsTable,
                     [self._home._resourceID, self._resourceID, name, nextrevision]
                 )
-            yield self._txn.execSQL("""
-                update %(name)s
-                set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID,]
-            )
 
 
     @inlineCallbacks
@@ -1427,11 +1558,20 @@
     def syncToken(self):
         revision = (yield self._txn.execSQL(
             """
-            select %(column_REVISION)s from %(name)s
-            where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
+            select max(%(column_REVISION)s) from %(name)s
+            where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is not null
             """ % self._revisionsTable,
             [self._resourceID,]
         ))[0][0]
+
+        if revision is None:
+            revision = (yield self._txn.execSQL(
+                """
+                select %(column_REVISION)s from %(name)s
+                where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
+                """ % self._revisionsTable,
+                [self._resourceID,]
+            ))[0][0]
         returnValue("%s#%s" % (self._resourceID, revision,))
 
 
@@ -1511,13 +1651,6 @@
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
-            yield self._txn.execSQL("""
-                update %(name)s
-                set (%(column_REVISION)s) = (%%s)
-                where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID]
-            )
         elif action == "update":
             yield self._txn.execSQL("""
                 update %(name)s
@@ -1526,13 +1659,6 @@
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
-            yield self._txn.execSQL("""
-                update %(name)s
-                set (%(column_REVISION)s) = (%%s)
-                where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID]
-            )
         elif action == "insert":
             # Note that an "insert" may happen for a resource that previously existed and then
             # was deleted. In that case an entry in the REVISIONS table still exists so we have to
@@ -1560,13 +1686,6 @@
                     """ % self._revisionsTable,
                     [self._resourceID, name, nextrevision]
                 )
-            yield self._txn.execSQL("""
-                update %(name)s
-                set (%(column_REVISION)s) = (%%s)
-                where %(column_HOME_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s is null
-                """ % self._revisionsTable,
-                [nextrevision, self._resourceID]
-            )
 
 
     def properties(self):

Modified: CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql_legacy.py
===================================================================
--- CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql_legacy.py	2010-10-17 12:25:04 UTC (rev 6432)
+++ CalendarServer/branches/users/glyph/more-deferreds-7/txdav/common/datastore/sql_legacy.py	2010-10-18 04:33:34 UTC (rev 6433)
@@ -44,8 +44,8 @@
     ReservationError
 from txdav.common.datastore.sql_tables import \
     _BIND_MODE_OWN, _BIND_MODE_READ, _BIND_MODE_WRITE, _BIND_MODE_DIRECT, \
-    _BIND_STATUS_INVITED, _BIND_STATUS_ACCEPTED, _BIND_STATUS_DECLINED, _BIND_STATUS_INVALID,\
-    CALENDAR_BIND_TABLE, CALENDAR_HOME_TABLE, ADDRESSBOOK_HOME_TABLE,\
+    _BIND_STATUS_INVITED, _BIND_STATUS_ACCEPTED, _BIND_STATUS_DECLINED, _BIND_STATUS_INVALID, \
+    CALENDAR_BIND_TABLE, CALENDAR_HOME_TABLE, ADDRESSBOOK_HOME_TABLE, \
     ADDRESSBOOK_BIND_TABLE
 
 log = Logger()
@@ -114,9 +114,9 @@
         # Since we do multi-table requests we need a dict that combines tables
         self._combinedTable = {}
         for key, value in self._homeTable.iteritems():
-            self._combinedTable["HOME:%s" % (key,)] = value 
+            self._combinedTable["HOME:%s" % (key,)] = value
         for key, value in self._bindTable.iteritems():
-            self._combinedTable["BIND:%s" % (key,)] = value 
+            self._combinedTable["BIND:%s" % (key,)] = value
 
 
     @property
@@ -571,9 +571,17 @@
                     record.summary,
                 ])
 
+        shareeCollection = yield self._home.sharedChildWithName(record.localname)
+        shareeCollection._initSyncToken()
 
+
+    @inlineCallbacks
     def removeRecordForLocalName(self, localname):
-        return self._txn.execSQL(
+        record = yield self.recordForLocalName(localname)
+        shareeCollection = yield self._home.sharedChildWithName(record.localname)
+        yield shareeCollection._deletedSyncToken()
+
+        returnValue((yield self._txn.execSQL(
             """
             update %(name)s
             set %(column_RESOURCE_NAME)s = NULL
@@ -581,11 +589,16 @@
              and %(column_HOME_RESOURCE_ID)s = %%s
             """ % self._bindTable,
             [localname, self._home._resourceID]
-        )
+        )))
 
 
     @inlineCallbacks
     def removeRecordForShareUID(self, shareUID):
+
+        record = yield self.recordForShareUID(shareUID)
+        shareeCollection = yield self._home.sharedChildWithName(record.localname)
+        yield shareeCollection._deletedSyncToken()
+
         if not shareUID.startswith("Direct"):
             yield self._txn.execSQL(
                 """
@@ -596,12 +609,12 @@
                  and %(name)s.%(column_HOME_RESOURCE_ID)s = INVITE.HOME_RESOURCE_ID
                  and %(name)s.%(column_RESOURCE_ID)s = INVITE.RESOURCE_ID
                 """ % self._bindTable,
-                [shareUID,]
+                [shareUID, ]
             )
         else:
             # Extract pieces from synthesised UID
             homeID, resourceID = shareUID[len("Direct-"):].split("-")
-            
+
             # Now remove the binding for the direct share
             yield self._txn.execSQL(
                 """
@@ -609,7 +622,7 @@
                 where %(column_HOME_RESOURCE_ID)s = %%s
                  and %(column_RESOURCE_ID)s = %%s
                 """ % self._bindTable,
-                [homeID, resourceID,]
+                [homeID, resourceID, ]
             )
 
 
@@ -624,7 +637,7 @@
         self._homeTable = CALENDAR_HOME_TABLE
         self._bindTable = CALENDAR_BIND_TABLE
         self._urlTopSegment = "calendars"
-    
+
         super(SQLLegacyCalendarShares, self).__init__(home)
 
 
@@ -648,8 +661,8 @@
 
     def _getHomeWithUID(self, uid):
         return self._txn.addressbookHomeWithUID(uid, create=True)
-        
 
+
 class MemcachedUIDReserver(CachePoolUserMixIn, LoggingMixIn):
     def __init__(self, index, cachePool=None):
         self.index = index
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101017/e9463b1a/attachment-0001.html>


More information about the calendarserver-changes mailing list