diff --git a/.gitignore b/.gitignore
index e2e1ee9c..aede5fae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -90,3 +90,6 @@ gradle-app.setting
# Javadoc
javadoc/
+
+### VIM ###
+*.swp
diff --git a/.gitmodules b/.gitmodules
index 938ab729..8e635782 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,12 +1,9 @@
-[submodule "dav4android"]
- path = dav4android
- url = ../dav4android.git
[submodule "ical4android"]
path = ical4android
- url = ../ical4android.git
+ url = https://gitlab.com/bitfireAT/ical4android.git
[submodule "vcard4android"]
path = vcard4android
- url = ../vcard4android.git
+ url = https://gitlab.com/bitfireAT/vcard4android.git
[submodule "cert4android"]
path = cert4android
- url = ../cert4android.git
+ url = https://gitlab.com/bitfireAT/cert4android.git
diff --git a/app/build.gradle b/app/build.gradle
index a206c52e..6943a9f4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,11 +32,25 @@ android {
buildTypes {
debug {
- minifyEnabled false
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+
+ /*
+ * To override the server's url (for example when developing),
+ * create file gradle.properties in ~/.gradle/ with this content:
+ *
+ * appDebugRemoteUrl="http://localserver:8080/"
+ */
+ if (project.hasProperty('appDebugRemoteUrl')) {
+ buildConfigField 'String', 'DEBUG_REMOTE_URL', appDebugRemoteUrl
+ } else {
+ buildConfigField 'String', 'DEBUG_REMOTE_URL', 'null'
+ }
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ buildConfigField 'String', 'DEBUG_REMOTE_URL', 'null'
}
}
@@ -55,6 +69,14 @@ android {
disable 'Typos'
disable "RestrictedApi" // https://code.google.com/p/android/issues/detail?id=230387
}
+
+ dexOptions {
+ preDexLibraries = true
+ // dexInProcess requires much RAM, which is not available on all dev systems
+ dexInProcess = false
+ javaMaxHeapSize "2g"
+ }
+
packagingOptions {
exclude 'LICENSE'
exclude 'META-INF/LICENSE.txt'
@@ -68,7 +90,6 @@ android {
dependencies {
compile project(':cert4android')
- compile project(':dav4android')
compile project(':ical4android')
compile project(':vcard4android')
@@ -79,11 +100,10 @@ dependencies {
compile 'com.github.yukuku:ambilwarna:2.0.1'
+ compile group: 'com.madgag.spongycastle', name: 'core', version: '1.54.0.0'
+ compile group: 'com.madgag.spongycastle', name: 'prov', version: '1.54.0.0'
+ compile group: 'com.google.code.gson', name: 'gson', version: '1.7.2'
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
- compile 'commons-io:commons-io:2.5'
- compile 'dnsjava:dnsjava:2.1.7'
- compile 'org.apache.commons:commons-lang3:3.4'
- compile 'org.apache.commons:commons-collections4:4.1'
provided 'org.projectlombok:lombok:1.16.12'
// for tests
diff --git a/app/proguard-rules.txt b/app/proguard-rules.txt
index e3581e46..a38721ee 100644
--- a/app/proguard-rules.txt
+++ b/app/proguard-rules.txt
@@ -30,8 +30,23 @@
-dontwarn java.nio.file.** # not available on Android
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-# dnsjava
--dontwarn sun.net.spi.nameservice.** # not available on Android
-
# DAVdroid + libs
-keep class at.bitfire.** { *; } # all DAVdroid code is required
+
+# Spongcastle
+-dontwarn org.spongycastle.jce.provider.X509LDAPCertStoreSpi
+-dontwarn org.spongycastle.x509.util.LDAPStoreHelper
+-keep class org.spongycastle.crypto.BufferedBlockCipher
+-keep class org.spongycastle.crypto.CipherParameters
+-keep class org.spongycastle.crypto.InvalidCipherTextException
+-keep class org.spongycastle.crypto.digests.SHA256Digest
+-keep class org.spongycastle.crypto.engines.AESEngine
+-keep class org.spongycastle.crypto.generators.SCrypt
+-keep class org.spongycastle.crypto.macs.HMac
+-keep class org.spongycastle.crypto.modes.CBCBlockCipher
+-keep class org.spongycastle.crypto.paddings.BlockCipherPadding
+-keep class org.spongycastle.crypto.paddings.PKCS7Padding
+-keep class org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher
+-keep class org.spongycastle.crypto.params.KeyParameter
+-keep class org.spongycastle.crypto.params.ParametersWithIV
+-keep class org.spongycastle.util.encoders.Hex
diff --git a/app/src/androidTest/java/at/bitfire/davdroid/SSLSocketFactoryCompatTest.java b/app/src/androidTest/java/at/bitfire/davdroid/SSLSocketFactoryCompatTest.java
index 803a3dd7..d6c412cb 100644
--- a/app/src/androidTest/java/at/bitfire/davdroid/SSLSocketFactoryCompatTest.java
+++ b/app/src/androidTest/java/at/bitfire/davdroid/SSLSocketFactoryCompatTest.java
@@ -9,12 +9,10 @@
package at.bitfire.davdroid;
import android.os.Build;
-import android.support.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.io.IOException;
import java.net.Socket;
diff --git a/app/src/androidTest/java/at/bitfire/davdroid/model/CollectionInfoTest.java b/app/src/androidTest/java/at/bitfire/davdroid/model/CollectionInfoTest.java
index 7d3b7d0b..00d41faa 100644
--- a/app/src/androidTest/java/at/bitfire/davdroid/model/CollectionInfoTest.java
+++ b/app/src/androidTest/java/at/bitfire/davdroid/model/CollectionInfoTest.java
@@ -9,84 +9,19 @@
package at.bitfire.davdroid.model;
import android.content.ContentValues;
-import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import java.io.IOException;
-
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.ResourceType;
-import at.bitfire.davdroid.HttpClient;
import at.bitfire.davdroid.model.ServiceDB.Collections;
-import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class CollectionInfoTest {
MockWebServer server = new MockWebServer();
- @Test
- public void testFromDavResource() throws IOException, HttpException, DavException {
- // r/w address book
- server.enqueue(new MockResponse()
- .setResponseCode(207)
- .setBody("" +
- "" +
- " / " +
- " " +
- " " +
- " My Contacts " +
- " My Contacts Description " +
- " " +
- " " +
- " "));
-
- DavResource dav = new DavResource(HttpClient.create(null), server.url("/"));
- dav.propfind(0, ResourceType.NAME);
- CollectionInfo info = CollectionInfo.fromDavResource(dav);
- assertEquals(CollectionInfo.Type.ADDRESS_BOOK, info.type);
- assertFalse(info.readOnly);
- assertEquals("My Contacts", info.displayName);
- assertEquals("My Contacts Description", info.description);
-
- // read-only calendar, no display name
- server.enqueue(new MockResponse()
- .setResponseCode(207)
- .setBody("" +
- "" +
- " / " +
- " " +
- " " +
- " " +
- " My Calendar " +
- " tzdata " +
- " #ff0000 " +
- " " +
- " " +
- " "));
-
- dav = new DavResource(HttpClient.create(null), server.url("/"));
- dav.propfind(0, ResourceType.NAME);
- info = CollectionInfo.fromDavResource(dav);
- assertEquals(CollectionInfo.Type.CALENDAR, info.type);
- assertTrue(info.readOnly);
- assertNull(info.displayName);
- assertEquals("My Calendar", info.description);
- assertEquals(0xFFFF0000, (int)info.color);
- assertEquals("tzdata", info.timeZone);
- assertTrue(info.supportsVEVENT);
- assertTrue(info.supportsVTODO);
- }
-
@Test
public void testFromDB() {
ContentValues values = new ContentValues();
diff --git a/app/src/androidTest/java/at/bitfire/davdroid/ui/setup/DavResourceFinderTest.java b/app/src/androidTest/java/at/bitfire/davdroid/ui/setup/DavResourceFinderTest.java
index f8190fbe..0dd94a4a 100644
--- a/app/src/androidTest/java/at/bitfire/davdroid/ui/setup/DavResourceFinderTest.java
+++ b/app/src/androidTest/java/at/bitfire/davdroid/ui/setup/DavResourceFinderTest.java
@@ -8,27 +8,13 @@
package at.bitfire.davdroid.ui.setup;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.InstrumentationTestCase;
-
import org.junit.After;
import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import java.io.IOException;
import java.net.URI;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.AddressbookHomeSet;
-import at.bitfire.dav4android.property.ResourceType;
import at.bitfire.davdroid.App;
import at.bitfire.davdroid.HttpClient;
-import at.bitfire.davdroid.ui.setup.DavResourceFinder;
-import at.bitfire.davdroid.ui.setup.DavResourceFinder.Configuration.ServiceInfo;
-import at.bitfire.davdroid.ui.setup.LoginCredentials;
import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
@@ -36,10 +22,6 @@ import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static junit.framework.TestCase.assertFalse;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
public class DavResourceFinderTest {
@@ -69,7 +51,6 @@ public class DavResourceFinderTest {
finder = new DavResourceFinder(getTargetContext(), credentials);
client = HttpClient.create(null);
- client = HttpClient.addAuthentication(client, credentials.userName, credentials.password);
}
@After
@@ -77,66 +58,6 @@ public class DavResourceFinderTest {
server.shutdown();
}
- @Test
- public void testRememberIfAddressBookOrHomeset() throws IOException, HttpException, DavException {
- ServiceInfo info;
-
- // before dav.propfind(), no info is available
- DavResource dav = new DavResource(client, server.url(PATH_CARDDAV + SUBPATH_PRINCIPAL));
- finder.rememberIfAddressBookOrHomeset(dav, info = new ServiceInfo());
- assertEquals(0, info.collections.size());
- assertEquals(0, info.homeSets.size());
-
- // recognize home set
- dav.propfind(0, AddressbookHomeSet.NAME);
- finder.rememberIfAddressBookOrHomeset(dav, info = new ServiceInfo());
- assertEquals(0, info.collections.size());
- assertEquals(1, info.homeSets.size());
- assertEquals(server.url(PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET + "/").uri(), info.homeSets.iterator().next());
-
- // recognize address book
- dav = new DavResource(client, server.url(PATH_CARDDAV + SUBPATH_ADDRESSBOOK));
- dav.propfind(0, ResourceType.NAME);
- finder.rememberIfAddressBookOrHomeset(dav, info = new ServiceInfo());
- assertEquals(1, info.collections.size());
- assertEquals(server.url(PATH_CARDDAV + SUBPATH_ADDRESSBOOK + "/").uri(), info.collections.keySet().iterator().next());
- assertEquals(0, info.homeSets.size());
- }
-
- @Test
- public void testProvidesService() throws IOException {
- assertFalse(finder.providesService(server.url(PATH_NO_DAV), DavResourceFinder.Service.CALDAV));
- assertFalse(finder.providesService(server.url(PATH_NO_DAV), DavResourceFinder.Service.CARDDAV));
-
- assertTrue(finder.providesService(server.url(PATH_CALDAV), DavResourceFinder.Service.CALDAV));
- assertFalse(finder.providesService(server.url(PATH_CALDAV), DavResourceFinder.Service.CARDDAV));
-
- assertTrue(finder.providesService(server.url(PATH_CARDDAV), DavResourceFinder.Service.CARDDAV));
- assertFalse(finder.providesService(server.url(PATH_CARDDAV), DavResourceFinder.Service.CALDAV));
-
- assertTrue(finder.providesService(server.url(PATH_CALDAV_AND_CARDDAV), DavResourceFinder.Service.CALDAV));
- assertTrue(finder.providesService(server.url(PATH_CALDAV_AND_CARDDAV), DavResourceFinder.Service.CARDDAV));
- }
-
- @Test
- public void testGetCurrentUserPrincipal() throws IOException, HttpException, DavException {
- assertNull(finder.getCurrentUserPrincipal(server.url(PATH_NO_DAV), DavResourceFinder.Service.CALDAV));
- assertNull(finder.getCurrentUserPrincipal(server.url(PATH_NO_DAV), DavResourceFinder.Service.CARDDAV));
-
- assertEquals(
- server.url(PATH_CALDAV + SUBPATH_PRINCIPAL).uri(),
- finder.getCurrentUserPrincipal(server.url(PATH_CALDAV), DavResourceFinder.Service.CALDAV)
- );
- assertNull(finder.getCurrentUserPrincipal(server.url(PATH_CALDAV), DavResourceFinder.Service.CARDDAV));
-
- assertEquals(
- server.url(PATH_CARDDAV + SUBPATH_PRINCIPAL).uri(),
- finder.getCurrentUserPrincipal(server.url(PATH_CARDDAV), DavResourceFinder.Service.CARDDAV)
- );
- assertNull(finder.getCurrentUserPrincipal(server.url(PATH_CARDDAV), DavResourceFinder.Service.CALDAV));
- }
-
-
// mock server
public class TestDispatcher extends Dispatcher {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 072c30ad..7f445adb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -102,26 +102,14 @@
android:process=":sync"
tools:ignore="ExportedService">
-
+
+ android:resource="@xml/sync_calendars" />
-
-
-
-
-
-
= 0 entries more than n days in the past won't be synchronized
+ /**
+ * Time range limitation to the past [in days]
+ * value = null default value (DEFAULT_TIME_RANGE_PAST_DAYS)
+ * < 0 (-1) no limit
+ * >= 0 entries more than n days in the past won't be synchronized
*/
private final static String KEY_TIME_RANGE_PAST_DAYS = "time_range_past_days";
private final static int DEFAULT_TIME_RANGE_PAST_DAYS = 90;
@@ -70,10 +53,11 @@ public class AccountSettings {
"0" false */
private final static String KEY_MANAGE_CALENDAR_COLORS = "manage_calendar_colors";
- /** Contact group method:
- value = null (not existing) groups as separate VCards (default)
- "CATEGORIES" groups are per-contact CATEGORIES
- */
+ /**
+ * Contact group method:
+ * value = null (not existing) groups as separate VCards (default)
+ * "CATEGORIES" groups are per-contact CATEGORIES
+ */
private final static String KEY_CONTACT_GROUP_METHOD = "contact_group_method";
public final static long SYNC_INTERVAL_MANUALLY = -1;
@@ -90,7 +74,7 @@ public class AccountSettings {
accountManager = AccountManager.get(context);
- synchronized(AccountSettings.class) {
+ synchronized (AccountSettings.class) {
String versionStr = accountManager.getUserData(account, KEY_SETTINGS_VERSION);
if (versionStr == null)
throw new InvalidAccountException(account);
@@ -107,21 +91,52 @@ public class AccountSettings {
}
}
- public static Bundle initialUserData(String userName) {
+ public static Bundle initialUserData(URI uri, String userName) {
Bundle bundle = new Bundle();
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
bundle.putString(KEY_USERNAME, userName);
+ bundle.putString(KEY_URI, uri.toString());
return bundle;
}
// authentication settings
- public String username() { return accountManager.getUserData(account, KEY_USERNAME); }
- public void username(@NonNull String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
+ public URI getUri() {
+ try {
+ return new URI(accountManager.getUserData(account, KEY_URI));
+ } catch (URISyntaxException e) {
+ return null;
+ }
+ }
+
+ public void setUri(@NonNull URI uri) {
+ accountManager.setUserData(account, KEY_URI, uri.toString());
+ }
+
+ public String getAuthToken() {
+ return accountManager.getUserData(account, KEY_TOKEN);
+ }
+
+ public void setAuthToken(@NonNull String token) {
+ accountManager.setUserData(account, KEY_TOKEN, token);
+ }
+
+ public String username() {
+ return accountManager.getUserData(account, KEY_USERNAME);
+ }
+
+ public void username(@NonNull String userName) {
+ accountManager.setUserData(account, KEY_USERNAME, userName);
+ }
- public String password() { return accountManager.getPassword(account); }
- public void password(@NonNull String password) { accountManager.setPassword(account, password); }
+ public String password() {
+ return accountManager.getPassword(account);
+ }
+
+ public void password(@NonNull String password) {
+ accountManager.setPassword(account, password);
+ }
// sync. settings
@@ -224,175 +239,6 @@ public class AccountSettings {
}
}
- @SuppressWarnings({ "Recycle", "unused" })
- private void update_1_2() throws ContactsStorageException {
- /* - KEY_ADDRESSBOOK_URL ("addressbook_url"),
- - KEY_ADDRESSBOOK_CTAG ("addressbook_ctag"),
- - KEY_ADDRESSBOOK_VCARD_VERSION ("addressbook_vcard_version") are not used anymore (now stored in ContactsContract.SyncState)
- - KEY_LAST_ANDROID_VERSION ("last_android_version") has been added
- */
-
- // move previous address book info to ContactsContract.SyncState
- @Cleanup("release") ContentProviderClient provider = context.getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
- if (provider == null)
- throw new ContactsStorageException("Couldn't access Contacts provider");
-
- LocalAddressBook addr = new LocalAddressBook(account, provider);
-
- // until now, ContactsContract.Settings.UNGROUPED_VISIBLE was not set explicitly
- ContentValues values = new ContentValues();
- values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1);
- addr.updateSettings(values);
-
- String url = accountManager.getUserData(account, "addressbook_url");
- if (!TextUtils.isEmpty(url))
- addr.setURL(url);
- accountManager.setUserData(account, "addressbook_url", null);
-
- String cTag = accountManager.getUserData(account, "addressbook_ctag");
- if (!TextUtils.isEmpty(cTag))
- addr.setCTag(cTag);
- accountManager.setUserData(account, "addressbook_ctag", null);
- }
-
- @SuppressWarnings({ "Recycle", "unused" })
- private void update_2_3() {
- // Don't show a warning for Android updates anymore
- accountManager.setUserData(account, "last_android_version", null);
-
- Long serviceCardDAV = null, serviceCalDAV = null;
-
- ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(context);
- try {
- SQLiteDatabase db = dbHelper.getWritableDatabase();
- // we have to create the WebDAV Service database only from the old address book, calendar and task list URLs
-
- // CardDAV: migrate address books
- ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
- if (client != null)
- try {
- LocalAddressBook addrBook = new LocalAddressBook(account, client);
- String url = addrBook.getURL();
- if (url != null) {
- App.log.fine("Migrating address book " + url);
-
- // insert CardDAV service
- ContentValues values = new ContentValues();
- values.put(Services.ACCOUNT_NAME, account.name);
- values.put(Services.SERVICE, Services.SERVICE_CARDDAV);
- serviceCardDAV = db.insert(Services._TABLE, null, values);
-
- // insert address book
- values.clear();
- values.put(Collections.SERVICE_ID, serviceCardDAV);
- values.put(Collections.URL, url);
- values.put(Collections.SYNC, 1);
- db.insert(Collections._TABLE, null, values);
-
- // insert home set
- HttpUrl homeSet = HttpUrl.parse(url).resolve("../");
- values.clear();
- values.put(HomeSets.SERVICE_ID, serviceCardDAV);
- values.put(HomeSets.URL, homeSet.toString());
- db.insert(HomeSets._TABLE, null, values);
- }
-
- } catch (ContactsStorageException e) {
- App.log.log(Level.SEVERE, "Couldn't migrate address book", e);
- } finally {
- client.release();
- }
-
- // CalDAV: migrate calendars + task lists
- Set collections = new HashSet<>();
- Set homeSets = new HashSet<>();
-
- client = context.getContentResolver().acquireContentProviderClient(CalendarContract.AUTHORITY);
- if (client != null)
- try {
- LocalCalendar calendars[] = (LocalCalendar[])LocalCalendar.find(account, client, LocalCalendar.Factory.INSTANCE, null, null);
- for (LocalCalendar calendar : calendars) {
- String url = calendar.getName();
- App.log.fine("Migrating calendar " + url);
- collections.add(url);
- homeSets.add(HttpUrl.parse(url).resolve("../"));
- }
- } catch (CalendarStorageException e) {
- App.log.log(Level.SEVERE, "Couldn't migrate calendars", e);
- } finally {
- client.release();
- }
-
- TaskProvider provider = LocalTaskList.acquireTaskProvider(context.getContentResolver());
- if (provider != null)
- try {
- LocalTaskList[] taskLists = (LocalTaskList[])LocalTaskList.find(account, provider, LocalTaskList.Factory.INSTANCE, null, null);
- for (LocalTaskList taskList : taskLists) {
- String url = taskList.getSyncId();
- App.log.fine("Migrating task list " + url);
- collections.add(url);
- homeSets.add(HttpUrl.parse(url).resolve("../"));
- }
- } catch (CalendarStorageException e) {
- App.log.log(Level.SEVERE, "Couldn't migrate task lists", e);
- } finally {
- provider.close();
- }
-
- if (!collections.isEmpty()) {
- // insert CalDAV service
- ContentValues values = new ContentValues();
- values.put(Services.ACCOUNT_NAME, account.name);
- values.put(Services.SERVICE, Services.SERVICE_CALDAV);
- serviceCalDAV = db.insert(Services._TABLE, null, values);
-
- // insert collections
- for (String url : collections) {
- values.clear();
- values.put(Collections.SERVICE_ID, serviceCalDAV);
- values.put(Collections.URL, url);
- values.put(Collections.SYNC, 1);
- db.insert(Collections._TABLE, null, values);
- }
-
- // insert home sets
- for (HttpUrl homeSet : homeSets) {
- values.clear();
- values.put(HomeSets.SERVICE_ID, serviceCalDAV);
- values.put(HomeSets.URL, homeSet.toString());
- db.insert(HomeSets._TABLE, null, values);
- }
- }
- } finally {
- dbHelper.close();
- }
-
- // initiate service detection (refresh) to get display names, colors etc.
- Intent refresh = new Intent(context, DavService.class);
- refresh.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
- if (serviceCardDAV != null) {
- refresh.putExtra(DavService.EXTRA_DAV_SERVICE_ID, serviceCardDAV);
- context.startService(refresh);
- }
- if (serviceCalDAV != null) {
- refresh.putExtra(DavService.EXTRA_DAV_SERVICE_ID, serviceCalDAV);
- context.startService(refresh);
- }
- }
-
- @SuppressWarnings({ "Recycle", "unused" })
- private void update_3_4() {
- setGroupMethod(GroupMethod.CATEGORIES);
- }
-
- /* Android 7.1.1 OpenTasks fix */
- @SuppressWarnings({ "Recycle", "unused" })
- private void update_4_5() {
- // call PackageChangedReceiver which then enables/disables OpenTasks sync when it's (not) available
- PackageChangedReceiver.updateTaskSync(context);
- }
-
-
public static class AppUpdatedReceiver extends BroadcastReceiver {
@Override
diff --git a/app/src/main/java/at/bitfire/davdroid/App.java b/app/src/main/java/at/bitfire/davdroid/App.java
index f7fa1871..97d98321 100644
--- a/app/src/main/java/at/bitfire/davdroid/App.java
+++ b/app/src/main/java/at/bitfire/davdroid/App.java
@@ -68,7 +68,6 @@ public class App extends Application {
public final static Logger log = Logger.getLogger("davdroid");
static {
- at.bitfire.dav4android.Constants.log = Logger.getLogger("davdroid.dav4android");
at.bitfire.cert4android.Constants.log = Logger.getLogger("davdroid.cert4android");
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ArrayUtils.java b/app/src/main/java/at/bitfire/davdroid/ArrayUtils.java
deleted file mode 100644
index c9ac7247..00000000
--- a/app/src/main/java/at/bitfire/davdroid/ArrayUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package at.bitfire.davdroid;
-
-import java.lang.reflect.Array;
-
-public class ArrayUtils {
-
- @SuppressWarnings("unchecked")
- public static T[][] partition(T[] bigArray, int max) {
- int nItems = bigArray.length;
- int nPartArrays = (nItems + max-1)/max;
-
- T[][] partArrays = (T[][])Array.newInstance(bigArray.getClass().getComponentType(), nPartArrays, 0);
-
- // nItems is now the number of remaining items
- for (int i = 0; nItems > 0; i++) {
- int n = (nItems < max) ? nItems : max;
- partArrays[i] = (T[])Array.newInstance(bigArray.getClass().getComponentType(), n);
- System.arraycopy(bigArray, i*max, partArrays[i], 0, n);
-
- nItems -= n;
- }
-
- return partArrays;
- }
-
-}
diff --git a/app/src/main/java/at/bitfire/davdroid/Constants.java b/app/src/main/java/at/bitfire/davdroid/Constants.java
index 22543d17..0600b9e7 100644
--- a/app/src/main/java/at/bitfire/davdroid/Constants.java
+++ b/app/src/main/java/at/bitfire/davdroid/Constants.java
@@ -9,6 +9,8 @@ package at.bitfire.davdroid;
import android.net.Uri;
+import static at.bitfire.davdroid.BuildConfig.DEBUG_REMOTE_URL;
+
public class Constants {
public static final String
@@ -24,7 +26,15 @@ public class Constants {
NOTIFICATION_TASK_SYNC = 12,
NOTIFICATION_PERMISSIONS = 20;
- public static final Uri webUri = Uri.parse("https://davdroid.bitfire.at/?pk_campaign=davdroid-app");
+ public static final Uri webUri = Uri.parse("https://www.etesync.com/");
+ public static final Uri contactUri = Uri.parse("mailto:contact.app@etesync.com");
+ public static final Uri registrationUrl = webUri.buildUpon().appendEncodedPath("accounts/signup/").build();
+ public static final Uri reportIssueUri = Uri.parse("https://github.com/etesync/android/issues");
+ public static final Uri feedbackUri = reportIssueUri;
+ public static final Uri faqUri = webUri.buildUpon().appendEncodedPath("faq/").build();
+ public static final Uri helpUri = faqUri;
+
+ public static final Uri serviceUrl = Uri.parse((DEBUG_REMOTE_URL == null) ? "https://api.etesync.com/" : DEBUG_REMOTE_URL);
public static final int DEFAULT_SYNC_INTERVAL = 4 * 3600; // 4 hours
diff --git a/app/src/main/java/at/bitfire/davdroid/DavService.java b/app/src/main/java/at/bitfire/davdroid/DavService.java
index 514d4bb6..cd20b93c 100644
--- a/app/src/main/java/at/bitfire/davdroid/DavService.java
+++ b/app/src/main/java/at/bitfire/davdroid/DavService.java
@@ -11,8 +11,6 @@ package at.bitfire.davdroid;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
-import android.app.Notification;
-import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
@@ -22,41 +20,25 @@ import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.NotificationManagerCompat;
-import android.support.v7.app.NotificationCompat;
import android.text.TextUtils;
-import org.apache.commons.collections4.iterators.IteratorChain;
-import org.apache.commons.collections4.iterators.SingletonIterator;
-
-import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.UrlUtils;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.AddressbookHomeSet;
-import at.bitfire.dav4android.property.CalendarHomeSet;
-import at.bitfire.dav4android.property.CalendarProxyReadFor;
-import at.bitfire.dav4android.property.CalendarProxyWriteFor;
-import at.bitfire.dav4android.property.GroupMembership;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalManager;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.model.ServiceDB.Collections;
import at.bitfire.davdroid.model.ServiceDB.HomeSets;
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
import at.bitfire.davdroid.model.ServiceDB.Services;
-import at.bitfire.davdroid.ui.DebugInfoActivity;
import lombok.Cleanup;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
@@ -165,7 +147,6 @@ public class DavService extends Service {
private class RefreshCollections implements Runnable {
final long service;
final OpenHelper dbHelper;
- SQLiteDatabase db;
RefreshCollections(long davServiceId) {
this.service = davServiceId;
@@ -177,148 +158,56 @@ public class DavService extends Service {
Account account = null;
try {
- db = dbHelper.getWritableDatabase();
+ @Cleanup SQLiteDatabase db = dbHelper.getWritableDatabase();
- String serviceType = serviceType();
+ String serviceType = dbHelper.getServiceType(db, service);
App.log.info("Refreshing " + serviceType + " collections of service #" + service);
// get account
- account = account();
+ account = dbHelper.getServiceAccount(db, service);
- // create authenticating OkHttpClient (credentials taken from account settings)
OkHttpClient httpClient = HttpClient.create(DavService.this, account);
- // refresh home sets: principal
- Set homeSets = readHomeSets();
- HttpUrl principal = readPrincipal();
- if (principal != null) {
- App.log.fine("Querying principal for home sets");
- DavResource dav = new DavResource(httpClient, principal);
- queryHomeSets(serviceType, dav, homeSets);
-
- // refresh home sets: calendar-proxy-read/write-for
- CalendarProxyReadFor proxyRead = (CalendarProxyReadFor)dav.properties.get(CalendarProxyReadFor.NAME);
- if (proxyRead != null)
- for (String href : proxyRead.principals) {
- App.log.fine("Principal is a read-only proxy for " + href + ", checking for home sets");
- queryHomeSets(serviceType, new DavResource(httpClient, dav.location.resolve(href)), homeSets);
- }
- CalendarProxyWriteFor proxyWrite = (CalendarProxyWriteFor)dav.properties.get(CalendarProxyWriteFor.NAME);
- if (proxyWrite != null)
- for (String href : proxyWrite.principals) {
- App.log.fine("Principal is a read-write proxy for " + href + ", checking for home sets");
- queryHomeSets(serviceType, new DavResource(httpClient, dav.location.resolve(href)), homeSets);
- }
+ AccountSettings settings = new AccountSettings(DavService.this, account);
+ JournalManager journalsManager = new JournalManager(httpClient, HttpUrl.get(settings.getUri()));
- // refresh home sets: direct group memberships
- GroupMembership groupMembership = (GroupMembership)dav.properties.get(GroupMembership.NAME);
- if (groupMembership != null)
- for (String href : groupMembership.hrefs) {
- App.log.fine("Principal is member of group " + href + ", checking for home sets");
- DavResource group = new DavResource(httpClient, dav.location.resolve(href));
- try {
- queryHomeSets(serviceType, group, homeSets);
- } catch(HttpException|DavException e) {
- App.log.log(Level.WARNING, "Couldn't query member group ", e);
- }
- }
- }
+ List collections = new LinkedList<>();
- // now refresh collections (taken from home sets)
- Map collections = readCollections();
-
- // (remember selections before)
- Set selectedCollections = new HashSet<>();
- for (CollectionInfo info : collections.values())
- if (info.selected)
- selectedCollections.add(HttpUrl.parse(info.url));
-
- for (Iterator itHomeSets = homeSets.iterator(); itHomeSets.hasNext(); ) {
- HttpUrl homeSet = itHomeSets.next();
- App.log.fine("Listing home set " + homeSet);
-
- DavResource dav = new DavResource(httpClient, homeSet);
- try {
- dav.propfind(1, CollectionInfo.DAV_PROPERTIES);
- IteratorChain itCollections = new IteratorChain<>(dav.members.iterator(), new SingletonIterator(dav));
- while (itCollections.hasNext()) {
- DavResource member = itCollections.next();
- CollectionInfo info = CollectionInfo.fromDavResource(member);
- info.confirmed = true;
- App.log.log(Level.FINE, "Found collection", info);
-
- if ((serviceType.equals(Services.SERVICE_CARDDAV) && info.type == CollectionInfo.Type.ADDRESS_BOOK) ||
- (serviceType.equals(Services.SERVICE_CALDAV) && info.type == CollectionInfo.Type.CALENDAR))
- collections.put(member.location, info);
- }
- } catch(HttpException e) {
- if (e.status == 403 || e.status == 404 || e.status == 410)
- // delete home set only if it was not accessible (40x)
- itHomeSets.remove();
+ for (JournalManager.Journal journal : journalsManager.getJournals(settings.password())) {
+ CollectionInfo info = CollectionInfo.fromJson(journal.getContent(settings.password()));
+ info.url = journal.getUuid();
+ if (info.isOfTypeService(serviceType)) {
+ collections.add(info);
}
}
- // check/refresh unconfirmed collections
- for (Iterator> iterator = collections.entrySet().iterator(); iterator.hasNext(); ) {
- Map.Entry entry = iterator.next();
- HttpUrl url = entry.getKey();
- CollectionInfo info = entry.getValue();
-
- if (!info.confirmed)
- try {
- DavResource dav = new DavResource(httpClient, url);
- dav.propfind(0, CollectionInfo.DAV_PROPERTIES);
- info = CollectionInfo.fromDavResource(dav);
- info.confirmed = true;
-
- // remove unusable collections
- if ((serviceType.equals(Services.SERVICE_CARDDAV) && info.type != CollectionInfo.Type.ADDRESS_BOOK) ||
- (serviceType.equals(Services.SERVICE_CALDAV) && info.type != CollectionInfo.Type.CALENDAR))
- iterator.remove();
- } catch(HttpException e) {
- if (e.status == 403 || e.status == 404 || e.status == 410)
- // delete collection only if it was not accessible (40x)
- iterator.remove();
- else
- throw e;
- }
- }
+ // FIXME: handle deletion from server
- // restore selections
- for (HttpUrl url : selectedCollections) {
- CollectionInfo info = collections.get(url);
- if (info != null)
- info.selected = true;
+ if (collections.isEmpty()) {
+ CollectionInfo info = CollectionInfo.defaultForService(serviceType);
+ JournalManager.Journal journal = new JournalManager.Journal(settings.password(), info.toJson());
+ journalsManager.putJournal(journal);
+ info.url = journal.getUuid();
+ collections.add(info);
}
db.beginTransactionNonExclusive();
try {
- saveHomeSets(homeSets);
- saveCollections(collections.values());
+ saveCollections(db, collections);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
- } catch(InvalidAccountException e) {
- App.log.log(Level.SEVERE, "Invalid account", e);
- } catch(IOException|HttpException|DavException e) {
- App.log.log(Level.SEVERE, "Couldn't refresh collection list", e);
-
- Intent debugIntent = new Intent(DavService.this, DebugInfoActivity.class);
- debugIntent.putExtra(DebugInfoActivity.KEY_THROWABLE, e);
- if (account != null)
- debugIntent.putExtra(DebugInfoActivity.KEY_ACCOUNT, account);
-
- NotificationManagerCompat nm = NotificationManagerCompat.from(DavService.this);
- Notification notify = new NotificationCompat.Builder(DavService.this)
- .setSmallIcon(R.drawable.ic_error_light)
- .setLargeIcon(App.getLauncherBitmap(DavService.this))
- .setContentTitle(getString(R.string.dav_service_refresh_failed))
- .setContentText(getString(R.string.dav_service_refresh_couldnt_refresh))
- .setContentIntent(PendingIntent.getActivity(DavService.this, 0, debugIntent, PendingIntent.FLAG_UPDATE_CURRENT))
- .build();
- nm.notify(Constants.NOTIFICATION_REFRESH_COLLECTIONS, notify);
+ } catch (InvalidAccountException e) {
+ // FIXME: Do something
+ e.printStackTrace();
+ } catch (Exceptions.HttpException e) {
+ // FIXME: do something
+ e.printStackTrace();
+ } catch (Exceptions.IntegrityException e) {
+ // FIXME: do something
+ e.printStackTrace();
} finally {
dbHelper.close();
@@ -331,91 +220,20 @@ public class DavService extends Service {
}
}
- /**
- * Checks if the given URL defines home sets and adds them to the home set list.
- * @param serviceType CalDAV/CardDAV (calendar home set / addressbook home set)
- * @param dav DavResource to check
- * @param homeSets set where found home set URLs will be put into
- */
- private void queryHomeSets(String serviceType, DavResource dav, Set homeSets) throws IOException, HttpException, DavException {
- if (Services.SERVICE_CARDDAV.equals(serviceType)) {
- dav.propfind(0, AddressbookHomeSet.NAME, GroupMembership.NAME);
- AddressbookHomeSet addressbookHomeSet = (AddressbookHomeSet)dav.properties.get(AddressbookHomeSet.NAME);
- if (addressbookHomeSet != null)
- for (String href : addressbookHomeSet.hrefs)
- homeSets.add(UrlUtils.withTrailingSlash(dav.location.resolve(href)));
- } else if (Services.SERVICE_CALDAV.equals(serviceType)) {
- dav.propfind(0, CalendarHomeSet.NAME, CalendarProxyReadFor.NAME, CalendarProxyWriteFor.NAME, GroupMembership.NAME);
- CalendarHomeSet calendarHomeSet = (CalendarHomeSet)dav.properties.get(CalendarHomeSet.NAME);
- if (calendarHomeSet != null)
- for (String href : calendarHomeSet.hrefs)
- homeSets.add(UrlUtils.withTrailingSlash(dav.location.resolve(href)));
- }
- }
-
-
- @NonNull
- private Account account() {
- @Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.ACCOUNT_NAME }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
- if (cursor.moveToNext()) {
- return new Account(cursor.getString(0), Constants.ACCOUNT_TYPE);
- } else
- throw new IllegalArgumentException("Service not found");
- }
-
- @NonNull
- private String serviceType() {
- @Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.SERVICE }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
- if (cursor.moveToNext())
- return cursor.getString(0);
- else
- throw new IllegalArgumentException("Service not found");
- }
-
- @Nullable
- private HttpUrl readPrincipal() {
- @Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.PRINCIPAL }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
- if (cursor.moveToNext()) {
- String principal = cursor.getString(0);
- if (principal != null)
- return HttpUrl.parse(cursor.getString(0));
- }
- return null;
- }
-
- @NonNull
- private Set readHomeSets() {
- Set homeSets = new LinkedHashSet<>();
- @Cleanup Cursor cursor = db.query(HomeSets._TABLE, new String[] { HomeSets.URL }, HomeSets.SERVICE_ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
- while (cursor.moveToNext())
- homeSets.add(HttpUrl.parse(cursor.getString(0)));
- return homeSets;
- }
-
- private void saveHomeSets(Set homeSets) {
- db.delete(HomeSets._TABLE, HomeSets.SERVICE_ID + "=?", new String[] { String.valueOf(service) });
- for (HttpUrl homeSet : homeSets) {
- ContentValues values = new ContentValues(1);
- values.put(HomeSets.SERVICE_ID, service);
- values.put(HomeSets.URL, homeSet.toString());
- db.insertOrThrow(HomeSets._TABLE, null, values);
- }
- }
-
@NonNull
- private Map readCollections() {
- Map collections = new LinkedHashMap<>();
+ private Map readCollections(SQLiteDatabase db) {
+ Map collections = new LinkedHashMap<>();
@Cleanup Cursor cursor = db.query(Collections._TABLE, null, Collections.SERVICE_ID + "=?", new String[]{String.valueOf(service)}, null, null, null);
while (cursor.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(cursor, values);
- collections.put(HttpUrl.parse(values.getAsString(Collections.URL)), CollectionInfo.fromDB(values));
+ collections.put(values.getAsString(Collections.URL), CollectionInfo.fromDB(values));
}
return collections;
}
- private void saveCollections(Iterable collections) {
- db.delete(Collections._TABLE, HomeSets.SERVICE_ID + "=?", new String[] { String.valueOf(service) });
+ private void saveCollections(SQLiteDatabase db, Iterable collections) {
+ db.delete(Collections._TABLE, HomeSets.SERVICE_ID + "=?", new String[]{String.valueOf(service)});
for (CollectionInfo collection : collections) {
ContentValues values = collection.toDB();
App.log.log(Level.FINE, "Saving collection", values);
diff --git a/app/src/main/java/at/bitfire/davdroid/DavUtils.java b/app/src/main/java/at/bitfire/davdroid/DavUtils.java
deleted file mode 100644
index 8664f467..00000000
--- a/app/src/main/java/at/bitfire/davdroid/DavUtils.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-package at.bitfire.davdroid;
-
-import android.support.annotation.NonNull;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import okhttp3.HttpUrl;
-
-public class DavUtils {
-
- public static String ARGBtoCalDAVColor(int colorWithAlpha) {
- byte alpha = (byte)(colorWithAlpha >> 24);
- int color = colorWithAlpha & 0xFFFFFF;
- return String.format("#%06X%02X", color, alpha);
- }
-
- public static String lastSegmentOfUrl(@NonNull String url) {
- // the list returned by HttpUrl.pathSegments() is unmodifiable, so we have to create a copy
- List segments = new LinkedList<>(HttpUrl.parse(url).pathSegments());
- Collections.reverse(segments);
-
- for (String segment : segments)
- if (!StringUtils.isEmpty(segment))
- return segment;
-
- return "/";
- }
-
-}
diff --git a/app/src/main/java/at/bitfire/davdroid/GsonHelper.java b/app/src/main/java/at/bitfire/davdroid/GsonHelper.java
new file mode 100644
index 00000000..094652c3
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/GsonHelper.java
@@ -0,0 +1,31 @@
+package at.bitfire.davdroid;
+
+import android.util.Base64;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import java.lang.reflect.Type;
+
+public class GsonHelper {
+ public static final Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class,
+ new ByteArrayToBase64TypeAdapter()).create();
+
+ // Using Android's base64 libraries. This can be replaced with any base64 library.
+ private static class ByteArrayToBase64TypeAdapter implements JsonSerializer, JsonDeserializer {
+ public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ return Base64.decode(json.getAsString(), Base64.NO_WRAP);
+ }
+
+ public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
+ return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
+ }
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/HttpClient.java b/app/src/main/java/at/bitfire/davdroid/HttpClient.java
index 2da5aa30..6a0b6253 100644
--- a/app/src/main/java/at/bitfire/davdroid/HttpClient.java
+++ b/app/src/main/java/at/bitfire/davdroid/HttpClient.java
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
-import at.bitfire.dav4android.BasicDigestAuthHandler;
import at.bitfire.davdroid.model.ServiceDB;
import at.bitfire.davdroid.model.Settings;
import okhttp3.Interceptor;
@@ -39,9 +38,10 @@ public class HttpClient {
private static final UserAgentInterceptor userAgentInterceptor = new UserAgentInterceptor();
private static final String userAgent;
+
static {
String date = new SimpleDateFormat("yyyy/MM/dd", Locale.US).format(new Date(BuildConfig.buildTime));
- userAgent = "DAVdroid/" + BuildConfig.VERSION_NAME + " (" + date + "; dav4android; okhttp3) Android/" + Build.VERSION.RELEASE;
+ userAgent = "DAVdroid/" + BuildConfig.VERSION_NAME + " (" + date + "; okhttp3) Android/" + Build.VERSION.RELEASE;
}
private HttpClient() {
@@ -52,7 +52,7 @@ public class HttpClient {
// use account settings for authentication
AccountSettings settings = new AccountSettings(context, account);
- builder = addAuthentication(builder, null, settings.username(), settings.password());
+ builder = addAuthentication(builder, null, settings.getAuthToken());
return builder.build();
}
@@ -75,7 +75,7 @@ public class HttpClient {
// use MemorizingTrustManager to manage self-signed certificates
if (context != null) {
- App app = (App)context.getApplicationContext();
+ App app = (App) context.getApplicationContext();
if (App.getSslSocketFactoryCompat() != null && app.getCertManager() != null)
builder.sslSocketFactory(App.getSslSocketFactoryCompat(), app.getCertManager());
if (App.getHostnameVerifier() != null)
@@ -87,9 +87,6 @@ public class HttpClient {
builder.writeTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(120, TimeUnit.SECONDS);
- // don't allow redirects, because it would break PROPFIND handling
- builder.followRedirects(false);
-
// custom proxy support
if (context != null) {
SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(context);
@@ -105,7 +102,7 @@ public class HttpClient {
builder.proxy(proxy);
App.log.log(Level.INFO, "Using proxy", proxy);
}
- } catch(IllegalArgumentException|NullPointerException e) {
+ } catch (IllegalArgumentException | NullPointerException e) {
App.log.log(Level.SEVERE, "Can't set proxy, ignoring", e);
} finally {
dbHelper.close();
@@ -115,9 +112,6 @@ public class HttpClient {
// add User-Agent to every request
builder.addNetworkInterceptor(userAgentInterceptor);
- // add cookie store for non-persistent cookies (some services like Horde use cookies for session tracking)
- builder.cookieJar(new MemoryCookieStore());
-
// add network logging, if requested
if (logger.isLoggable(Level.FINEST)) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@@ -126,32 +120,46 @@ public class HttpClient {
logger.finest(message);
}
});
- loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
+ loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(loggingInterceptor);
}
return builder;
}
- private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @Nullable String host, @NonNull String username, @NonNull String password) {
- BasicDigestAuthHandler authHandler = new BasicDigestAuthHandler(host, username, password);
- return builder
- .addNetworkInterceptor(authHandler)
- .authenticator(authHandler);
- }
+ private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @Nullable String host, @NonNull String token) {
+ TokenAuthenticator authHandler = new TokenAuthenticator(host, token);
- public static OkHttpClient addAuthentication(@NonNull OkHttpClient client, @NonNull String username, @NonNull String password) {
- OkHttpClient.Builder builder = client.newBuilder();
- addAuthentication(builder, null, username, password);
- return builder.build();
+ return builder.addNetworkInterceptor(authHandler);
}
- public static OkHttpClient addAuthentication(@NonNull OkHttpClient client, @NonNull String host, @NonNull String username, @NonNull String password) {
- OkHttpClient.Builder builder = client.newBuilder();
- addAuthentication(builder, host, username, password);
- return builder.build();
- }
+ private static class TokenAuthenticator implements Interceptor {
+ protected static final String
+ HEADER_AUTHORIZATION = "Authorization";
+
+ // FIXME: Host is not used
+ final String host, token;
+
+ private TokenAuthenticator(String host, String token) {
+ this.host = host;
+ this.token = token;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+
+ if ((token != null)
+ && (request.header(HEADER_AUTHORIZATION) == null)) {
+ request = request.newBuilder()
+ .header(HEADER_AUTHORIZATION, "Token " + token)
+ .build();
+ }
+
+ return chain.proceed(request);
+ }
+ }
static class UserAgentInterceptor implements Interceptor {
@Override
diff --git a/app/src/main/java/at/bitfire/davdroid/MemoryCookieStore.java b/app/src/main/java/at/bitfire/davdroid/MemoryCookieStore.java
deleted file mode 100644
index 1b1cf330..00000000
--- a/app/src/main/java/at/bitfire/davdroid/MemoryCookieStore.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-package at.bitfire.davdroid;
-
-import org.apache.commons.collections4.MapIterator;
-import org.apache.commons.collections4.keyvalue.MultiKey;
-import org.apache.commons.collections4.map.HashedMap;
-import org.apache.commons.collections4.map.MultiKeyMap;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import okhttp3.Cookie;
-import okhttp3.CookieJar;
-import okhttp3.HttpUrl;
-
-/**
- * Primitive cookie store that stores cookies in a (volatile) hash map.
- * Will be sufficient for session cookies.
- */
-public class MemoryCookieStore implements CookieJar {
-
- /**
- * Stored cookies. The multi-key consists of three parts: name, domain, and path.
- * This ensures that cookies can be overwritten. [RFC 6265 5.3 Storage Model]
- * Not thread-safe!
- */
- protected final MultiKeyMap storage = MultiKeyMap.multiKeyMap(new HashedMap, Cookie>());
-
- @Override
- public void saveFromResponse(HttpUrl url, List cookies) {
- synchronized(storage) {
- for (Cookie cookie : cookies)
- storage.put(cookie.name(), cookie.domain(), cookie.path(), cookie);
- }
- }
-
- @Override
- public List loadForRequest(HttpUrl url) {
- List cookies = new LinkedList<>();
-
- synchronized(storage) {
- MapIterator, Cookie> iter = storage.mapIterator();
- while (iter.hasNext()) {
- iter.next();
- Cookie cookie = iter.getValue();
-
- // remove expired cookies
- if (cookie.expiresAt() <= System.currentTimeMillis()) {
- iter.remove();
- continue;
- }
-
- // add applicable cookies
- if (cookie.matches(url))
- cookies.add(cookie);
- }
- }
-
- return cookies;
- }
-
-}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/BaseManager.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/BaseManager.java
new file mode 100644
index 00000000..eef20483
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/BaseManager.java
@@ -0,0 +1,104 @@
+package at.bitfire.davdroid.journalmanager;
+
+import org.apache.commons.codec.Charsets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.logging.Level;
+
+import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.GsonHelper;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import okhttp3.HttpUrl;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import static at.bitfire.davdroid.journalmanager.Helpers.hmac;
+
+abstract class BaseManager {
+ final static protected MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+
+ protected HttpUrl remote;
+ protected OkHttpClient client;
+
+ Response newCall(Request request) throws Exceptions.HttpException {
+ Response response;
+ try {
+ response = client.newCall(request).execute();
+ } catch (IOException e) {
+ App.log.log(Level.SEVERE, "Couldn't download external resource", e);
+ throw new Exceptions.ServiceUnavailableException("Failed downloading");
+ }
+
+ if (!response.isSuccessful()) {
+ switch (response.code()) {
+ case 401:
+ throw new Exceptions.UnauthorizedException("Failed to connect");
+ default:
+ throw new Exceptions.HttpException("Error getting");
+ }
+ }
+
+ return response;
+ }
+
+ static class Base {
+ @Setter(AccessLevel.PACKAGE)
+ @Getter(AccessLevel.PACKAGE)
+ private byte[] content;
+ @Setter(AccessLevel.PACKAGE)
+ private String uid;
+
+ public String getUuid() {
+ return uid;
+ }
+
+ public String getContent(String keyBase64) {
+ // FIXME: probably cache encryption object
+ return new String(new Helpers.Cipher().decrypt(keyBase64, content), Charsets.UTF_8);
+ }
+
+ void setContent(String keyBase64, String content) {
+ // FIXME: probably cache encryption object
+ this.content = new Helpers.Cipher().encrypt(keyBase64, content.getBytes(Charsets.UTF_8));
+ }
+
+ byte[] calculateHmac(String keyBase64, String uuid) {
+ ByteArrayOutputStream hashContent = new ByteArrayOutputStream();
+
+ try {
+ if (uuid != null) {
+ hashContent.write(uuid.getBytes(Charsets.UTF_8));
+ }
+
+ hashContent.write(content);
+ } catch (IOException e) {
+ // FIXME: Do something
+ e.printStackTrace();
+ }
+
+ return hmac(keyBase64, hashContent.toByteArray());
+ }
+
+ protected Base() {
+ }
+
+ Base(String keyBase64, String content, String uid) {
+ setContent(keyBase64, content);
+ setUid(uid);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "<" + uid + ">";
+ }
+
+ String toJson() {
+ return GsonHelper.gson.toJson(this, getClass());
+ }
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/Exceptions.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/Exceptions.java
new file mode 100644
index 00000000..4d9deff4
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/Exceptions.java
@@ -0,0 +1,31 @@
+package at.bitfire.davdroid.journalmanager;
+
+public class Exceptions {
+ public static class UnauthorizedException extends HttpException {
+ public UnauthorizedException(String message) {
+ super(401, message);
+ }
+ }
+
+ public static class ServiceUnavailableException extends HttpException {
+ public ServiceUnavailableException(String message) {
+ super(message);
+ }
+ }
+
+ public static class HttpException extends Exception {
+ public HttpException(String message) {
+ super(message);
+ }
+
+ public HttpException(int status, String message) {
+ super(status + " " + message);
+ }
+ }
+
+ public static class IntegrityException extends Exception {
+ public IntegrityException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/Helpers.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/Helpers.java
new file mode 100644
index 00000000..c25ef7c2
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/Helpers.java
@@ -0,0 +1,128 @@
+package at.bitfire.davdroid.journalmanager;
+
+import android.util.Base64;
+
+import org.apache.commons.codec.Charsets;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.digests.SHA256Digest;
+import org.spongycastle.crypto.engines.AESEngine;
+import org.spongycastle.crypto.generators.SCrypt;
+import org.spongycastle.crypto.macs.HMac;
+import org.spongycastle.crypto.modes.CBCBlockCipher;
+import org.spongycastle.crypto.paddings.BlockCipherPadding;
+import org.spongycastle.crypto.paddings.PKCS7Padding;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithIV;
+import org.spongycastle.util.encoders.Hex;
+
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+public class Helpers {
+ // FIXME: This should be somewhere else
+ public static String deriveKey(String salt, String password) {
+ final int keySize = 190;
+
+ return Base64.encodeToString(SCrypt.generate(password.getBytes(Charsets.UTF_8), salt.getBytes(Charsets.UTF_8), 16384, 8, 1, keySize), Base64.NO_WRAP);
+ }
+
+ private static byte[] hmac256(byte[] keyByte, byte[] data) {
+ HMac hmac = new HMac(new SHA256Digest());
+ KeyParameter key = new KeyParameter(keyByte);
+ byte[] ret = new byte[hmac.getMacSize()];
+ hmac.init(key);
+ hmac.update(data, 0, data.length);
+ hmac.doFinal(ret, 0);
+ return ret;
+ }
+
+ static byte[] hmac(String keyBase64, byte[] data) {
+ byte[] derivedKey = hmac256("hmac".getBytes(Charsets.UTF_8), Base64.decode(keyBase64, Base64.NO_WRAP));
+ return hmac256(derivedKey, data);
+ }
+
+ static class Cipher {
+ SecureRandom random;
+
+ Cipher() {
+ random = new SecureRandom();
+ }
+
+ private static final int blockSize = 16; // AES's block size in bytes
+
+ private BufferedBlockCipher getCipher(String keyBase64, byte[] iv, boolean encrypt) {
+ byte[] derivedKey = hmac256("aes".getBytes(Charsets.UTF_8), Base64.decode(keyBase64, Base64.NO_WRAP));
+ KeyParameter key = new KeyParameter(derivedKey);
+ CipherParameters params = new ParametersWithIV(key, iv);
+
+ BlockCipherPadding padding = new PKCS7Padding();
+ BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
+ new CBCBlockCipher(new AESEngine()), padding);
+ cipher.reset();
+ cipher.init(encrypt, params);
+
+ return cipher;
+ }
+
+ byte[] decrypt(String keyBase64, byte[] _data) {
+ byte[] iv = Arrays.copyOfRange(_data, 0, blockSize);
+ byte[] data = Arrays.copyOfRange(_data, blockSize, _data.length);
+
+ BufferedBlockCipher cipher = getCipher(keyBase64, iv, false);
+
+ byte[] buf = new byte[cipher.getOutputSize(data.length)];
+ int len = cipher.processBytes(data, 0, data.length, buf, 0);
+ try {
+ len += cipher.doFinal(buf, len);
+ } catch (InvalidCipherTextException e) {
+ // FIXME: Fail!
+ e.printStackTrace();
+ }
+
+ // remove padding
+ byte[] out = new byte[len];
+ System.arraycopy(buf, 0, out, 0, len);
+
+ return out;
+ }
+
+ byte[] encrypt(String keyBase64, byte[] data) {
+ byte[] iv = new byte[blockSize];
+ random.nextBytes(iv);
+
+ BufferedBlockCipher cipher = getCipher(keyBase64, iv, true);
+
+ byte[] buf = new byte[cipher.getOutputSize(data.length) + blockSize];
+ System.arraycopy(iv, 0, buf, 0, iv.length);
+ int len = iv.length + cipher.processBytes(data, 0, data.length, buf, iv.length);
+ try {
+ cipher.doFinal(buf, len);
+ } catch (InvalidCipherTextException e) {
+ // FIXME: Fail!
+ e.printStackTrace();
+ }
+
+ return buf;
+ }
+ }
+
+ /* FIXME: Replace with bouncy-castle once available. */
+ static String sha256(String base) {
+ return sha256(base.getBytes(Charsets.UTF_8));
+ }
+
+ /* FIXME: Replace with bouncy-castle once available. */
+ static String sha256(byte[] base) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] hash = digest.digest(base);
+ return Hex.toHexString(hash);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalAuthenticator.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalAuthenticator.java
new file mode 100644
index 00000000..6e1ae7a7
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalAuthenticator.java
@@ -0,0 +1,58 @@
+package at.bitfire.davdroid.journalmanager;
+
+import java.io.IOException;
+import java.util.logging.Level;
+
+import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.GsonHelper;
+import okhttp3.FormBody;
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class JournalAuthenticator {
+ private HttpUrl remote;
+ private OkHttpClient client;
+
+ public JournalAuthenticator(OkHttpClient client, HttpUrl remote) {
+ this.client = client;
+ this.remote = remote.newBuilder()
+ .addPathSegments("api-token-auth")
+ .addPathSegment("")
+ .build();
+ }
+
+ private class AuthResponse {
+ private String token;
+
+ private AuthResponse() {
+ }
+ }
+
+ public String getAuthToken(String username, String password) throws Exceptions.HttpException {
+ FormBody.Builder formBuilder = new FormBody.Builder()
+ .add("username", username)
+ .add("password", password);
+
+ Request request = new Request.Builder()
+ .post(formBuilder.build())
+ .url(remote)
+ .build();
+
+ try {
+ Response response = client.newCall(request).execute();
+ if (response.isSuccessful()) {
+ return GsonHelper.gson.fromJson(response.body().charStream(), AuthResponse.class).token;
+ } else if (response.code() == 400) {
+ throw new Exceptions.UnauthorizedException("Username or password incorrect");
+ } else {
+ throw new Exceptions.HttpException("Error authenticating");
+ }
+ } catch (IOException e) {
+ App.log.log(Level.SEVERE, "Couldn't download external resource", e);
+ }
+
+ return null;
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalEntryManager.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalEntryManager.java
new file mode 100644
index 00000000..b5fe6592
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalEntryManager.java
@@ -0,0 +1,112 @@
+package at.bitfire.davdroid.journalmanager;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import aQute.lib.hex.Hex;
+import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.GsonHelper;
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+public class JournalEntryManager extends BaseManager {
+ final static private Type entryType = new TypeToken>() {
+ }.getType();
+
+
+ public JournalEntryManager(OkHttpClient httpClient, HttpUrl remote, String journal) {
+ this.remote = remote.newBuilder()
+ .addPathSegments("api/v1/journal")
+ .addPathSegments(journal)
+ .addPathSegment("")
+ .build();
+ App.log.info("Created for: " + this.remote.toString());
+
+ this.client = httpClient;
+ }
+
+ public List getEntries(String keyBase64, String last) throws Exceptions.HttpException, Exceptions.IntegrityException {
+ Entry previousEntry = null;
+ HttpUrl.Builder urlBuilder = this.remote.newBuilder();
+ if (last != null) {
+ urlBuilder.addQueryParameter("last", last);
+ previousEntry = Entry.getFakeWithUid(last);
+ }
+
+ HttpUrl remote = urlBuilder.build();
+
+ Request request = new Request.Builder()
+ .get()
+ .url(remote)
+ .build();
+
+ Response response = newCall(request);
+ ResponseBody body = response.body();
+ List ret = GsonHelper.gson.fromJson(body.charStream(), entryType);
+
+ for (Entry entry : ret) {
+ entry.verify(keyBase64, previousEntry);
+ previousEntry = entry;
+ }
+
+ return ret;
+ }
+
+ public void putEntries(List entries, String last) throws Exceptions.HttpException {
+ HttpUrl.Builder urlBuilder = this.remote.newBuilder();
+ if (last != null) {
+ urlBuilder.addQueryParameter("last", last);
+ }
+
+ HttpUrl remote = urlBuilder.build();
+
+ RequestBody body = RequestBody.create(JSON, GsonHelper.gson.toJson(entries, entryType));
+
+ Request request = new Request.Builder()
+ .post(body)
+ .url(remote)
+ .build();
+
+ newCall(request);
+ }
+
+ public static class Entry extends Base {
+ public Entry() {
+ super();
+ }
+
+ public void update(String keyBase64, String content, Entry previous) {
+ setContent(keyBase64, content);
+ setUid(calculateHmac(keyBase64, previous));
+ }
+
+ void verify(String keyBase64, Entry previous) throws Exceptions.IntegrityException {
+ String correctHash = calculateHmac(keyBase64, previous);
+ if (!getUuid().equals(correctHash)) {
+ throw new Exceptions.IntegrityException("Bad HMAC. " + getUuid() + " != " + correctHash);
+ }
+ }
+
+ public static Entry getFakeWithUid(String uid) {
+ Entry ret = new Entry();
+ ret.setUid(uid);
+ return ret;
+ }
+
+ private String calculateHmac(String keyBase64, Entry previous) {
+ String uuid = null;
+ if (previous != null) {
+ uuid = previous.getUuid();
+ }
+
+ return Hex.toHexString(calculateHmac(keyBase64, uuid));
+ }
+ }
+
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalManager.java b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalManager.java
new file mode 100644
index 00000000..bbed9b7e
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/journalmanager/JournalManager.java
@@ -0,0 +1,124 @@
+package at.bitfire.davdroid.journalmanager;
+
+import com.google.gson.reflect.TypeToken;
+
+import org.spongycastle.util.Arrays;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.UUID;
+
+import aQute.lib.hex.Hex;
+import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.GsonHelper;
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+import static at.bitfire.davdroid.journalmanager.Helpers.sha256;
+
+public class JournalManager extends BaseManager {
+ final static private Type journalType = new TypeToken>() {
+ }.getType();
+
+
+ public JournalManager(OkHttpClient httpClient, HttpUrl remote) {
+ this.remote = remote.newBuilder()
+ .addPathSegments("api/v1/journals")
+ .addPathSegment("")
+ .build();
+ App.log.info("Created for: " + this.remote.toString());
+
+ this.client = httpClient;
+ }
+
+ public List getJournals(String keyBase64) throws Exceptions.HttpException, Exceptions.IntegrityException {
+ Request request = new Request.Builder()
+ .get()
+ .url(remote)
+ .build();
+
+ Response response = newCall(request);
+ ResponseBody body = response.body();
+ List ret = GsonHelper.gson.fromJson(body.charStream(), journalType);
+
+ for (Journal journal : ret) {
+ journal.processFromJson();
+ journal.verify(keyBase64);
+ }
+
+ return ret;
+ }
+
+ public void deleteJournal(Journal journal) throws Exceptions.HttpException {
+ HttpUrl remote = this.remote.resolve(journal.getUuid() + "/");
+ Request request = new Request.Builder()
+ .delete()
+ .url(remote)
+ .build();
+
+ newCall(request);
+ }
+
+ public void putJournal(Journal journal) throws Exceptions.HttpException {
+ RequestBody body = RequestBody.create(JSON, journal.toJson());
+
+ Request request = new Request.Builder()
+ .post(body)
+ .url(remote)
+ .build();
+
+ newCall(request);
+ }
+
+ public static class Journal extends Base {
+ final private transient int hmacSize = 256 / 8; // hmac256 in bytes
+ private transient byte[] hmac = null;
+
+ @SuppressWarnings("unused")
+ private Journal() {
+ super();
+ }
+
+ public Journal(String keyBase64, String content) {
+ this(keyBase64, content, sha256(UUID.randomUUID().toString()));
+ }
+
+ public Journal(String keyBase64, String content, String uid) {
+ super(keyBase64, content, uid);
+ hmac = calculateHmac(keyBase64);
+ }
+
+ private void processFromJson() {
+ hmac = Arrays.copyOfRange(getContent(), 0, hmacSize);
+ setContent(Arrays.copyOfRange(getContent(), hmacSize, getContent().length));
+ }
+
+ void verify(String keyBase64) throws Exceptions.IntegrityException {
+ if (hmac == null) {
+ throw new Exceptions.IntegrityException("HMAC is null!");
+ }
+
+ byte[] correctHash = calculateHmac(keyBase64);
+ if (!Arrays.areEqual(hmac, correctHash)) {
+ throw new Exceptions.IntegrityException("Bad HMAC. " + Hex.toHexString(hmac) + " != " + Hex.toHexString(correctHash));
+ }
+ }
+
+ byte[] calculateHmac(String keyBase64) {
+ return super.calculateHmac(keyBase64, getUuid());
+ }
+
+ @Override
+ String toJson() {
+ byte[] rawContent = getContent();
+ setContent(Arrays.concatenate(hmac, rawContent));
+ String ret = super.toJson();
+ setContent(rawContent);
+ return ret;
+ }
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.java b/app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.java
index 3e0f710a..be1a54ef 100644
--- a/app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.java
+++ b/app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.java
@@ -10,36 +10,25 @@ package at.bitfire.davdroid.model;
import android.content.ContentValues;
-import org.apache.commons.lang3.StringUtils;
-
import java.io.Serializable;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.Property;
-import at.bitfire.dav4android.property.AddressbookDescription;
-import at.bitfire.dav4android.property.CalendarColor;
-import at.bitfire.dav4android.property.CalendarDescription;
-import at.bitfire.dav4android.property.CalendarTimezone;
-import at.bitfire.dav4android.property.CurrentUserPrivilegeSet;
-import at.bitfire.dav4android.property.DisplayName;
-import at.bitfire.dav4android.property.ResourceType;
-import at.bitfire.dav4android.property.SupportedAddressData;
-import at.bitfire.dav4android.property.SupportedCalendarComponentSet;
+import at.bitfire.davdroid.GsonHelper;
import at.bitfire.davdroid.model.ServiceDB.Collections;
import lombok.ToString;
@ToString
public class CollectionInfo implements Serializable {
- public long id;
- public Long serviceID;
+ public transient long id;
+ public transient Long serviceID;
public enum Type {
ADDRESS_BOOK,
CALENDAR
}
+
public Type type;
- public String url;
+ public transient String url; // Essentially the uuid
public boolean readOnly;
public String displayName, description;
@@ -51,68 +40,29 @@ public class CollectionInfo implements Serializable {
public boolean selected;
- // non-persistent properties
- public boolean confirmed;
-
-
- public static final Property.Name[] DAV_PROPERTIES = {
- ResourceType.NAME,
- CurrentUserPrivilegeSet.NAME,
- DisplayName.NAME,
- AddressbookDescription.NAME, SupportedAddressData.NAME,
- CalendarDescription.NAME, CalendarColor.NAME, SupportedCalendarComponentSet.NAME
- };
+ public CollectionInfo() {
+ }
- public static CollectionInfo fromDavResource(DavResource dav) {
+ public static CollectionInfo defaultForService(String sService) {
+ Type service = Type.valueOf(sService);
CollectionInfo info = new CollectionInfo();
- info.url = dav.location.toString();
-
- ResourceType type = (ResourceType)dav.properties.get(ResourceType.NAME);
- if (type != null) {
- if (type.types.contains(ResourceType.ADDRESSBOOK))
- info.type = Type.ADDRESS_BOOK;
- else if (type.types.contains(ResourceType.CALENDAR))
- info.type = Type.CALENDAR;
- }
-
+ info.displayName = "Default";
+ info.selected = true;
info.readOnly = false;
- CurrentUserPrivilegeSet privilegeSet = (CurrentUserPrivilegeSet)dav.properties.get(CurrentUserPrivilegeSet.NAME);
- if (privilegeSet != null)
- info.readOnly = !privilegeSet.mayWriteContent;
-
- DisplayName displayName = (DisplayName)dav.properties.get(DisplayName.NAME);
- if (displayName != null && !StringUtils.isEmpty(displayName.displayName))
- info.displayName = displayName.displayName;
-
- if (info.type == Type.ADDRESS_BOOK) {
- AddressbookDescription addressbookDescription = (AddressbookDescription)dav.properties.get(AddressbookDescription.NAME);
- if (addressbookDescription != null)
- info.description = addressbookDescription.description;
-
- } else if (info.type == Type.CALENDAR) {
- CalendarDescription calendarDescription = (CalendarDescription)dav.properties.get(CalendarDescription.NAME);
- if (calendarDescription != null)
- info.description = calendarDescription.description;
-
- CalendarColor calendarColor = (CalendarColor)dav.properties.get(CalendarColor.NAME);
- if (calendarColor != null)
- info.color = calendarColor.color;
-
- CalendarTimezone timeZone = (CalendarTimezone)dav.properties.get(CalendarTimezone.NAME);
- if (timeZone != null)
- info.timeZone = timeZone.vTimeZone;
-
- info.supportsVEVENT = info.supportsVTODO = true;
- SupportedCalendarComponentSet supportedCalendarComponentSet = (SupportedCalendarComponentSet)dav.properties.get(SupportedCalendarComponentSet.NAME);
- if (supportedCalendarComponentSet != null) {
- info.supportsVEVENT = supportedCalendarComponentSet.supportsEvents;
- info.supportsVTODO = supportedCalendarComponentSet.supportsTasks;
- }
- }
+ info.type = service;
+ if (service.equals(Type.CALENDAR)) {
+ info.supportsVEVENT = true;
+ // info.supportsVTODO = true;
+ } else {
+ // Carddav
+ }
return info;
}
+ public boolean isOfTypeService(String service) {
+ return service.equals(type.toString());
+ }
public static CollectionInfo fromDB(ContentValues values) {
CollectionInfo info = new CollectionInfo();
@@ -154,6 +104,13 @@ public class CollectionInfo implements Serializable {
return values;
}
+ public static CollectionInfo fromJson(String json) {
+ return GsonHelper.gson.fromJson(json, CollectionInfo.class);
+ }
+
+ public String toJson() {
+ return GsonHelper.gson.toJson(this, CollectionInfo.class);
+ }
private static Boolean getAsBooleanOrNull(ContentValues values, String field) {
Integer i = values.getAsInteger(field);
diff --git a/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java b/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java
index c24af265..06ad1fd4 100644
--- a/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java
+++ b/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java
@@ -8,6 +8,7 @@
package at.bitfire.davdroid.model;
+import android.accounts.Account;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -16,9 +17,11 @@ import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.Constants;
import lombok.Cleanup;
public class ServiceDB {
@@ -35,13 +38,12 @@ public class ServiceDB {
_TABLE = "services",
ID = "_id",
ACCOUNT_NAME = "accountName",
- SERVICE = "service",
- PRINCIPAL = "principal";
+ SERVICE = "service";
// allowed values for SERVICE column
public static final String
- SERVICE_CALDAV = "caldav",
- SERVICE_CARDDAV = "carddav";
+ SERVICE_CALDAV = CollectionInfo.Type.CALENDAR.toString(),
+ SERVICE_CARDDAV = CollectionInfo.Type.ADDRESS_BOOK.toString();
}
public static class HomeSets {
@@ -103,8 +105,7 @@ public class ServiceDB {
db.execSQL("CREATE TABLE " + Services._TABLE + "(" +
Services.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Services.ACCOUNT_NAME + " TEXT NOT NULL," +
- Services.SERVICE + " TEXT NOT NULL," +
- Services.PRINCIPAL + " TEXT NULL" +
+ Services.SERVICE + " TEXT NOT NULL" +
")");
db.execSQL("CREATE UNIQUE INDEX services_account ON " + Services._TABLE + " (" + Services.ACCOUNT_NAME + "," + Services.SERVICE + ")");
@@ -183,6 +184,34 @@ public class ServiceDB {
}
db.endTransaction();
}
+
+ @NonNull
+ public Account getServiceAccount(SQLiteDatabase db, long service) {
+ @Cleanup Cursor cursor = db.query(Services._TABLE, new String[]{Services.ACCOUNT_NAME}, Services.ID + "=?", new String[]{String.valueOf(service)}, null, null, null);
+ if (cursor.moveToNext()) {
+ return new Account(cursor.getString(0), Constants.ACCOUNT_TYPE);
+ } else
+ throw new IllegalArgumentException("Service not found");
+ }
+
+ @NonNull
+ public String getServiceType(SQLiteDatabase db, long service) {
+ @Cleanup Cursor cursor = db.query(Services._TABLE, new String[]{Services.SERVICE}, Services.ID + "=?", new String[]{String.valueOf(service)}, null, null, null);
+ if (cursor.moveToNext())
+ return cursor.getString(0);
+ else
+ throw new IllegalArgumentException("Service not found");
+ }
+
+ @Nullable
+ public Long getService(@NonNull SQLiteDatabase db, @NonNull Account account, String service) {
+ @Cleanup Cursor c = db.query(Services._TABLE, new String[]{Services.ID},
+ Services.ACCOUNT_NAME + "=? AND " + Services.SERVICE + "=?", new String[]{account.name, service}, null, null, null);
+ if (c.moveToNext())
+ return c.getLong(0);
+ else
+ return null;
+ }
}
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalAddressBook.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalAddressBook.java
index d8dde423..f503bfe3 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalAddressBook.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalAddressBook.java
@@ -123,7 +123,7 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
}
public LocalContact[] getDirtyContacts() throws ContactsStorageException {
- return (LocalContact[])queryContacts(RawContacts.DIRTY + "!= 0", null);
+ return (LocalContact[])queryContacts(RawContacts.DIRTY + "!= 0 AND " + RawContacts.DELETED + "== 0", null);
}
public LocalGroup[] getDeletedGroups() throws ContactsStorageException {
@@ -131,7 +131,7 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
}
public LocalGroup[] getDirtyGroups() throws ContactsStorageException {
- return (LocalGroup[])queryGroups(Groups.DIRTY + "!= 0", null);
+ return (LocalGroup[])queryGroups(Groups.DIRTY + "!= 0 AND " + Groups.DELETED + "== 0", null);
}
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java
index d5626a31..31d89d67 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java
@@ -32,7 +32,6 @@ import java.util.LinkedList;
import java.util.List;
import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.DavUtils;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.ical4android.AndroidCalendar;
import at.bitfire.ical4android.AndroidCalendarFactory;
@@ -86,7 +85,7 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
private static ContentValues valuesFromCollectionInfo(CollectionInfo info, boolean withColor) {
ContentValues values = new ContentValues();
values.put(Calendars.NAME, info.url);
- values.put(Calendars.CALENDAR_DISPLAY_NAME, !TextUtils.isEmpty(info.displayName) ? info.displayName : DavUtils.lastSegmentOfUrl(info.url));
+ values.put(Calendars.CALENDAR_DISPLAY_NAME, info.displayName);
if (withColor)
values.put(Calendars.CALENDAR_COLOR, info.color != null ? info.color : defaultColor);
@@ -131,7 +130,7 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
List dirty = new LinkedList<>();
// get dirty events which are required to have an increased SEQUENCE value
- for (LocalEvent event : (LocalEvent[])queryEvents(Events.DIRTY + "!=0 AND " + Events.ORIGINAL_ID + " IS NULL", null)) {
+ for (LocalEvent event : (LocalEvent[])queryEvents(Events.DIRTY + "!=0 AND " + Events.DELETED + "==0 AND " + Events.ORIGINAL_ID + " IS NULL", null)) {
if (event.getEvent().sequence == null) // sequence has not been assigned yet (i.e. this event was just locally created)
event.getEvent().sequence = 0;
else if (event.weAreOrganizer)
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalCollection.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalCollection.java
index 18994d70..bb97dbae 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalCollection.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalCollection.java
@@ -17,6 +17,7 @@ public interface LocalCollection {
LocalResource[] getDeleted() throws CalendarStorageException, ContactsStorageException;
LocalResource[] getWithoutFileName() throws CalendarStorageException, ContactsStorageException;
+ /** Dirty *non-deleted* entries */
LocalResource[] getDirty() throws CalendarStorageException, ContactsStorageException, FileNotFoundException;
LocalResource[] getAll() throws CalendarStorageException, ContactsStorageException;
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalContact.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalContact.java
index f12fa78e..74bab556 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalContact.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalContact.java
@@ -15,12 +15,16 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.RawContacts.Data;
import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
+import java.util.logging.Level;
-import at.bitfire.davdroid.BuildConfig;
+import at.bitfire.davdroid.App;
import at.bitfire.davdroid.model.UnknownProperties;
import at.bitfire.vcard4android.AndroidAddressBook;
import at.bitfire.vcard4android.AndroidContact;
@@ -29,24 +33,32 @@ import at.bitfire.vcard4android.BatchOperation;
import at.bitfire.vcard4android.CachedGroupMembership;
import at.bitfire.vcard4android.Contact;
import at.bitfire.vcard4android.ContactsStorageException;
-import ezvcard.Ezvcard;
+import ezvcard.VCardVersion;
-public class LocalContact extends AndroidContact implements LocalResource {
- static {
- Contact.productID = "+//IDN bitfire.at//DAVdroid/" + BuildConfig.VERSION_NAME + " vcard4android ez-vcard/" + Ezvcard.VERSION;
- }
+import static at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS;
+public class LocalContact extends AndroidContact implements LocalResource {
protected final Set
cachedGroupMemberships = new HashSet<>(),
groupMemberships = new HashSet<>();
- protected LocalContact(AndroidAddressBook addressBook, long id, String fileName, String eTag) {
- super(addressBook, id, fileName, eTag);
+ protected LocalContact(AndroidAddressBook addressBook, long id, String uuid, String eTag) {
+ super(addressBook, id, uuid, eTag);
+ }
+
+ public LocalContact(AndroidAddressBook addressBook, Contact contact, String uuid, String eTag) {
+ super(addressBook, contact, uuid, eTag);
+ }
+
+ public String getUuid() {
+ // The same now
+ return getFileName();
}
- public LocalContact(AndroidAddressBook addressBook, Contact contact, String fileName, String eTag) {
- super(addressBook, contact, fileName, eTag);
+ @Override
+ public boolean isLocalOnly() {
+ return TextUtils.isEmpty(getETag());
}
public void clearDirty(String eTag) throws ContactsStorageException {
@@ -64,7 +76,7 @@ public class LocalContact extends AndroidContact implements LocalResource {
public void updateFileNameAndUID(String uid) throws ContactsStorageException {
try {
- String newFileName = uid + ".vcf";
+ String newFileName = uid;
ContentValues values = new ContentValues(2);
values.put(COLUMN_FILENAME, newFileName);
@@ -77,6 +89,18 @@ public class LocalContact extends AndroidContact implements LocalResource {
}
}
+ @Override
+ public String getContent() throws IOException, ContactsStorageException {
+ final Contact contact;
+ contact = getContact();
+
+ App.log.log(Level.FINE, "Preparing upload of VCard " + getUuid(), contact);
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ contact.write(VCardVersion.V4_0, GROUP_VCARDS, os);
+
+ return os.toString();
+ }
@Override
protected void populateData(String mimeType, ContentValues row) {
@@ -181,11 +205,6 @@ public class LocalContact extends AndroidContact implements LocalResource {
return new LocalContact(addressBook, id, fileName, eTag);
}
- @Override
- public LocalContact newInstance(AndroidAddressBook addressBook, Contact contact, String fileName, String eTag) {
- return new LocalContact(addressBook, contact, fileName, eTag);
- }
-
@Override
public LocalContact[] newArray(int size) {
return new LocalContact[size];
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java
index 858d8d20..b2f52c98 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java
@@ -16,30 +16,33 @@ import android.os.RemoteException;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Events;
import android.support.annotation.NonNull;
+import android.text.TextUtils;
-import net.fortuna.ical4j.model.property.ProdId;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.logging.Level;
-import at.bitfire.davdroid.BuildConfig;
+import at.bitfire.davdroid.App;
import at.bitfire.ical4android.AndroidCalendar;
import at.bitfire.ical4android.AndroidEvent;
import at.bitfire.ical4android.AndroidEventFactory;
import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.ical4android.Event;
+import at.bitfire.vcard4android.ContactsStorageException;
import lombok.Getter;
import lombok.Setter;
@TargetApi(17)
public class LocalEvent extends AndroidEvent implements LocalResource {
- static {
- Event.prodId = new ProdId("+//IDN bitfire.at//DAVdroid/" + BuildConfig.VERSION_NAME + " ical4android ical4j/2.x");
- }
-
static final String COLUMN_ETAG = CalendarContract.Events.SYNC_DATA1,
- COLUMN_UID = Build.VERSION.SDK_INT >= 17 ? Events.UID_2445 : Events.SYNC_DATA2,
- COLUMN_SEQUENCE = CalendarContract.Events.SYNC_DATA3;
+ COLUMN_UID = Build.VERSION.SDK_INT >= 17 ? Events.UID_2445 : Events.SYNC_DATA2,
+ COLUMN_SEQUENCE = CalendarContract.Events.SYNC_DATA3;
- @Getter protected String fileName;
- @Getter @Setter protected String eTag;
+ @Getter
+ protected String fileName;
+ @Getter
+ @Setter
+ protected String eTag;
public boolean weAreOrganizer = true;
@@ -57,6 +60,26 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
}
}
+ @Override
+ public String getContent() throws IOException, ContactsStorageException, CalendarStorageException {
+ App.log.log(Level.FINE, "Preparing upload of event " + getFileName(), getEvent());
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ getEvent().write(os);
+
+ return os.toString();
+ }
+
+ @Override
+ public boolean isLocalOnly() {
+ return TextUtils.isEmpty(getETag());
+ }
+
+ @Override
+ public String getUuid() {
+ // Now the same
+ return getFileName();
+ }
/* process LocalEvent-specific fields */
@@ -83,7 +106,7 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
boolean buildException = recurrence != null;
Event eventToBuild = buildException ? recurrence : event;
- builder .withValue(COLUMN_UID, event.uid)
+ builder.withValue(COLUMN_UID, event.uid)
.withValue(COLUMN_SEQUENCE, eventToBuild.sequence)
.withValue(CalendarContract.Events.DIRTY, 0)
.withValue(CalendarContract.Events.DELETED, 0);
@@ -91,7 +114,7 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
if (buildException)
builder.withValue(Events.ORIGINAL_SYNC_ID, fileName);
else
- builder .withValue(Events._SYNC_ID, fileName)
+ builder.withValue(Events._SYNC_ID, fileName)
.withValue(COLUMN_ETAG, eTag);
}
@@ -100,7 +123,7 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
public void updateFileNameAndUID(String uid) throws CalendarStorageException {
try {
- String newFileName = uid + ".ics";
+ String newFileName = uid;
ContentValues values = new ContentValues(2);
values.put(Events._SYNC_ID, newFileName);
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalGroup.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalGroup.java
index 1f96f2a7..7e0d8c8e 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalGroup.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalGroup.java
@@ -23,11 +23,12 @@ import android.provider.ContactsContract.RawContacts.Data;
import org.apache.commons.lang3.ArrayUtils;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
-import at.bitfire.dav4android.Constants;
+import at.bitfire.davdroid.App;
import at.bitfire.vcard4android.AndroidAddressBook;
import at.bitfire.vcard4android.AndroidGroup;
import at.bitfire.vcard4android.AndroidGroupFactory;
@@ -36,10 +37,13 @@ import at.bitfire.vcard4android.CachedGroupMembership;
import at.bitfire.vcard4android.Contact;
import at.bitfire.vcard4android.ContactsStorageException;
import lombok.Cleanup;
+import lombok.Getter;
import lombok.ToString;
@ToString(callSuper=true)
public class LocalGroup extends AndroidGroup implements LocalResource {
+ @Getter
+ protected String uuid;
/** marshalled list of member UIDs, as sent by server */
public static final String COLUMN_PENDING_MEMBERS = Groups.SYNC3;
@@ -51,6 +55,15 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
super(addressBook, contact, fileName, eTag);
}
+ @Override
+ public String getContent() throws IOException, ContactsStorageException {
+ return null;
+ }
+
+ @Override
+ public boolean isLocalOnly() {
+ return false;
+ }
@Override
public void clearDirty(String eTag) throws ContactsStorageException {
@@ -145,7 +158,7 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
BatchOperation batch = new BatchOperation(addressBook.provider);
while (cursor != null && cursor.moveToNext()) {
long id = cursor.getLong(0);
- Constants.log.fine("Assigning members to group " + id);
+ App.log.fine("Assigning members to group " + id);
// delete all memberships and cached memberships for this group
batch.enqueue(new BatchOperation.Operation(
@@ -167,12 +180,12 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
// insert memberships
for (String uid : members) {
- Constants.log.fine("Assigning member: " + uid);
+ App.log.fine("Assigning member: " + uid);
try {
LocalContact member = addressBook.findContactByUID(uid);
member.addToGroup(batch, id);
} catch(FileNotFoundException e) {
- Constants.log.log(Level.WARNING, "Group member not found: " + uid, e);
+ App.log.log(Level.WARNING, "Group member not found: " + uid, e);
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalResource.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalResource.java
index bb18503c..3989299c 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalResource.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalResource.java
@@ -8,15 +8,20 @@
package at.bitfire.davdroid.resource;
+import java.io.IOException;
+
import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.vcard4android.ContactsStorageException;
public interface LocalResource {
-
+ String getUuid();
Long getId();
- String getFileName();
- String getETag();
+ /** True if doesn't exist on server yet, false otherwise. */
+ boolean isLocalOnly();
+
+ /** Returns a string of how this should be represented for example: vCard. */
+ String getContent() throws IOException, ContactsStorageException, CalendarStorageException;
int delete() throws CalendarStorageException, ContactsStorageException;
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalTask.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalTask.java
index fe9ad292..6c4d0ec3 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalTask.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalTask.java
@@ -14,26 +14,24 @@ import android.os.RemoteException;
import android.provider.CalendarContract.Events;
import android.support.annotation.NonNull;
-import net.fortuna.ical4j.model.property.ProdId;
-
import org.dmfs.provider.tasks.TaskContract.Tasks;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.text.ParseException;
-import at.bitfire.davdroid.BuildConfig;
import at.bitfire.ical4android.AndroidTask;
import at.bitfire.ical4android.AndroidTaskFactory;
import at.bitfire.ical4android.AndroidTaskList;
import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.ical4android.Task;
+import at.bitfire.vcard4android.ContactsStorageException;
import lombok.Getter;
import lombok.Setter;
public class LocalTask extends AndroidTask implements LocalResource {
- static {
- Task.prodId = new ProdId("+//IDN bitfire.at//DAVdroid/" + BuildConfig.VERSION_NAME + " ical4android ical4j/2.x");
- }
+ @Getter
+ protected String uuid;
static final String COLUMN_ETAG = Tasks.SYNC1,
COLUMN_UID = Tasks.SYNC2,
@@ -56,6 +54,15 @@ public class LocalTask extends AndroidTask implements LocalResource {
}
}
+ @Override
+ public String getContent() throws IOException, ContactsStorageException {
+ return null;
+ }
+
+ @Override
+ public boolean isLocalOnly() {
+ return false;
+ }
/* process LocalTask-specific fields */
diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalTaskList.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalTaskList.java
index b293a7fa..e08a264d 100644
--- a/app/src/main/java/at/bitfire/davdroid/resource/LocalTaskList.java
+++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalTaskList.java
@@ -18,14 +18,12 @@ import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.support.annotation.NonNull;
-import android.text.TextUtils;
import org.dmfs.provider.tasks.TaskContract.TaskLists;
import org.dmfs.provider.tasks.TaskContract.Tasks;
import java.io.FileNotFoundException;
-import at.bitfire.davdroid.DavUtils;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.ical4android.AndroidTaskList;
import at.bitfire.ical4android.AndroidTaskListFactory;
@@ -71,7 +69,7 @@ public class LocalTaskList extends AndroidTaskList implements LocalCollection {
private static ContentValues valuesFromCollectionInfo(CollectionInfo info, boolean withColor) {
ContentValues values = new ContentValues();
values.put(TaskLists._SYNC_ID, info.url);
- values.put(TaskLists.LIST_NAME, !TextUtils.isEmpty(info.displayName) ? info.displayName : DavUtils.lastSegmentOfUrl(info.url));
+ values.put(TaskLists.LIST_NAME, info.displayName);
if (withColor)
values.put(TaskLists.LIST_COLOR, info.color != null ? info.color : defaultColor);
@@ -97,7 +95,7 @@ public class LocalTaskList extends AndroidTaskList implements LocalCollection {
@Override
public LocalResource[] getDirty() throws CalendarStorageException, FileNotFoundException {
- LocalTask[] tasks = (LocalTask[])queryTasks(Tasks._DIRTY + "!=0", null);
+ LocalTask[] tasks = (LocalTask[])queryTasks(Tasks._DIRTY + "!=0 AND " + Tasks._DELETED + "== 0", null);
if (tasks != null)
for (LocalTask task : tasks) {
if (task.getTask().sequence == null) // sequence has not been assigned yet (i.e. this task was just locally created)
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java
index 6c3d6698..9d57f24d 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarSyncManager.java
@@ -14,34 +14,18 @@ import android.content.SyncResult;
import android.os.Bundle;
import org.apache.commons.codec.Charsets;
-import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-
-import at.bitfire.dav4android.DavCalendar;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.CalendarData;
-import at.bitfire.dav4android.property.GetCTag;
-import at.bitfire.dav4android.property.GetContentType;
-import at.bitfire.dav4android.property.GetETag;
+
import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.ArrayUtils;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalEntryManager;
import at.bitfire.davdroid.resource.LocalCalendar;
import at.bitfire.davdroid.resource.LocalEvent;
import at.bitfire.davdroid.resource.LocalResource;
@@ -49,23 +33,20 @@ import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.ical4android.Event;
import at.bitfire.ical4android.InvalidCalendarException;
import at.bitfire.vcard4android.ContactsStorageException;
-import lombok.Cleanup;
import okhttp3.HttpUrl;
-import okhttp3.MediaType;
-import okhttp3.RequestBody;
-import okhttp3.ResponseBody;
/**
- * Synchronization manager for CalDAV collections; handles events ({@code VEVENT}).
+ * Synchronization manager for CardDAV collections; handles contacts and groups.
*/
public class CalendarSyncManager extends SyncManager {
+ protected static final int MAX_MULTIGET = 10;
- protected static final int MAX_MULTIGET = 20;
-
+ final private HttpUrl remote;
- public CalendarSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, SyncResult result, LocalCalendar calendar) throws InvalidAccountException {
+ public CalendarSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, SyncResult result, LocalCalendar calendar, HttpUrl remote) throws InvalidAccountException {
super(context, account, settings, extras, authority, result, "calendar/" + calendar.getId());
localCollection = calendar;
+ this.remote = remote;
}
@Override
@@ -78,16 +59,14 @@ public class CalendarSyncManager extends SyncManager {
return context.getString(R.string.sync_error_calendar, account.name);
}
-
@Override
- protected void prepare() {
- collectionURL = HttpUrl.parse(localCalendar().getName());
- davCollection = new DavCalendar(httpClient, collectionURL);
+ protected void prepare() throws ContactsStorageException {
+ journal = new JournalEntryManager(httpClient, remote, localCalendar().getName());
}
@Override
- protected void queryCapabilities() throws DavException, IOException, HttpException {
- davCollection.propfind(0, GetCTag.NAME);
+ protected void applyLocalEntries() throws IOException, Exceptions.HttpException, ContactsStorageException, CalendarStorageException {
+
}
@Override
@@ -97,139 +76,55 @@ public class CalendarSyncManager extends SyncManager {
localCalendar().processDirtyExceptions();
}
- @Override
- protected RequestBody prepareUpload(LocalResource resource) throws IOException, CalendarStorageException {
- LocalEvent local = (LocalEvent)resource;
- App.log.log(Level.FINE, "Preparing upload of event " + local.getFileName(), local.getEvent());
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- local.getEvent().write(os);
+ // helpers
- return RequestBody.create(
- DavCalendar.MIME_ICALENDAR,
- os.toByteArray()
- );
+ private LocalCalendar localCalendar() {
+ return (LocalCalendar) localCollection;
}
- @Override
- protected void listRemote() throws IOException, HttpException, DavException {
- // calculate time range limits
- Date limitStart = null;
- Integer pastDays = settings.getTimeRangePastDays();
- if (pastDays != null) {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_MONTH, -pastDays);
- limitStart = calendar.getTime();
- }
+ protected void processSyncEntry(SyncEntry cEntry) throws IOException, ContactsStorageException, CalendarStorageException, InvalidCalendarException {
+ InputStream is = new ByteArrayInputStream(cEntry.getContent().getBytes(Charsets.UTF_8));
- // fetch list of remote VEVENTs and build hash table to index file name
- davCalendar().calendarQuery("VEVENT", limitStart, null);
+ Event[] events = Event.fromStream(is, Charsets.UTF_8);
+ if (events.length == 0) {
+ App.log.warning("Received VCard without data, ignoring");
+ return;
+ } else if (events.length > 1)
+ App.log.warning("Received multiple VCALs, using first one");
- remoteResources = new HashMap<>(davCollection.members.size());
- for (DavResource iCal : davCollection.members) {
- String fileName = iCal.fileName();
- App.log.fine("Found remote VEVENT: " + fileName);
- remoteResources.put(fileName, iCal);
- }
- }
+ Event event = events[0];
- @Override
- protected void downloadRemote() throws IOException, HttpException, DavException, CalendarStorageException {
- App.log.info("Downloading " + toDownload.size() + " events (" + MAX_MULTIGET + " at once)");
-
- // download new/updated iCalendars from server
- for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
- if (Thread.interrupted())
- return;
- App.log.info("Downloading " + StringUtils.join(bunch, ", "));
-
- if (bunch.length == 1) {
- // only one contact, use GET
- DavResource remote = bunch[0];
-
- ResponseBody body = remote.get("text/calendar");
-
- // CalDAV servers MUST return ETag on GET [https://tools.ietf.org/html/rfc4791#section-5.3.4]
- GetETag eTag = (GetETag)remote.properties.get(GetETag.NAME);
- if (eTag == null || StringUtils.isEmpty(eTag.eTag))
- throw new DavException("Received CalDAV GET response without ETag for " + remote.location);
-
- Charset charset = Charsets.UTF_8;
- MediaType contentType = body.contentType();
- if (contentType != null)
- charset = contentType.charset(Charsets.UTF_8);
-
- @Cleanup InputStream stream = body.byteStream();
- processVEvent(remote.fileName(), eTag.eTag, stream, charset);
-
- } else {
- // multiple contacts, use multi-get
- List urls = new LinkedList<>();
- for (DavResource remote : bunch)
- urls.add(remote.location);
- davCalendar().multiget(urls.toArray(new HttpUrl[urls.size()]));
-
- // process multiget results
- for (DavResource remote : davCollection.members) {
- String eTag;
- GetETag getETag = (GetETag)remote.properties.get(GetETag.NAME);
- if (getETag != null)
- eTag = getETag.eTag;
- else
- throw new DavException("Received multi-get response without ETag");
-
- Charset charset = Charsets.UTF_8;
- GetContentType getContentType = (GetContentType)remote.properties.get(GetContentType.NAME);
- if (getContentType != null && getContentType.type != null) {
- MediaType type = MediaType.parse(getContentType.type);
- if (type != null)
- charset = type.charset(Charsets.UTF_8);
- }
-
- CalendarData calendarData = (CalendarData)remote.properties.get(CalendarData.NAME);
- if (calendarData == null || calendarData.iCalendar == null)
- throw new DavException("Received multi-get response without address data");
-
- @Cleanup InputStream stream = new ByteArrayInputStream(calendarData.iCalendar.getBytes());
- processVEvent(remote.fileName(), eTag, stream, charset);
- }
+ if (cEntry.isAction(SyncEntry.Actions.ADD) || cEntry.isAction(SyncEntry.Actions.CHANGE)) {
+ LocalResource local = processEvent(event);
+
+ if (local != null) {
+ localResources.put(local.getUuid(), local);
}
+
+ } else {
+ LocalResource local = localResources.get(event.uid);
+ App.log.info("Removing local record #" + local.getId() + " which has been deleted on the server");
+ localResources.remove(local.getUuid());
+ local.delete();
}
}
-
- // helpers
-
- private LocalCalendar localCalendar() { return ((LocalCalendar)localCollection); }
- private DavCalendar davCalendar() { return (DavCalendar)davCollection; }
-
- private void processVEvent(String fileName, String eTag, InputStream stream, Charset charset) throws IOException, CalendarStorageException {
- Event[] events;
- try {
- events = Event.fromStream(stream, charset);
- } catch (InvalidCalendarException e) {
- App.log.log(Level.SEVERE, "Received invalid iCalendar, ignoring", e);
- return;
+ private LocalResource processEvent(final Event newData) throws IOException, ContactsStorageException, CalendarStorageException {
+ // delete local event, if it exists
+ LocalEvent localEvent = (LocalEvent) localResources.get(newData.uid);
+ if (localEvent != null) {
+ App.log.info("Updating " + newData.uid + " in local calendar");
+ localEvent.setETag(newData.uid);
+ localEvent.update(newData);
+ syncResult.stats.numUpdates++;
+ } else {
+ App.log.info("Adding " + newData.uid + " to local calendar");
+ localEvent = new LocalEvent(localCalendar(), newData, newData.uid, null);
+ localEvent.add();
+ syncResult.stats.numInserts++;
}
- if (events.length == 1) {
- Event newData = events[0];
-
- // delete local event, if it exists
- LocalEvent localEvent = (LocalEvent)localResources.get(fileName);
- if (localEvent != null) {
- App.log.info("Updating " + fileName + " in local calendar");
- localEvent.setETag(eTag);
- localEvent.update(newData);
- syncResult.stats.numUpdates++;
- } else {
- App.log.info("Adding " + fileName + " to local calendar");
- localEvent = new LocalEvent(localCalendar(), newData, fileName, eTag);
- localEvent.add();
- syncResult.stats.numInserts++;
- }
- } else
- App.log.severe("Received VCALENDAR with not exactly one VEVENT with UID, but without RECURRENCE-ID; ignoring " + fileName);
+ return localEvent;
}
-
}
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarsSyncAdapterService.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarsSyncAdapterService.java
index 67f617c8..e6937a3e 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarsSyncAdapterService.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarsSyncAdapterService.java
@@ -18,11 +18,9 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -38,6 +36,7 @@ import at.bitfire.davdroid.model.ServiceDB.Services;
import at.bitfire.davdroid.resource.LocalCalendar;
import at.bitfire.ical4android.CalendarStorageException;
import lombok.Cleanup;
+import okhttp3.HttpUrl;
public class CalendarsSyncAdapterService extends SyncAdapterService {
@@ -47,7 +46,7 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
}
- private static class SyncAdapter extends SyncAdapterService.SyncAdapter {
+ private static class SyncAdapter extends SyncAdapterService.SyncAdapter {
public SyncAdapter(Context context) {
super(context);
@@ -62,29 +61,33 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
return;
- updateLocalCalendars(provider, account, settings);
+ HttpUrl principal = updateLocalCalendars(provider, account, settings);
- for (LocalCalendar calendar : (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
- App.log.info("Synchronizing calendar #" + calendar.getId() + ", URL: " + calendar.getName());
- CalendarSyncManager syncManager = new CalendarSyncManager(getContext(), account, settings, extras, authority, syncResult, calendar);
+ for (LocalCalendar calendar : (LocalCalendar[]) LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
+ App.log.info("Synchronizing calendar #" + calendar.getId() + ", URL: " + calendar.getName());
+ CalendarSyncManager syncManager = new CalendarSyncManager(getContext(), account, settings, extras, authority, syncResult, calendar, principal);
syncManager.performSync();
}
- } catch(CalendarStorageException|SQLiteException e) {
+ } catch (CalendarStorageException | SQLiteException e) {
App.log.log(Level.SEVERE, "Couldn't prepare local calendars", e);
syncResult.databaseError = true;
- } catch(InvalidAccountException e) {
+ } catch (InvalidAccountException e) {
App.log.log(Level.SEVERE, "Couldn't get account settings", e);
}
App.log.info("Calendar sync complete");
}
- private void updateLocalCalendars(ContentProviderClient provider, Account account, AccountSettings settings) throws CalendarStorageException {
- SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
+ private HttpUrl updateLocalCalendars(ContentProviderClient provider, Account account, AccountSettings settings) throws CalendarStorageException {
+ HttpUrl ret = null;
+ ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
try {
// enumerate remote and local calendars
SQLiteDatabase db = dbHelper.getReadableDatabase();
- Long service = getService(db, account);
+ Long service = dbHelper.getService(db, account, Services.SERVICE_CALDAV);
+
+ ret = HttpUrl.get(settings.getUri());
+
Map remote = remoteCalendars(db, service);
LocalCalendar[] local = (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null);
@@ -116,16 +119,8 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
} finally {
dbHelper.close();
}
- }
- @Nullable
- Long getService(@NonNull SQLiteDatabase db, @NonNull Account account) {
- @Cleanup Cursor c = db.query(Services._TABLE, new String[] { Services.ID },
- Services.ACCOUNT_NAME + "=? AND " + Services.SERVICE + "=?", new String[] { account.name, Services.SERVICE_CALDAV }, null, null, null);
- if (c.moveToNext())
- return c.getLong(0);
- else
- return null;
+ return ret;
}
@NonNull
@@ -134,7 +129,7 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
if (service != null) {
@Cleanup Cursor cursor = db.query(Collections._TABLE, null,
Collections.SERVICE_ID + "=? AND " + Collections.SUPPORTS_VEVENT + "!=0 AND " + Collections.SYNC,
- new String[] { String.valueOf(service) }, null, null, null);
+ new String[]{String.valueOf(service)}, null, null, null);
while (cursor.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(cursor, values);
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncAdapterService.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncAdapterService.java
index c179d908..5dd84b3c 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncAdapterService.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncAdapterService.java
@@ -17,7 +17,6 @@ import android.content.SyncResult;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -31,6 +30,7 @@ import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.model.ServiceDB;
import at.bitfire.davdroid.model.ServiceDB.Collections;
import lombok.Cleanup;
+import okhttp3.HttpUrl;
public class ContactsSyncAdapterService extends SyncAdapterService {
@@ -40,7 +40,7 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
}
- private static class ContactsSyncAdapter extends SyncAdapter {
+ private static class ContactsSyncAdapter extends SyncAdapter {
public ContactsSyncAdapter(Context context) {
super(context);
@@ -50,25 +50,23 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
super.onPerformSync(account, extras, authority, provider, syncResult);
- SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
+ ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
try {
AccountSettings settings = new AccountSettings(getContext(), account);
if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
return;
SQLiteDatabase db = dbHelper.getReadableDatabase();
- Long service = getService(db, account);
+ Long service = dbHelper.getService(db, account, ServiceDB.Services.SERVICE_CARDDAV);
if (service != null) {
- CollectionInfo remote = remoteAddressBook(db, service);
- if (remote != null)
- try {
- ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, settings, extras, authority, provider, syncResult, remote);
- syncManager.performSync();
- } catch(InvalidAccountException e) {
- App.log.log(Level.SEVERE, "Couldn't get account settings", e);
- }
- else
- App.log.info("No address book collection selected for synchronization");
+ HttpUrl principal = HttpUrl.get(settings.getUri());
+ CollectionInfo info = remoteAddressBook(db, service);
+ try {
+ ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, settings, extras, authority, provider, syncResult, principal, info);
+ syncManager.performSync();
+ } catch (InvalidAccountException e) {
+ App.log.log(Level.SEVERE, "Couldn't get account settings", e);
+ }
} else
App.log.info("No CardDAV service found in DB");
} catch (InvalidAccountException e) {
@@ -80,20 +78,10 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
App.log.info("Address book sync complete");
}
- @Nullable
- private Long getService(@NonNull SQLiteDatabase db, @NonNull Account account) {
- @Cleanup Cursor c = db.query(ServiceDB.Services._TABLE, new String[] { ServiceDB.Services.ID },
- ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?", new String[] { account.name, ServiceDB.Services.SERVICE_CARDDAV }, null, null, null);
- if (c.moveToNext())
- return c.getLong(0);
- else
- return null;
- }
-
@Nullable
private CollectionInfo remoteAddressBook(@NonNull SQLiteDatabase db, long service) {
@Cleanup Cursor c = db.query(Collections._TABLE, null,
- Collections.SERVICE_ID + "=? AND " + Collections.SYNC, new String[] { String.valueOf(service) }, null, null, null);
+ Collections.SERVICE_ID + "=? AND " + Collections.SYNC, new String[]{String.valueOf(service)}, null, null, null);
if (c.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(c, values);
@@ -101,7 +89,6 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
} else
return null;
}
-
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java
index 6ac1bcec..d066eeeb 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/ContactsSyncManager.java
@@ -10,123 +10,58 @@ package at.bitfire.davdroid.syncadapter;
import android.accounts.Account;
import android.content.ContentProviderClient;
-import android.content.ContentProviderOperation;
-import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
-import android.database.Cursor;
import android.os.Bundle;
-import android.os.RemoteException;
import android.provider.ContactsContract;
-import android.provider.ContactsContract.Groups;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
import org.apache.commons.codec.Charsets;
-import org.apache.commons.collections4.SetUtils;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
import java.util.logging.Level;
-import at.bitfire.dav4android.DavAddressBook;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.AddressData;
-import at.bitfire.dav4android.property.GetCTag;
-import at.bitfire.dav4android.property.GetContentType;
-import at.bitfire.dav4android.property.GetETag;
-import at.bitfire.dav4android.property.ResourceType;
-import at.bitfire.dav4android.property.SupportedAddressData;
import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.ArrayUtils;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.HttpClient;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.JournalEntryManager;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.resource.LocalAddressBook;
import at.bitfire.davdroid.resource.LocalContact;
import at.bitfire.davdroid.resource.LocalGroup;
import at.bitfire.davdroid.resource.LocalResource;
import at.bitfire.ical4android.CalendarStorageException;
-import at.bitfire.vcard4android.BatchOperation;
import at.bitfire.vcard4android.Contact;
import at.bitfire.vcard4android.ContactsStorageException;
-import at.bitfire.vcard4android.GroupMethod;
-import ezvcard.VCardVersion;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import okhttp3.HttpUrl;
-import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
-import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* Synchronization manager for CardDAV collections; handles contacts and groups.
- *
- *
Group handling differs according to the {@link #groupMethod}. There are two basic methods to
- * handle/manage groups:
- *
- * {@code CATEGORIES}: groups memberships are attached to each contact and represented as
- * "category". When a group is dirty or has been deleted, all its members have to be set to
- * dirty, too (because they have to be uploaded without the respective category). This
- * is done in {@link #prepareDirty()}. Empty groups can be deleted without further processing,
- * which is done in {@link #postProcess()} because groups may become empty after downloading
- * updated remoted contacts.
- * Groups as separate VCards: individual and group contacts (with a list of member UIDs) are
- * distinguished. When a local group is dirty, its members don't need to be set to dirty.
- *
- * However, when a contact is dirty, it has
- * to be checked whether its group memberships have changed. In this case, the respective
- * groups have to be set to dirty. For instance, if contact A is in group G and H, and then
- * group membership of G is removed, the contact will be set to dirty because of the changed
- * {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}. DAVdroid will
- * then have to check whether the group memberships have actually changed, and if so,
- * all affected groups have to be set to dirty. To detect changes in group memberships,
- * DAVdroid always mirrors all {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}
- * data rows in respective {@link at.bitfire.vcard4android.CachedGroupMembership} rows.
- * If the cached group memberships are not the same as the current group member ships, the
- * difference set (in our example G, because its in the cached memberships, but not in the
- * actual ones) is marked as dirty. This is done in {@link #prepareDirty()}.
- * When downloading remote contacts, groups (+ member information) may be received
- * by the actual members. Thus, the member lists have to be cached until all VCards
- * are received. This is done by caching the member UIDs of each group in
- * {@link LocalGroup#COLUMN_PENDING_MEMBERS}. In {@link #postProcess()},
- * these "pending memberships" are assigned to the actual contacs and then cleaned up.
- *
- *
*/
public class ContactsSyncManager extends SyncManager {
protected static final int MAX_MULTIGET = 10;
final private ContentProviderClient provider;
- final private CollectionInfo remote;
+ final private HttpUrl remote;
+ final private CollectionInfo info;
- private boolean hasVCard4;
- private GroupMethod groupMethod;
-
-
- public ContactsSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, ContentProviderClient provider, SyncResult result, CollectionInfo remote) throws InvalidAccountException {
+ public ContactsSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, ContentProviderClient provider, SyncResult result, HttpUrl principal, CollectionInfo info) throws InvalidAccountException {
super(context, account, settings, extras, authority, result, "addressBook");
this.provider = provider;
- this.remote = remote;
+ this.remote = principal;
+ this.info = info;
}
@Override
@@ -139,20 +74,12 @@ public class ContactsSyncManager extends SyncManager {
return context.getString(R.string.sync_error_contacts, account.name);
}
-
@Override
- protected void prepare() throws ContactsStorageException {
+ protected void prepare() throws ContactsStorageException, CalendarStorageException {
// prepare local address book
localCollection = new LocalAddressBook(account, provider);
LocalAddressBook localAddressBook = localAddressBook();
-
- String url = remote.url;
- String lastUrl = localAddressBook.getURL();
- if (!url.equals(lastUrl)) {
- App.log.info("Selected address book has changed from " + lastUrl + " to " + url + ", deleting all local contacts");
- localAddressBook.deleteAll();
- localAddressBook.setURL(remote.url);
- }
+ localAddressBook.setURL(info.url);
// set up Contacts Provider Settings
ContentValues values = new ContentValues(2);
@@ -160,22 +87,12 @@ public class ContactsSyncManager extends SyncManager {
values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1);
localAddressBook.updateSettings(values);
- collectionURL = HttpUrl.parse(url);
- davCollection = new DavAddressBook(httpClient, collectionURL);
+ journal = new JournalEntryManager(httpClient, remote, info.url);
}
@Override
- protected void queryCapabilities() throws DavException, IOException, HttpException {
- // prepare remote address book
- davCollection.propfind(0, SupportedAddressData.NAME, GetCTag.NAME);
- SupportedAddressData supportedAddressData = (SupportedAddressData)davCollection.properties.get(SupportedAddressData.NAME);
- hasVCard4 = supportedAddressData != null && supportedAddressData.hasVCard4();
- App.log.info("Server advertises VCard/4 support: " + hasVCard4);
-
- groupMethod = settings.getGroupMethod();
- App.log.info("Contact group method: " + groupMethod);
+ protected void applyLocalEntries() throws IOException, ContactsStorageException, CalendarStorageException {
- localAddressBook().includeGroups = groupMethod == GroupMethod.GROUP_VCARDS;
}
@Override
@@ -184,232 +101,75 @@ public class ContactsSyncManager extends SyncManager {
LocalAddressBook addressBook = localAddressBook();
- if (groupMethod == GroupMethod.CATEGORIES) {
- /* groups memberships are represented as contact CATEGORIES */
+ /* groups as separate VCards: thtere are group contacts and individual contacts */
- // groups with DELETED=1: set all members to dirty, then remove group
- for (LocalGroup group : addressBook.getDeletedGroups()) {
- App.log.fine("Finally removing group " + group);
- // useless because Android deletes group memberships as soon as a group is set to DELETED:
- // group.markMembersDirty();
- group.delete();
- }
+ // mark groups with changed members as dirty
- // groups with DIRTY=1: mark all memberships as dirty, then clean DIRTY flag of group
- for (LocalGroup group : addressBook.getDirtyGroups()) {
- App.log.fine("Marking members of modified group " + group + " as dirty");
- group.markMembersDirty();
- group.clearDirty(null);
- }
- } else {
- /* groups as separate VCards: there are group contacts and individual contacts */
+ // FIXME: add back
- // mark groups with changed members as dirty
- BatchOperation batch = new BatchOperation(addressBook.provider);
- for (LocalContact contact : addressBook.getDirtyContacts())
- try {
- App.log.fine("Looking for changed group memberships of contact " + contact.getFileName());
- Set cachedGroups = contact.getCachedGroupMemberships(),
- currentGroups = contact.getGroupMemberships();
- for (Long groupID : SetUtils.disjunction(cachedGroups, currentGroups)) {
- App.log.fine("Marking group as dirty: " + groupID);
- batch.enqueue(new BatchOperation.Operation(
- ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, groupID)))
- .withValue(Groups.DIRTY, 1)
- .withYieldAllowed(true)
- ));
- }
- } catch(FileNotFoundException ignored) {
- }
- batch.commit();
- }
- }
-
- @Override
- protected RequestBody prepareUpload(@NonNull LocalResource resource) throws IOException, ContactsStorageException {
- final Contact contact;
- if (resource instanceof LocalContact) {
- LocalContact local = ((LocalContact)resource);
- contact = local.getContact();
-
- if (groupMethod == GroupMethod.CATEGORIES) {
- // add groups as CATEGORIES
- for (long groupID : local.getGroupMemberships()) {
- try {
- @Cleanup Cursor c = provider.query(
- localAddressBook().syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, groupID)),
- new String[] { Groups.TITLE },
- null, null,
- null
- );
- if (c != null && c.moveToNext()) {
- String title = c.getString(0);
- if (!TextUtils.isEmpty(title))
- contact.categories.add(title);
- }
- } catch(RemoteException e) {
- throw new ContactsStorageException("Couldn't find group for adding CATEGORIES", e);
- }
- }
- }
- } else if (resource instanceof LocalGroup)
- contact = ((LocalGroup)resource).getContact();
- else
- throw new IllegalArgumentException("Argument must be LocalContact or LocalGroup");
-
- App.log.log(Level.FINE, "Preparing upload of VCard " + resource.getFileName(), contact);
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- contact.write(hasVCard4 ? VCardVersion.V4_0 : VCardVersion.V3_0, groupMethod, os);
-
- return RequestBody.create(
- hasVCard4 ? DavAddressBook.MIME_VCARD4 : DavAddressBook.MIME_VCARD3_UTF8,
- os.toByteArray()
- );
- }
-
- @Override
- protected void listRemote() throws IOException, HttpException, DavException {
- // fetch list of remote VCards and build hash table to index file name
- davAddressBook().propfind(1, ResourceType.NAME, GetETag.NAME);
-
- remoteResources = new HashMap<>(davCollection.members.size());
- for (DavResource vCard : davCollection.members) {
- // ignore member collections
- ResourceType type = (ResourceType)vCard.properties.get(ResourceType.NAME);
- if (type != null && type.types.contains(ResourceType.COLLECTION))
- continue;
-
- String fileName = vCard.fileName();
- App.log.fine("Found remote VCard: " + fileName);
- remoteResources.put(fileName, vCard);
- }
- }
-
- @Override
- protected void downloadRemote() throws IOException, HttpException, DavException, ContactsStorageException {
- App.log.info("Downloading " + toDownload.size() + " contacts (" + MAX_MULTIGET + " at once)");
-
- // prepare downloader which may be used to download external resource like contact photos
- Contact.Downloader downloader = new ResourceDownloader(collectionURL);
-
- // download new/updated VCards from server
- for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
- if (Thread.interrupted())
- return;
-
- App.log.info("Downloading " + StringUtils.join(bunch, ", "));
-
- if (bunch.length == 1) {
- // only one contact, use GET
- DavResource remote = bunch[0];
-
- ResponseBody body = remote.get("text/vcard;version=4.0, text/vcard;charset=utf-8;q=0.8, text/vcard;q=0.5");
-
- // CardDAV servers MUST return ETag on GET [https://tools.ietf.org/html/rfc6352#section-6.3.2.3]
- GetETag eTag = (GetETag)remote.properties.get(GetETag.NAME);
- if (eTag == null || StringUtils.isEmpty(eTag.eTag))
- throw new DavException("Received CardDAV GET response without ETag for " + remote.location);
-
- Charset charset = Charsets.UTF_8;
- MediaType contentType = body.contentType();
- if (contentType != null)
- charset = contentType.charset(Charsets.UTF_8);
-
- @Cleanup InputStream stream = body.byteStream();
- processVCard(remote.fileName(), eTag.eTag, stream, charset, downloader);
-
- } else {
- // multiple contacts, use multi-get
- List urls = new LinkedList<>();
- for (DavResource remote : bunch)
- urls.add(remote.location);
- davAddressBook().multiget(urls.toArray(new HttpUrl[urls.size()]), hasVCard4);
-
- // process multiget results
- for (DavResource remote : davCollection.members) {
- String eTag;
- GetETag getETag = (GetETag)remote.properties.get(GetETag.NAME);
- if (getETag != null)
- eTag = getETag.eTag;
- else
- throw new DavException("Received multi-get response without ETag");
-
- Charset charset = Charsets.UTF_8;
- GetContentType getContentType = (GetContentType)remote.properties.get(GetContentType.NAME);
- if (getContentType != null && getContentType.type != null) {
- MediaType type = MediaType.parse(getContentType.type);
- if (type != null)
- charset = type.charset(Charsets.UTF_8);
- }
-
- AddressData addressData = (AddressData)remote.properties.get(AddressData.NAME);
- if (addressData == null || addressData.vCard == null)
- throw new DavException("Received multi-get response without address data");
-
- @Cleanup InputStream stream = new ByteArrayInputStream(addressData.vCard.getBytes());
- processVCard(remote.fileName(), eTag, stream, charset, downloader);
- }
- }
- }
}
@Override
protected void postProcess() throws CalendarStorageException, ContactsStorageException {
- if (groupMethod == GroupMethod.CATEGORIES) {
- /* VCard3 group handling: groups memberships are represented as contact CATEGORIES */
-
- // remove empty groups
- App.log.info("Removing empty groups");
- localAddressBook().removeEmptyGroups();
-
- } else {
- /* VCard4 group handling: there are group contacts and individual contacts */
- App.log.info("Assigning memberships of downloaded contact groups");
- LocalGroup.applyPendingMemberships(localAddressBook());
- }
+ /* VCard4 group handling: there are group contacts and individual contacts */
+ App.log.info("Assigning memberships of downloaded contact groups");
+ LocalGroup.applyPendingMemberships(localAddressBook());
}
// helpers
- private DavAddressBook davAddressBook() { return (DavAddressBook)davCollection; }
- private LocalAddressBook localAddressBook() { return (LocalAddressBook)localCollection; }
+ private LocalAddressBook localAddressBook() {
+ return (LocalAddressBook) localCollection;
+ }
+
+ protected void processSyncEntry(SyncEntry cEntry) throws IOException, ContactsStorageException, CalendarStorageException {
+ InputStream is = new ByteArrayInputStream(cEntry.getContent().getBytes(Charsets.UTF_8));
+ // FIXME: Probably cache this and enable it. prepare downloader which may be used to download external resource like contact photos
+ // Contact.Downloader downloader = new ResourceDownloader(collectionURL);
- private void processVCard(String fileName, String eTag, InputStream stream, Charset charset, Contact.Downloader downloader) throws IOException, ContactsStorageException {
- App.log.info("Processing CardDAV resource " + fileName);
- Contact[] contacts = Contact.fromStream(stream, charset, downloader);
+ Contact[] contacts = Contact.fromStream(is, Charsets.UTF_8, null);
if (contacts.length == 0) {
App.log.warning("Received VCard without data, ignoring");
return;
} else if (contacts.length > 1)
App.log.warning("Received multiple VCards, using first one");
- final Contact newData = contacts[0];
+ Contact contact = contacts[0];
+
+ if (cEntry.isAction(SyncEntry.Actions.ADD) || cEntry.isAction(SyncEntry.Actions.CHANGE)) {
+ LocalResource local = processContact(contact);
- if (groupMethod == GroupMethod.CATEGORIES && newData.group) {
- groupMethod = GroupMethod.GROUP_VCARDS;
- App.log.warning("Received group VCard although group method is CATEGORIES. Deleting all groups; new group method: " + groupMethod);
- localAddressBook().removeGroups();
- settings.setGroupMethod(groupMethod);
+ if (local != null) {
+ localResources.put(local.getUuid(), local);
+ }
+
+ } else {
+ LocalResource local = localResources.get(contact.uid);
+ App.log.info("Removing local record #" + local.getId() + " which has been deleted on the server");
+ localResources.remove(local.getUuid());
+ local.delete();
}
+ }
+ private LocalResource processContact(final Contact newData) throws IOException, ContactsStorageException {
+ String uuid = newData.uid;
// update local contact, if it exists
- LocalResource local = localResources.get(fileName);
+ LocalResource local = localResources.get(uuid);
if (local != null) {
- App.log.log(Level.INFO, "Updating " + fileName + " in local address book", newData);
+ App.log.log(Level.INFO, "Updating " + uuid + " in local address book", newData);
if (local instanceof LocalGroup && newData.group) {
// update group
- LocalGroup group = (LocalGroup)local;
- group.eTag = eTag;
+ LocalGroup group = (LocalGroup) local;
+ group.eTag = uuid;
group.updateFromServer(newData);
syncResult.stats.numUpdates++;
} else if (local instanceof LocalContact && !newData.group) {
// update contact
- LocalContact contact = (LocalContact)local;
- contact.eTag = eTag;
+ LocalContact contact = (LocalContact) local;
+ contact.eTag = uuid;
contact.update(newData);
syncResult.stats.numUpdates++;
@@ -418,7 +178,7 @@ public class ContactsSyncManager extends SyncManager {
try {
local.delete();
local = null;
- } catch(CalendarStorageException e) {
+ } catch (CalendarStorageException e) {
// CalendarStorageException is not used by LocalGroup and LocalContact
}
}
@@ -427,13 +187,13 @@ public class ContactsSyncManager extends SyncManager {
if (local == null) {
if (newData.group) {
App.log.log(Level.INFO, "Creating local group", newData);
- LocalGroup group = new LocalGroup(localAddressBook(), newData, fileName, eTag);
+ LocalGroup group = new LocalGroup(localAddressBook(), newData, uuid, null);
group.create();
local = group;
} else {
App.log.log(Level.INFO, "Creating local contact", newData);
- LocalContact contact = new LocalContact(localAddressBook(), newData, fileName, eTag);
+ LocalContact contact = new LocalContact(localAddressBook(), newData, uuid, null);
contact.create();
local = contact;
@@ -441,25 +201,9 @@ public class ContactsSyncManager extends SyncManager {
syncResult.stats.numInserts++;
}
- if (groupMethod == GroupMethod.CATEGORIES && local instanceof LocalContact) {
- // VCard3: update group memberships from CATEGORIES
- LocalContact contact = (LocalContact)local;
-
- BatchOperation batch = new BatchOperation(provider);
- App.log.log(Level.FINE, "Removing contact group memberships");
- contact.removeGroupMemberships(batch);
-
- for (String category : contact.getContact().categories) {
- long groupID = localAddressBook().findOrCreateGroup(category);
- App.log.log(Level.FINE, "Adding membership in group " + category + " (" + groupID + ")");
- contact.addToGroup(batch, groupID);
- }
-
- batch.commit();
- }
+ return local;
}
-
// downloader helper class
@RequiredArgsConstructor
@@ -484,7 +228,7 @@ public class ContactsSyncManager extends SyncManager {
OkHttpClient resourceClient = HttpClient.create(context);
// authenticate only against a certain host, and only upon request
- resourceClient = HttpClient.addAuthentication(resourceClient, baseUrl.host(), settings.username(), settings.password());
+ // resourceClient = HttpClient.addAuthentication(resourceClient, baseUrl.host(), settings.username(), settings.password());
// allow redirects
resourceClient = resourceClient.newBuilder()
@@ -505,7 +249,7 @@ public class ContactsSyncManager extends SyncManager {
} else
App.log.severe("Couldn't download external resource");
}
- } catch(IOException e) {
+ } catch (IOException e) {
App.log.log(Level.SEVERE, "Couldn't download external resource", e);
}
return null;
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java
index d2a62c9c..3d9cbd02 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java
@@ -65,7 +65,7 @@ public abstract class SyncAdapterService extends Service {
@Override
public void onSecurityException(Account account, Bundle extras, String authority, SyncResult syncResult) {
- App.log.log(Level.WARNING, "Security exception when opening content provider for " + authority);
+ App.log.log(Level.WARNING, "Security exception when opening content provider for " + authority);
syncResult.databaseError = true;
Intent intent = new Intent(getContext(), PermissionsActivity.class);
@@ -85,7 +85,7 @@ public abstract class SyncAdapterService extends Service {
protected boolean checkSyncConditions(@NonNull AccountSettings settings) {
if (settings.getSyncWifiOnly()) {
- ConnectivityManager cm = (ConnectivityManager)getContext().getSystemService(CONNECTIVITY_SERVICE);
+ ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo network = cm.getActiveNetworkInfo();
if (network == null) {
App.log.info("No network available, stopping");
@@ -99,7 +99,7 @@ public abstract class SyncAdapterService extends Service {
String onlySSID = settings.getSyncWifiOnlySSID();
if (onlySSID != null) {
onlySSID = "\"" + onlySSID + "\"";
- WifiManager wifi = (WifiManager)getContext().getApplicationContext().getSystemService(WIFI_SERVICE);
+ WifiManager wifi = (WifiManager) getContext().getApplicationContext().getSystemService(WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
if (info == null || !onlySSID.equals(info.getSSID())) {
App.log.info("Connected to wrong WiFi network (" + info.getSSID() + ", required: " + onlySSID + "), ignoring");
@@ -109,7 +109,6 @@ public abstract class SyncAdapterService extends Service {
}
return true;
}
-
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java
index bd8e4c5d..c88746f7 100644
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java
+++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncManager.java
@@ -1,16 +1,15 @@
- /*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
+/*
+* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the GNU Public License v3.0
+* which accompanies this distribution, and is available at
+* http://www.gnu.org/licenses/gpl.html
+*/
package at.bitfire.davdroid.syncadapter;
import android.accounts.Account;
import android.annotation.TargetApi;
import android.app.PendingIntent;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
@@ -18,55 +17,49 @@ import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.NotificationCompat;
-import android.text.TextUtils;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.ConflictException;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.exception.PreconditionFailedException;
-import at.bitfire.dav4android.exception.ServiceUnavailableException;
-import at.bitfire.dav4android.exception.UnauthorizedException;
-import at.bitfire.dav4android.property.GetCTag;
-import at.bitfire.dav4android.property.GetETag;
import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.GsonHelper;
import at.bitfire.davdroid.HttpClient;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalEntryManager;
import at.bitfire.davdroid.resource.LocalCollection;
import at.bitfire.davdroid.resource.LocalResource;
import at.bitfire.davdroid.ui.AccountSettingsActivity;
import at.bitfire.davdroid.ui.DebugInfoActivity;
import at.bitfire.ical4android.CalendarStorageException;
+import at.bitfire.ical4android.InvalidCalendarException;
import at.bitfire.vcard4android.ContactsStorageException;
-import okhttp3.HttpUrl;
+import lombok.Getter;
import okhttp3.OkHttpClient;
-import okhttp3.RequestBody;
abstract public class SyncManager {
- protected final int SYNC_PHASE_PREPARE = 0,
- SYNC_PHASE_QUERY_CAPABILITIES = 1,
- SYNC_PHASE_PROCESS_LOCALLY_DELETED = 2,
- SYNC_PHASE_PREPARE_DIRTY = 3,
- SYNC_PHASE_UPLOAD_DIRTY = 4,
- SYNC_PHASE_CHECK_SYNC_STATE = 5,
- SYNC_PHASE_LIST_LOCAL = 6,
- SYNC_PHASE_LIST_REMOTE = 7,
- SYNC_PHASE_COMPARE_LOCAL_REMOTE = 8,
- SYNC_PHASE_DOWNLOAD_REMOTE = 9,
- SYNC_PHASE_POST_PROCESSING = 10,
- SYNC_PHASE_SAVE_SYNC_STATE = 11;
+ protected final String SYNC_PHASE_PREPARE = "sync_phase_prepare",
+ SYNC_PHASE_QUERY_CAPABILITIES = "sync_phase_query_capabilities",
+ SYNC_PHASE_PREPARE_LOCAL = "sync_phase_prepare_local",
+ SYNC_PHASE_CREATE_LOCAL_ENTRIES = "sync_phase_create_local_entries",
+ SYNC_PHASE_FETCH_ENTRIES = "sync_phase_fetch_entries",
+ SYNC_PHASE_APPLY_REMOTE_ENTRIES = "sync_phase_apply_remote_entries",
+ SYNC_PHASE_APPLY_LOCAL_ENTRIES = "sync_phase_apply_local_entries",
+ SYNC_PHASE_PUSH_ENTRIES = "sync_phase_push_entries",
+ SYNC_PHASE_POST_PROCESSING = "sync_phase_post_processing",
+ SYNC_PHASE_SAVE_SYNC_TAG = "sync_phase_save_sync_tag";
+
protected final NotificationManagerCompat notificationManager;
protected final String uniqueCollectionId;
@@ -81,23 +74,28 @@ abstract public class SyncManager {
protected LocalCollection localCollection;
protected OkHttpClient httpClient;
- protected HttpUrl collectionURL;
- protected DavResource davCollection;
+ protected JournalEntryManager journal;
- /** remote CTag at the time of {@link #listRemote()} */
+ /**
+ * remote CTag (uuid of the last entry on the server). We update it when we fetch/push and save when everything works.
+ */
protected String remoteCTag = null;
- /** sync-able resources in the local collection, as enumerated by {@link #listLocal()} */
- protected Map localResources;
-
- /** sync-able resources in the remote collection, as enumerated by {@link #listRemote()} */
- protected Map remoteResources;
-
- /** resources which have changed on the server, as determined by {@link #compareLocalRemote()} */
- protected Set toDownload;
+ /**
+ * Syncable local journal entries.
+ */
+ protected List localEntries;
+ /**
+ * Syncable remote journal entries (fetch from server).
+ */
+ protected List remoteEntries;
+ /**
+ * sync-able resources in the local collection, as enumerated by {@link #prepareLocal()}
+ */
+ protected Map localResources;
public SyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, SyncResult syncResult, String uniqueCollectionId) throws InvalidAccountException {
this.context = context;
@@ -117,95 +115,100 @@ abstract public class SyncManager {
}
protected abstract int notificationId();
+
protected abstract String getSyncErrorTitle();
@TargetApi(21)
public void performSync() {
- int syncPhase = SYNC_PHASE_PREPARE;
+ String syncPhase = SYNC_PHASE_PREPARE;
try {
- App.log.info("Preparing synchronization");
+ App.log.info("Sync phase: " + syncPhase);
prepare();
if (Thread.interrupted())
return;
syncPhase = SYNC_PHASE_QUERY_CAPABILITIES;
- App.log.info("Querying capabilities");
+ App.log.info("Sync phase: " + syncPhase);
queryCapabilities();
- syncPhase = SYNC_PHASE_PROCESS_LOCALLY_DELETED;
- App.log.info("Processing locally deleted entries");
- processLocallyDeleted();
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_PREPARE_LOCAL;
+ App.log.info("Sync phase: " + syncPhase);
+ prepareLocal();
+ /* Create journal entries out of local changes. */
if (Thread.interrupted())
return;
- syncPhase = SYNC_PHASE_PREPARE_DIRTY;
- App.log.info("Locally preparing dirty entries");
- prepareDirty();
-
- syncPhase = SYNC_PHASE_UPLOAD_DIRTY;
- App.log.info("Uploading dirty entries");
- uploadDirty();
-
- syncPhase = SYNC_PHASE_CHECK_SYNC_STATE;
- App.log.info("Checking sync state");
- if (checkSyncState()) {
- syncPhase = SYNC_PHASE_LIST_LOCAL;
- App.log.info("Listing local entries");
- listLocal();
-
- if (Thread.interrupted())
- return;
- syncPhase = SYNC_PHASE_LIST_REMOTE;
- App.log.info("Listing remote entries");
- listRemote();
-
- if (Thread.interrupted())
- return;
- syncPhase = SYNC_PHASE_COMPARE_LOCAL_REMOTE;
- App.log.info("Comparing local/remote entries");
- compareLocalRemote();
-
- syncPhase = SYNC_PHASE_DOWNLOAD_REMOTE;
- App.log.info("Downloading remote entries");
- downloadRemote();
-
- syncPhase = SYNC_PHASE_POST_PROCESSING;
- App.log.info("Post-processing");
- postProcess();
-
- syncPhase = SYNC_PHASE_SAVE_SYNC_STATE;
- App.log.info("Saving sync state");
- saveSyncState();
- } else
- App.log.info("Remote collection didn't change, skipping remote sync");
-
- } catch (IOException|ServiceUnavailableException e) {
+ syncPhase = SYNC_PHASE_CREATE_LOCAL_ENTRIES;
+ App.log.info("Sync phase: " + syncPhase);
+ createLocalEntries();
+
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_FETCH_ENTRIES;
+ App.log.info("Sync phase: " + syncPhase);
+ fetchEntries();
+
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_APPLY_REMOTE_ENTRIES;
+ App.log.info("Sync phase: " + syncPhase);
+ applyRemoteEntries();
+
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_APPLY_LOCAL_ENTRIES;
+ App.log.info("Sync phase: " + syncPhase);
+ applyLocalEntries();
+
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_PUSH_ENTRIES;
+ App.log.info("Sync phase: " + syncPhase);
+ pushEntries();
+
+ /* Cleanup and finalize changes */
+ if (Thread.interrupted())
+ return;
+ syncPhase = SYNC_PHASE_POST_PROCESSING;
+ App.log.info("Sync phase: " + syncPhase);
+ postProcess();
+
+ syncPhase = SYNC_PHASE_SAVE_SYNC_TAG;
+ App.log.info("Sync phase: " + syncPhase);
+ saveSyncTag();
+
+ } catch (IOException e) {
App.log.log(Level.WARNING, "I/O exception during sync, trying again later", e);
syncResult.stats.numIoExceptions++;
- if (e instanceof ServiceUnavailableException) {
- Date retryAfter = ((ServiceUnavailableException) e).retryAfter;
+ } catch (Exceptions.ServiceUnavailableException e) {
+ Date retryAfter = null; // ((Exceptions.ServiceUnavailableException) e).retryAfter;
if (retryAfter != null) {
// how many seconds to wait? getTime() returns ms, so divide by 1000
- syncResult.delayUntil = (retryAfter.getTime() - new Date().getTime()) / 1000;
+ // syncResult.delayUntil = (retryAfter.getTime() - new Date().getTime()) / 1000;
}
- }
-
- } catch(Exception|OutOfMemoryError e) {
+ } catch (Exception | OutOfMemoryError e) {
final int messageString;
- if (e instanceof UnauthorizedException) {
+ if (e instanceof Exceptions.UnauthorizedException) {
App.log.log(Level.SEVERE, "Not authorized anymore", e);
messageString = R.string.sync_error_unauthorized;
syncResult.stats.numAuthExceptions++;
- } else if (e instanceof HttpException || e instanceof DavException) {
- App.log.log(Level.SEVERE, "HTTP/DAV Exception during sync", e);
+ } else if (e instanceof Exceptions.HttpException) {
+ App.log.log(Level.SEVERE, "HTTP Exception during sync", e);
messageString = R.string.sync_error_http_dav;
syncResult.stats.numParseExceptions++;
} else if (e instanceof CalendarStorageException || e instanceof ContactsStorageException) {
App.log.log(Level.SEVERE, "Couldn't access local storage", e);
messageString = R.string.sync_error_local_storage;
syncResult.databaseError = true;
+ } else if (e instanceof Exceptions.IntegrityException) {
+ App.log.log(Level.SEVERE, "Integrity error", e);
+ // FIXME: Make a proper error message
+ messageString = R.string.sync_error;
+ syncResult.stats.numParseExceptions++;
} else {
App.log.log(Level.SEVERE, "Unknown sync error", e);
messageString = R.string.sync_error;
@@ -213,7 +216,7 @@ abstract public class SyncManager {
}
final Intent detailsIntent;
- if (e instanceof UnauthorizedException) {
+ if (e instanceof Exceptions.UnauthorizedException) {
detailsIntent = new Intent(context, AccountSettingsActivity.class);
detailsIntent.putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account);
} else {
@@ -228,206 +231,162 @@ abstract public class SyncManager {
detailsIntent.setData(Uri.parse("uri://" + getClass().getName() + "/" + uniqueCollectionId));
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
- builder .setSmallIcon(R.drawable.ic_error_light)
+ builder.setSmallIcon(R.drawable.ic_error_light)
.setLargeIcon(App.getLauncherBitmap(context))
.setContentTitle(getSyncErrorTitle())
.setContentIntent(PendingIntent.getActivity(context, 0, detailsIntent, PendingIntent.FLAG_CANCEL_CURRENT))
.setCategory(NotificationCompat.CATEGORY_ERROR);
- try {
- String[] phases = context.getResources().getStringArray(R.array.sync_error_phases);
- String message = context.getString(messageString, phases[syncPhase]);
- builder.setContentText(message);
- } catch (IndexOutOfBoundsException ex) {
- // should never happen
- }
+ String message = context.getString(messageString, syncPhase);
+ builder.setContentText(message);
+
notificationManager.notify(uniqueCollectionId, notificationId(), builder.build());
}
}
- abstract protected void prepare() throws ContactsStorageException;
+ abstract protected void prepare() throws ContactsStorageException, CalendarStorageException;
- abstract protected void queryCapabilities() throws IOException, HttpException, DavException, CalendarStorageException, ContactsStorageException;
+ abstract protected void processSyncEntry(SyncEntry cEntry) throws IOException, ContactsStorageException, CalendarStorageException, InvalidCalendarException;
- /**
- * Process locally deleted entries (DELETE them on the server as well).
- * Checks Thread.interrupted() before each request to allow quick sync cancellation.
- */
- protected void processLocallyDeleted() throws CalendarStorageException, ContactsStorageException {
- // Remove locally deleted entries from server (if they have a name, i.e. if they were uploaded before),
- // but only if they don't have changed on the server. Then finally remove them from the local address book.
- LocalResource[] localList = localCollection.getDeleted();
- for (LocalResource local : localList) {
- if (Thread.interrupted())
- return;
+ abstract protected void applyLocalEntries() throws IOException, ContactsStorageException, CalendarStorageException, Exceptions.HttpException;
- final String fileName = local.getFileName();
- if (!TextUtils.isEmpty(fileName)) {
- App.log.info(fileName + " has been deleted locally -> deleting from server");
- try {
- new DavResource(httpClient, collectionURL.newBuilder().addPathSegment(fileName).build())
- .delete(local.getETag());
- } catch (IOException|HttpException e) {
- App.log.warning("Couldn't delete " + fileName + " from server; ignoring (may be downloaded again)");
- }
- } else
- App.log.info("Removing local record #" + local.getId() + " which has been deleted locally and was never uploaded");
- local.delete();
- syncResult.stats.numDeletes++;
- }
+ protected void queryCapabilities() throws IOException, CalendarStorageException, ContactsStorageException {
}
- protected void prepareDirty() throws CalendarStorageException, ContactsStorageException {
- // assign file names and UIDs to new contacts so that we can use the file name as an index
- App.log.info("Looking for contacts/groups without file name");
- for (LocalResource local : localCollection.getWithoutFileName()) {
- String uuid = UUID.randomUUID().toString();
- App.log.fine("Found local record #" + local.getId() + " without file name; assigning file name/UID based on " + uuid);
- local.updateFileNameAndUID(uuid);
+ protected void fetchEntries() throws Exceptions.HttpException, ContactsStorageException, CalendarStorageException, Exceptions.IntegrityException {
+ remoteEntries = journal.getEntries(settings.password(), remoteCTag);
+
+ if (!remoteEntries.isEmpty()) {
+ remoteCTag = remoteEntries.get(remoteEntries.size() - 1).getUuid();
}
}
- abstract protected RequestBody prepareUpload(LocalResource resource) throws IOException, CalendarStorageException, ContactsStorageException;
-
- /**
- * Uploads dirty records to the server, using a PUT request for each record.
- * Checks Thread.interrupted() before each request to allow quick sync cancellation.
- */
- protected void uploadDirty() throws IOException, HttpException, CalendarStorageException, ContactsStorageException {
- // upload dirty contacts
- for (LocalResource local : localCollection.getDirty()) {
+ protected void applyRemoteEntries() throws IOException, ContactsStorageException, CalendarStorageException, InvalidCalendarException {
+ // Process new vcards from server
+ for (JournalEntryManager.Entry entry : remoteEntries) {
if (Thread.interrupted())
return;
- final String fileName = local.getFileName();
+ App.log.info("Processing " + entry.toString());
- DavResource remote = new DavResource(httpClient, collectionURL.newBuilder().addPathSegment(fileName).build());
+ SyncEntry cEntry = SyncEntry.fromJournalEntry(settings.password(), entry);
+ App.log.info("Processing resource for journal entry " + entry.getUuid());
+ processSyncEntry(cEntry);
+ }
+ }
- // generate entity to upload (VCard, iCal, whatever)
- RequestBody body = prepareUpload(local);
+ protected void pushEntries() throws Exceptions.HttpException, IOException, ContactsStorageException, CalendarStorageException {
+ // upload dirty contacts
+ // FIXME: Deal with failure
+ if (!localEntries.isEmpty()) {
+ journal.putEntries(localEntries, remoteCTag);
- try {
- if (local.getETag() == null) {
- App.log.info("Uploading new record " + fileName);
- remote.put(body, null, true);
- } else {
- App.log.info("Uploading locally modified record " + fileName);
- remote.put(body, local.getETag(), false);
- }
- } catch (ConflictException|PreconditionFailedException e) {
- // we can't interact with the user to resolve the conflict, so we treat 409 like 412
- App.log.log(Level.INFO, "Resource has been modified on the server before upload, ignoring", e);
+ for (LocalResource local : localCollection.getDirty()) {
+ App.log.info("Added/changed resource with UUID: " + local.getUuid());
+ local.clearDirty(local.getUuid());
}
- String eTag = null;
- GetETag newETag = (GetETag) remote.properties.get(GetETag.NAME);
- if (newETag != null) {
- eTag = newETag.eTag;
- App.log.fine("Received new ETag=" + eTag + " after uploading");
- } else
- App.log.fine("Didn't receive new ETag after uploading, setting to null");
+ for (LocalResource local : localCollection.getDeleted()) {
+ local.delete();
+ }
- local.clearDirty(eTag);
+ remoteCTag = localEntries.get(localEntries.size() - 1).getUuid();
}
}
- /**
- * Checks the current sync state (e.g. CTag) and whether synchronization from remote is required.
- * @return
- * true
if the remote collection has changed, i.e. synchronization from remote is required
- * false
if the remote collection hasn't changed
- *
- */
- protected boolean checkSyncState() throws CalendarStorageException, ContactsStorageException {
- // check CTag (ignore on manual sync)
- GetCTag getCTag = (GetCTag)davCollection.properties.get(GetCTag.NAME);
- if (getCTag != null)
- remoteCTag = getCTag.cTag;
-
- String localCTag = null;
- if (extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL))
- App.log.info("Manual sync, ignoring CTag");
- else
- localCTag = localCollection.getCTag();
-
- if (remoteCTag != null && remoteCTag.equals(localCTag)) {
- App.log.info("Remote collection didn't change (CTag=" + remoteCTag + "), no need to query children");
- return false;
- } else
- return true;
+ protected void createLocalEntries() throws CalendarStorageException, ContactsStorageException, IOException {
+ localEntries = new LinkedList<>();
+
+ // Not saving, just creating a fake one until we load it from a local db
+ JournalEntryManager.Entry previousEntry = (remoteCTag != null) ? JournalEntryManager.Entry.getFakeWithUid(remoteCTag) : null;
+
+ for (LocalResource local : processLocallyDeleted()) {
+ SyncEntry entry = new SyncEntry(local.getContent(), SyncEntry.Actions.DELETE);
+ JournalEntryManager.Entry tmp = new JournalEntryManager.Entry();
+ tmp.update(settings.password(), entry.toJson(), previousEntry);
+ previousEntry = tmp;
+ localEntries.add(previousEntry);
+ }
+
+ try {
+ for (LocalResource local : localCollection.getDirty()) {
+ SyncEntry.Actions action;
+ if (local.isLocalOnly()) {
+ action = SyncEntry.Actions.ADD;
+ } else {
+ action = SyncEntry.Actions.CHANGE;
+ }
+
+ SyncEntry entry = new SyncEntry(local.getContent(), action);
+ JournalEntryManager.Entry tmp = new JournalEntryManager.Entry();
+ tmp.update(settings.password(), entry.toJson(), previousEntry);
+ previousEntry = tmp;
+ localEntries.add(previousEntry);
+ }
+ } catch (FileNotFoundException e) {
+ // FIXME: Do something
+ e.printStackTrace();
+ }
}
/**
* Lists all local resources which should be taken into account for synchronization into {@link #localResources}.
*/
- protected void listLocal() throws CalendarStorageException, ContactsStorageException {
+ protected void prepareLocal() throws CalendarStorageException, ContactsStorageException {
+ prepareDirty();
+
// fetch list of local contacts and build hash table to index file name
LocalResource[] localList = localCollection.getAll();
localResources = new HashMap<>(localList.length);
for (LocalResource resource : localList) {
- App.log.fine("Found local resource: " + resource.getFileName());
- localResources.put(resource.getFileName(), resource);
+ App.log.fine("Found local resource: " + resource.getUuid());
+ localResources.put(resource.getUuid(), resource);
}
+
+ remoteCTag = localCollection.getCTag();
}
- /**
- * Lists all members of the remote collection which should be taken into account for synchronization into {@link #remoteResources}.
- */
- abstract protected void listRemote() throws IOException, HttpException, DavException;
/**
- * Compares {@link #localResources} and {@link #remoteResources} by file name and ETag:
- *
- * Local resources which are not available in the remote collection (anymore) will be removed.
- * Resources whose remote ETag has changed will be added into {@link #toDownload}
- *
+ * Delete unpublished locally deleted, and return the rest.
+ * Checks Thread.interrupted() before each request to allow quick sync cancellation.
*/
- protected void compareLocalRemote() throws IOException, HttpException, DavException, CalendarStorageException, ContactsStorageException {
- /* check which contacts
- 1. are not present anymore remotely -> delete immediately on local side
- 2. updated remotely -> add to downloadNames
- 3. added remotely -> add to downloadNames
- */
- toDownload = new HashSet<>();
- for (String localName : localResources.keySet()) {
- DavResource remote = remoteResources.get(localName);
- if (remote == null) {
- App.log.info(localName + " is not on server anymore, deleting");
- localResources.get(localName).delete();
- syncResult.stats.numDeletes++;
- } else {
- // contact is still on server, check whether it has been updated remotely
- GetETag getETag = (GetETag)remote.properties.get(GetETag.NAME);
- if (getETag == null || getETag.eTag == null)
- throw new DavException("Server didn't provide ETag");
- String localETag = localResources.get(localName).getETag(),
- remoteETag = getETag.eTag;
- if (remoteETag.equals(localETag))
- syncResult.stats.numSkippedEntries++;
- else {
- App.log.info(localName + " has been changed on server (current ETag=" + remoteETag + ", last known ETag=" + localETag + ")");
- toDownload.add(remote);
- }
+ protected List processLocallyDeleted() throws CalendarStorageException, ContactsStorageException {
+ // FIXME: This needs refactoring and fixing, it's just not true.
+ // Remove locally deleted entries from server (if they have a name, i.e. if they were uploaded before),
+ // but only if they don't have changed on the server. Then finally remove them from the local address book.
+ LocalResource[] localList = localCollection.getDeleted();
+ List ret = new ArrayList<>(localList.length);
+
+ for (LocalResource local : localList) {
+ if (Thread.interrupted())
+ return ret;
- // remote entry has been seen, remove from list
- remoteResources.remove(localName);
+ if (!local.isLocalOnly()) {
+ App.log.info(local.getUuid() + " has been deleted locally -> deleting from server");
+ ret.add(local);
+ } else {
+ App.log.info("Removing local record #" + local.getId() + " which has been deleted locally and was never uploaded");
+ local.delete();
}
- }
- // add all unseen (= remotely added) remote contacts
- if (!remoteResources.isEmpty()) {
- App.log.info("New resources have been found on the server: " + TextUtils.join(", ", remoteResources.keySet()));
- toDownload.addAll(remoteResources.values());
+ syncResult.stats.numDeletes++;
}
+
+ return ret;
}
- /**
- * Downloads the remote resources in {@link #toDownload} and stores them locally.
- * Must check Thread.interrupted() periodically to allow quick sync cancellation.
- */
- abstract protected void downloadRemote() throws IOException, HttpException, DavException, ContactsStorageException, CalendarStorageException;
+ protected void prepareDirty() throws CalendarStorageException, ContactsStorageException {
+ // assign file names and UIDs to new contacts so that we can use the file name as an index
+ App.log.info("Looking for contacts/groups without file name");
+ for (LocalResource local : localCollection.getWithoutFileName()) {
+ String uuid = UUID.randomUUID().toString();
+ App.log.fine("Found local record #" + local.getId() + " without file name; assigning file name/UID based on " + uuid);
+ local.updateFileNameAndUID(uuid);
+ }
+ }
/**
* For post-processing of entries, for instance assigning groups.
@@ -435,12 +394,54 @@ abstract public class SyncManager {
protected void postProcess() throws CalendarStorageException, ContactsStorageException {
}
- protected void saveSyncState() throws CalendarStorageException, ContactsStorageException {
- /* Save sync state (CTag). It doesn't matter if it has changed during the sync process
- (for instance, because another client has uploaded changes), because this will simply
- cause all remote entries to be listed at the next sync. */
+ protected void saveSyncTag() throws CalendarStorageException, ContactsStorageException {
App.log.info("Saving CTag=" + remoteCTag);
localCollection.setCTag(remoteCTag);
}
+
+ static class SyncEntry {
+ @Getter
+ private String content;
+ @Getter
+ private Actions action;
+
+ enum Actions {
+ ADD("ADD"),
+ CHANGE("CHANGE"),
+ DELETE("DELETE");
+
+ private final String text;
+
+ Actions(final String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private SyncEntry() {
+ }
+
+ protected SyncEntry(String content, Actions action) {
+ this.content = content;
+ this.action = action;
+ }
+
+ boolean isAction(Actions action) {
+ return this.action.equals(action);
+ }
+
+ static SyncEntry fromJournalEntry(String keyBase64, JournalEntryManager.Entry entry) {
+ return GsonHelper.gson.fromJson(entry.getContent(keyBase64), SyncEntry.class);
+ }
+
+ String toJson() {
+ return GsonHelper.gson.toJson(this, this.getClass());
+ }
+ }
}
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncAdapterService.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncAdapterService.java
deleted file mode 100644
index 648e39ac..00000000
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncAdapterService.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package at.bitfire.davdroid.syncadapter;
-
-import android.accounts.Account;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SyncResult;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import org.dmfs.provider.tasks.TaskContract;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.logging.Level;
-
-import at.bitfire.davdroid.AccountSettings;
-import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.InvalidAccountException;
-import at.bitfire.davdroid.model.CollectionInfo;
-import at.bitfire.davdroid.model.ServiceDB;
-import at.bitfire.davdroid.model.ServiceDB.Collections;
-import at.bitfire.davdroid.model.ServiceDB.Services;
-import at.bitfire.davdroid.resource.LocalTaskList;
-import at.bitfire.ical4android.CalendarStorageException;
-import at.bitfire.ical4android.TaskProvider;
-import lombok.Cleanup;
-
-/**
- * Synchronization manager for CalDAV collections; handles tasks ({@code VTODO}).
- */
-public class TasksSyncAdapterService extends SyncAdapterService {
-
- @Override
- protected AbstractThreadedSyncAdapter syncAdapter() {
- return new SyncAdapter(this);
- }
-
-
- private static class SyncAdapter extends SyncAdapterService.SyncAdapter {
-
- public SyncAdapter(Context context) {
- super(context);
- }
-
- @Override
- public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient providerClient, SyncResult syncResult) {
- super.onPerformSync(account, extras, authority, providerClient, syncResult);
-
- try {
- @Cleanup TaskProvider provider = TaskProvider.acquire(getContext().getContentResolver(), TaskProvider.ProviderName.OpenTasks);
- if (provider == null)
- throw new CalendarStorageException("Couldn't access OpenTasks provider");
-
- AccountSettings settings = new AccountSettings(getContext(), account);
- if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
- return;
-
- updateLocalTaskLists(provider, account, settings);
-
- for (LocalTaskList taskList : (LocalTaskList[])LocalTaskList.find(account, provider, LocalTaskList.Factory.INSTANCE, TaskContract.TaskLists.SYNC_ENABLED + "!=0", null)) {
- App.log.info("Synchronizing task list #" + taskList.getId() + " [" + taskList.getSyncId() + "]");
- TasksSyncManager syncManager = new TasksSyncManager(getContext(), account, settings, extras, authority, provider, syncResult, taskList);
- syncManager.performSync();
- }
- } catch (CalendarStorageException e) {
- App.log.log(Level.SEVERE, "Couldn't enumerate local task lists", e);
- } catch (InvalidAccountException e) {
- App.log.log(Level.SEVERE, "Couldn't get account settings", e);
- }
-
- App.log.info("Task sync complete");
- }
-
- private void updateLocalTaskLists(TaskProvider provider, Account account, AccountSettings settings) throws CalendarStorageException {
- SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
- try {
- // enumerate remote and local task lists
- SQLiteDatabase db = dbHelper.getReadableDatabase();
- Long service = getService(db, account);
- Map remote = remoteTaskLists(db, service);
- LocalTaskList[] local = (LocalTaskList[])LocalTaskList.find(account, provider, LocalTaskList.Factory.INSTANCE, null, null);
-
- boolean updateColors = settings.getManageCalendarColors();
-
- // delete obsolete local task lists
- for (LocalTaskList list : local) {
- String url = list.getSyncId();
- if (!remote.containsKey(url)) {
- App.log.fine("Deleting obsolete local task list" + url);
- list.delete();
- } else {
- // remote CollectionInfo found for this local collection, update data
- CollectionInfo info = remote.get(url);
- App.log.fine("Updating local task list " + url + " with " + info);
- list.update(info, updateColors);
- // we already have a local task list for this remote collection, don't take into consideration anymore
- remote.remove(url);
- }
- }
-
- // create new local task lists
- for (String url : remote.keySet()) {
- CollectionInfo info = remote.get(url);
- App.log.info("Adding local task list " + info);
- LocalTaskList.create(account, provider, info);
- }
- } finally {
- dbHelper.close();
- }
- }
-
- @Nullable
- Long getService(@NonNull SQLiteDatabase db, @NonNull Account account) {
- @Cleanup Cursor c = db.query(Services._TABLE, new String[] { Services.ID },
- Services.ACCOUNT_NAME + "=? AND " + Services.SERVICE + "=?", new String[] { account.name, Services.SERVICE_CALDAV }, null, null, null);
- if (c.moveToNext())
- return c.getLong(0);
- else
- return null;
- }
-
- @NonNull
- private Map remoteTaskLists(@NonNull SQLiteDatabase db, Long service) {
- Map collections = new LinkedHashMap<>();
- if (service != null) {
- @Cleanup Cursor cursor = db.query(Collections._TABLE, null,
- Collections.SERVICE_ID + "=? AND " + Collections.SUPPORTS_VTODO + "!=0 AND " + Collections.SYNC,
- new String[] { String.valueOf(service) }, null, null, null);
- while (cursor.moveToNext()) {
- ContentValues values = new ContentValues();
- DatabaseUtils.cursorRowToContentValues(cursor, values);
- CollectionInfo info = CollectionInfo.fromDB(values);
- collections.put(info.url, info);
- }
- }
- return collections;
- }
- }
-
-}
diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncManager.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncManager.java
deleted file mode 100644
index 1a1994fa..00000000
--- a/app/src/main/java/at/bitfire/davdroid/syncadapter/TasksSyncManager.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-package at.bitfire.davdroid.syncadapter;
-
-import android.accounts.Account;
-import android.content.Context;
-import android.content.SyncResult;
-import android.os.Bundle;
-
-import org.apache.commons.codec.Charsets;
-import org.apache.commons.lang3.StringUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-
-import at.bitfire.dav4android.DavCalendar;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.property.CalendarData;
-import at.bitfire.dav4android.property.GetCTag;
-import at.bitfire.dav4android.property.GetContentType;
-import at.bitfire.dav4android.property.GetETag;
-import at.bitfire.davdroid.AccountSettings;
-import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.ArrayUtils;
-import at.bitfire.davdroid.Constants;
-import at.bitfire.davdroid.InvalidAccountException;
-import at.bitfire.davdroid.R;
-import at.bitfire.davdroid.resource.LocalResource;
-import at.bitfire.davdroid.resource.LocalTask;
-import at.bitfire.davdroid.resource.LocalTaskList;
-import at.bitfire.ical4android.CalendarStorageException;
-import at.bitfire.ical4android.InvalidCalendarException;
-import at.bitfire.ical4android.Task;
-import at.bitfire.ical4android.TaskProvider;
-import lombok.Cleanup;
-import okhttp3.HttpUrl;
-import okhttp3.MediaType;
-import okhttp3.RequestBody;
-import okhttp3.ResponseBody;
-
-public class TasksSyncManager extends SyncManager {
-
- protected static final int MAX_MULTIGET = 30;
-
- final protected TaskProvider provider;
-
-
- public TasksSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, TaskProvider provider, SyncResult result, LocalTaskList taskList) throws InvalidAccountException {
- super(context, account, settings, extras, authority, result, "taskList/" + taskList.getId());
- this.provider = provider;
- localCollection = taskList;
- }
-
- @Override
- protected int notificationId() {
- return Constants.NOTIFICATION_TASK_SYNC;
- }
-
- @Override
- protected String getSyncErrorTitle() {
- return context.getString(R.string.sync_error_tasks, account.name);
- }
-
-
- @Override
- protected void prepare() {
- collectionURL = HttpUrl.parse(localTaskList().getSyncId());
- davCollection = new DavCalendar(httpClient, collectionURL);
- }
-
- @Override
- protected void queryCapabilities() throws DavException, IOException, HttpException {
- davCollection.propfind(0, GetCTag.NAME);
- }
-
- @Override
- protected RequestBody prepareUpload(LocalResource resource) throws IOException, CalendarStorageException {
- LocalTask local = (LocalTask)resource;
- App.log.log(Level.FINE, "Preparing upload of task " + local.getFileName(), local.getTask() );
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- local.getTask().write(os);
-
- return RequestBody.create(
- DavCalendar.MIME_ICALENDAR,
- os.toByteArray()
- );
- }
-
- @Override
- protected void listRemote() throws IOException, HttpException, DavException {
- // fetch list of remote VTODOs and build hash table to index file name
- davCalendar().calendarQuery("VTODO", null, null);
- remoteResources = new HashMap<>(davCollection.members.size());
- for (DavResource vCard : davCollection.members) {
- String fileName = vCard.fileName();
- App.log.fine("Found remote VTODO: " + fileName);
- remoteResources.put(fileName, vCard);
- }
- }
-
- @Override
- protected void downloadRemote() throws IOException, HttpException, DavException, CalendarStorageException {
- App.log.info("Downloading " + toDownload.size() + " tasks (" + MAX_MULTIGET + " at once)");
-
- // download new/updated iCalendars from server
- for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
- if (Thread.interrupted())
- return;
-
- App.log.info("Downloading " + StringUtils.join(bunch, ", "));
-
- if (bunch.length == 1) {
- // only one contact, use GET
- DavResource remote = bunch[0];
-
- ResponseBody body = remote.get("text/calendar");
-
- // CalDAV servers MUST return ETag on GET [https://tools.ietf.org/html/rfc4791#section-5.3.4]
- GetETag eTag = (GetETag)remote.properties.get(GetETag.NAME);
- if (eTag == null || StringUtils.isEmpty(eTag.eTag))
- throw new DavException("Received CalDAV GET response without ETag for " + remote.location);
-
- Charset charset = Charsets.UTF_8;
- MediaType contentType = body.contentType();
- if (contentType != null)
- charset = contentType.charset(Charsets.UTF_8);
-
- @Cleanup InputStream stream = body.byteStream();
- processVTodo(remote.fileName(), eTag.eTag, stream, charset);
-
- } else {
- // multiple contacts, use multi-get
- List urls = new LinkedList<>();
- for (DavResource remote : bunch)
- urls.add(remote.location);
- davCalendar().multiget(urls.toArray(new HttpUrl[urls.size()]));
-
- // process multiget results
- for (DavResource remote : davCollection.members) {
- String eTag;
- GetETag getETag = (GetETag)remote.properties.get(GetETag.NAME);
- if (getETag != null)
- eTag = getETag.eTag;
- else
- throw new DavException("Received multi-get response without ETag");
-
- Charset charset = Charsets.UTF_8;
- GetContentType getContentType = (GetContentType)remote.properties.get(GetContentType.NAME);
- if (getContentType != null && getContentType.type != null) {
- MediaType type = MediaType.parse(getContentType.type);
- if (type != null)
- charset = type.charset(Charsets.UTF_8);
- }
-
- CalendarData calendarData = (CalendarData)remote.properties.get(CalendarData.NAME);
- if (calendarData == null || calendarData.iCalendar == null)
- throw new DavException("Received multi-get response without address data");
-
- @Cleanup InputStream stream = new ByteArrayInputStream(calendarData.iCalendar.getBytes());
- processVTodo(remote.fileName(), eTag, stream, charset);
- }
- }
- }
- }
-
-
- // helpers
-
- private LocalTaskList localTaskList() { return ((LocalTaskList)localCollection); }
- private DavCalendar davCalendar() { return (DavCalendar)davCollection; }
-
- private void processVTodo(String fileName, String eTag, InputStream stream, Charset charset) throws IOException, CalendarStorageException {
- Task[] tasks;
- try {
- tasks = Task.fromStream(stream, charset);
- } catch (InvalidCalendarException e) {
- App.log.log(Level.SEVERE, "Received invalid iCalendar, ignoring", e);
- return;
- }
-
- if (tasks.length == 1) {
- Task newData = tasks[0];
-
- // update local task, if it exists
- LocalTask localTask = (LocalTask)localResources.get(fileName);
- if (localTask != null) {
- App.log.info("Updating " + fileName + " in local tasklist");
- localTask.setETag(eTag);
- localTask.update(newData);
- syncResult.stats.numUpdates++;
- } else {
- App.log.info("Adding " + fileName + " to local task list");
- localTask = new LocalTask(localTaskList(), newData, fileName, eTag);
- localTask.add();
- syncResult.stats.numInserts++;
- }
- } else
- App.log.severe("Received VCALENDAR with not exactly one VTODO; ignoring " + fileName);
- }
-
-}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java
index 219b4541..35d12739 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java
@@ -57,11 +57,8 @@ import android.widget.EditText;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.ProgressBar;
-import android.widget.RadioButton;
import android.widget.TextView;
-import org.apache.commons.lang3.BooleanUtils;
-
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@@ -106,15 +103,14 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
// CardDAV toolbar
tbCardDAV = (Toolbar)findViewById(R.id.carddav_menu);
- tbCardDAV.setOverflowIcon(icMenu);
- tbCardDAV.inflateMenu(R.menu.carddav_actions);
- tbCardDAV.setOnMenuItemClickListener(this);
+ tbCardDAV.setTitle(R.string.settings_carddav);
// CalDAV toolbar
tbCalDAV = (Toolbar)findViewById(R.id.caldav_menu);
tbCalDAV.setOverflowIcon(icMenu);
tbCalDAV.inflateMenu(R.menu.caldav_actions);
tbCalDAV.setOnMenuItemClickListener(this);
+ tbCalDAV.setTitle(R.string.settings_caldav);
// load CardDAV/CalDAV collections
getLoaderManager().initLoader(0, getIntent().getExtras(), this);
@@ -142,14 +138,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
return true;
}
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuItem itemRename = menu.findItem(R.id.rename_account);
- // renameAccount is available for API level 21+
- itemRename.setVisible(Build.VERSION.SDK_INT >= 21);
- return super.onPrepareOptionsMenu(menu);
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -161,9 +149,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
intent.putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account);
startActivity(intent);
break;
- case R.id.rename_account:
- RenameAccountFragment.newInstance(account).show(getSupportFragmentManager(), null);
- break;
case R.id.delete_account:
new AlertDialog.Builder(AccountActivity.this)
.setIcon(R.drawable.ic_error_dark)
@@ -297,7 +282,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
long id;
boolean refreshing;
- boolean hasHomeSets;
List collections;
}
}
@@ -324,13 +308,9 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
listCardDAV.setEnabled(!info.carddav.refreshing);
listCardDAV.setAlpha(info.carddav.refreshing ? 0.5f : 1);
- tbCardDAV.getMenu().findItem(R.id.create_address_book).setEnabled(info.carddav.hasHomeSets);
-
AddressBookAdapter adapter = new AddressBookAdapter(this);
adapter.addAll(info.carddav.collections);
listCardDAV.setAdapter(adapter);
- listCardDAV.setOnItemClickListener(onItemClickListener);
- listCardDAV.setOnItemLongClickListener(onItemLongClickListener);
} else
card.setVisibility(View.GONE);
@@ -343,8 +323,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
listCalDAV.setEnabled(!info.caldav.refreshing);
listCalDAV.setAlpha(info.caldav.refreshing ? 0.5f : 1);
- tbCalDAV.getMenu().findItem(R.id.create_calendar).setEnabled(info.caldav.hasHomeSets);
-
final CalendarAdapter adapter = new CalendarAdapter(this);
adapter.addAll(info.caldav.collections);
listCalDAV.setAdapter(adapter);
@@ -433,7 +411,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
info.carddav = new AccountInfo.ServiceInfo();
info.carddav.id = id;
info.carddav.refreshing = (davService != null && davService.isRefreshing(id)) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
- info.carddav.hasHomeSets = hasHomeSets(db, id);
info.carddav.collections = readCollections(db, id);
} else if (Services.SERVICE_CALDAV.equals(service)) {
@@ -442,19 +419,12 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
info.caldav.refreshing = (davService != null && davService.isRefreshing(id)) ||
ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) ||
ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority);
- info.caldav.hasHomeSets = hasHomeSets(db, id);
info.caldav.collections = readCollections(db, id);
}
}
return info;
}
- private boolean hasHomeSets(@NonNull SQLiteDatabase db, long service) {
- @Cleanup Cursor cursor = db.query(ServiceDB.HomeSets._TABLE, null, ServiceDB.HomeSets.SERVICE_ID + "=?",
- new String[] { String.valueOf(service) }, null, null, null);
- return cursor.getCount() > 0;
- }
-
private List readCollections(@NonNull SQLiteDatabase db, long service) {
List collections = new LinkedList<>();
@Cleanup Cursor cursor = db.query(Collections._TABLE, null, Collections.SERVICE_ID + "=?",
@@ -484,9 +454,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
final CollectionInfo info = getItem(position);
- RadioButton checked = (RadioButton)v.findViewById(R.id.checked);
- checked.setChecked(info.selected);
-
TextView tv = (TextView)v.findViewById(R.id.title);
tv.setText(TextUtils.isEmpty(info.displayName) ? info.url : info.displayName);
@@ -541,99 +508,10 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
tv = (TextView)v.findViewById(R.id.read_only);
tv.setVisibility(info.readOnly ? View.VISIBLE : View.GONE);
- tv = (TextView)v.findViewById(R.id.events);
- tv.setVisibility(BooleanUtils.isTrue(info.supportsVEVENT) ? View.VISIBLE : View.GONE);
-
- tv = (TextView)v.findViewById(R.id.tasks);
- tv.setVisibility(BooleanUtils.isTrue(info.supportsVTODO) ? View.VISIBLE : View.GONE);
-
return v;
}
}
-
- /* DIALOG FRAGMENTS */
-
- public static class RenameAccountFragment extends DialogFragment {
-
- private final static String ARG_ACCOUNT = "account";
-
- static RenameAccountFragment newInstance(@NonNull Account account) {
- RenameAccountFragment fragment = new RenameAccountFragment();
- Bundle args = new Bundle(1);
- args.putParcelable(ARG_ACCOUNT, account);
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Account oldAccount = getArguments().getParcelable(ARG_ACCOUNT);
-
- final EditText editText = new EditText(getContext());
- editText.setText(oldAccount.name);
-
- return new AlertDialog.Builder(getContext())
- .setTitle(R.string.account_rename)
- .setMessage(R.string.account_rename_new_name)
- .setView(editText)
- .setPositiveButton(R.string.account_rename_rename, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final String newName = editText.getText().toString();
-
- if (newName.equals(oldAccount.name))
- return;
-
- final AccountManager accountManager = AccountManager.get(getContext());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- accountManager.renameAccount(oldAccount, newName,
- new AccountManagerCallback() {
- @Override
- public void run(AccountManagerFuture future) {
- App.log.info("Updating account name references");
-
- // cancel running synchronization
- ContentResolver.cancelSync(oldAccount, null);
-
- // update account name references in database
- @Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
- ServiceDB.onRenameAccount(dbHelper.getWritableDatabase(), oldAccount.name, newName);
-
- // update account_name of local contacts
- try {
- LocalAddressBook.onRenameAccount(getContext().getContentResolver(), oldAccount.name, newName);
- } catch(RemoteException e) {
- App.log.log(Level.SEVERE, "Couldn't propagate new account name to contacts provider");
- }
-
- // calendar provider doesn't allow changing account_name of Events
-
- // update account_name of local tasks
- try {
- LocalTaskList.onRenameAccount(getContext().getContentResolver(), oldAccount.name, newName);
- } catch(RemoteException e) {
- App.log.log(Level.SEVERE, "Couldn't propagate new account name to tasks provider");
- }
-
- // synchronize again
- requestSync(new Account(newName, oldAccount.type));
- }
- }, null
- );
- getActivity().finish();
- }
- })
- .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- }
- })
- .create();
- }
- }
-
-
/* USER ACTIONS */
private void deleteAccount() {
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java
index d4a8d1db..bdf94ee1 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/AccountSettingsActivity.java
@@ -92,23 +92,11 @@ public class AccountSettingsActivity extends AppCompatActivity {
}
// category: authentication
- final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");
- prefUserName.setSummary(settings.username());
- prefUserName.setText(settings.username());
- prefUserName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- settings.username((String)newValue);
- refresh();
- return false;
- }
- });
-
final EditTextPreference prefPassword = (EditTextPreference)findPreference("password");
prefPassword.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- settings.password((String)newValue);
+ settings.setAuthToken((String)newValue);
refresh();
return false;
}
@@ -205,66 +193,6 @@ public class AccountSettingsActivity extends AppCompatActivity {
return false;
}
});
-
- // category: CardDAV
- final ListPreference prefGroupMethod = (ListPreference)findPreference("contact_group_method");
- if (syncIntervalContacts != null) {
- prefGroupMethod.setValue(settings.getGroupMethod().name());
- prefGroupMethod.setSummary(prefGroupMethod.getEntry());
- prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object o) {
- String name = (String)o;
- settings.setGroupMethod(GroupMethod.valueOf(name));
- refresh();
- return false;
- }
- });
- } else
- prefGroupMethod.setEnabled(false);
-
- // category: CalDAV
- final EditTextPreference prefTimeRangePastDays = (EditTextPreference)findPreference("time_range_past_days");
- if (syncIntervalCalendars != null) {
- Integer pastDays = settings.getTimeRangePastDays();
- if (pastDays != null) {
- prefTimeRangePastDays.setText(pastDays.toString());
- prefTimeRangePastDays.setSummary(getResources().getQuantityString(R.plurals.settings_sync_time_range_past_days, pastDays, pastDays));
- } else {
- prefTimeRangePastDays.setText(null);
- prefTimeRangePastDays.setSummary(R.string.settings_sync_time_range_past_none);
- }
- prefTimeRangePastDays.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- int days;
- try {
- days = Integer.parseInt((String)newValue);
- } catch(NumberFormatException ignored) {
- days = -1;
- }
- settings.setTimeRangePastDays(days < 0 ? null : days);
- refresh();
- return false;
- }
- });
- } else
- prefTimeRangePastDays.setEnabled(false);
-
- final SwitchPreferenceCompat prefManageColors = (SwitchPreferenceCompat)findPreference("manage_calendar_colors");
- if (syncIntervalCalendars != null || syncIntervalTasks != null) {
- prefManageColors.setChecked(settings.getManageCalendarColors());
- prefManageColors.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- settings.setManageCalendarColors((Boolean)newValue);
- refresh();
- return false;
- }
- });
- } else
- prefManageColors.setEnabled(false);
-
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AccountsActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AccountsActivity.java
index 3abb0e83..0826c8b2 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/AccountsActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/AccountsActivity.java
@@ -10,11 +10,9 @@ package at.bitfire.davdroid.ui;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
-import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@@ -23,8 +21,6 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
-import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.BuildConfig;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.ui.setup.LoginActivity;
@@ -56,13 +52,6 @@ public class AccountsActivity extends AppCompatActivity implements NavigationVie
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setItemIconTintList(null);
-
- if (savedInstanceState == null && !getPackageName().equals(getCallingPackage())) {
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- for (StartupDialogFragment fragment : StartupDialogFragment.getStartupDialogs(this))
- ft.add(fragment, null);
- ft.commit();
- }
}
@Override
@@ -83,20 +72,17 @@ public class AccountsActivity extends AppCompatActivity implements NavigationVie
case R.id.nav_app_settings:
startActivity(new Intent(this, AppSettingsActivity.class));
break;
- case R.id.nav_twitter:
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/davdroidapp")));
- break;
case R.id.nav_website:
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri));
break;
case R.id.nav_faq:
- startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("faq/").build()));
+ startActivity(new Intent(Intent.ACTION_VIEW, Constants.faqUri));
break;
- case R.id.nav_forums:
- startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));
+ case R.id.nav_report_issue:
+ startActivity(new Intent(Intent.ACTION_VIEW, Constants.reportIssueUri));
break;
- case R.id.nav_donate:
- startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));
+ case R.id.nav_contact:
+ startActivity(new Intent(Intent.ACTION_VIEW, Constants.contactUri));
break;
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/CreateAddressBookActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/CreateAddressBookActivity.java
index 7e47d77c..3aa6d26f 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/CreateAddressBookActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/CreateAddressBookActivity.java
@@ -9,36 +9,21 @@
package at.bitfire.davdroid.ui;
import android.accounts.Account;
-import android.content.Context;
import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
import android.support.v4.app.NavUtils;
-import android.support.v4.content.AsyncTaskLoader;
-import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
-import android.widget.ArrayAdapter;
import android.widget.EditText;
-import android.widget.Spinner;
import org.apache.commons.lang3.StringUtils;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
-
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.model.CollectionInfo;
-import at.bitfire.davdroid.model.ServiceDB;
-import lombok.Cleanup;
-import okhttp3.HttpUrl;
-public class CreateAddressBookActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks {
+public class CreateAddressBookActivity extends AppCompatActivity {
public static final String EXTRA_ACCOUNT = "account";
protected Account account;
@@ -51,8 +36,6 @@ public class CreateAddressBookActivity extends AppCompatActivity implements Load
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.activity_create_address_book);
-
- getSupportLoaderManager().initLoader(0, getIntent().getExtras(), this);
}
@Override
@@ -76,9 +59,6 @@ public class CreateAddressBookActivity extends AppCompatActivity implements Load
boolean ok = true;
CollectionInfo info = new CollectionInfo();
- Spinner spinner = (Spinner)findViewById(R.id.home_sets);
- String homeSet = (String)spinner.getSelectedItem();
-
EditText edit = (EditText)findViewById(R.id.display_name);
info.displayName = edit.getText().toString();
if (TextUtils.isEmpty(info.displayName)) {
@@ -91,71 +71,8 @@ public class CreateAddressBookActivity extends AppCompatActivity implements Load
if (ok) {
info.type = CollectionInfo.Type.ADDRESS_BOOK;
- info.url = HttpUrl.parse(homeSet).resolve(UUID.randomUUID().toString() + "/").toString();
- CreateCollectionFragment.newInstance(account, info).show(getSupportFragmentManager(), null);
- }
- }
-
- @Override
- public Loader onCreateLoader(int id, Bundle args) {
- return new AccountInfoLoader(this, account);
- }
-
- @Override
- public void onLoadFinished(Loader loader, AccountInfo info) {
- if (info != null) {
- Spinner spinner = (Spinner)findViewById(R.id.home_sets);
- spinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, info.homeSets));
- }
- }
-
- @Override
- public void onLoaderReset(Loader loader) {
- }
-
- protected static class AccountInfo {
- List homeSets = new LinkedList<>();
- }
-
- protected static class AccountInfoLoader extends AsyncTaskLoader {
- private final Account account;
- private final ServiceDB.OpenHelper dbHelper;
-
- public AccountInfoLoader(Context context, Account account) {
- super(context);
- this.account = account;
- dbHelper = new ServiceDB.OpenHelper(context);
- }
-
- @Override
- protected void onStartLoading() {
- forceLoad();
- }
-
- @Override
- public AccountInfo loadInBackground() {
- final AccountInfo info = new AccountInfo();
-
- // find DAV service and home sets
- SQLiteDatabase db = dbHelper.getReadableDatabase();
- try {
- @Cleanup Cursor cursorService = db.query(ServiceDB.Services._TABLE, new String[] { ServiceDB.Services.ID },
- ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?",
- new String[] { account.name, ServiceDB.Services.SERVICE_CARDDAV }, null, null, null);
- if (!cursorService.moveToNext())
- return null;
- String strServiceID = cursorService.getString(0);
-
- @Cleanup Cursor cursorHomeSets = db.query(ServiceDB.HomeSets._TABLE, new String[] { ServiceDB.HomeSets.URL },
- ServiceDB.HomeSets.SERVICE_ID + "=?", new String[] { strServiceID }, null, null, null);
- while (cursorHomeSets.moveToNext())
- info.homeSets.add(cursorHomeSets.getString(0));
- } finally {
- dbHelper.close();
- }
-
- return info;
+ CreateCollectionFragment.newInstance(account, info).show(getSupportFragmentManager(), null);
}
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.java
index 0ecf52e1..6f85c7a2 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.java
@@ -9,22 +9,15 @@
package at.bitfire.davdroid.ui;
import android.accounts.Account;
-import android.content.Context;
import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
import android.support.v4.app.NavUtils;
-import android.support.v4.content.AsyncTaskLoader;
-import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Spinner;
@@ -33,20 +26,12 @@ import net.fortuna.ical4j.model.Calendar;
import org.apache.commons.lang3.StringUtils;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.TimeZone;
-import java.util.UUID;
-
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.model.CollectionInfo;
-import at.bitfire.davdroid.model.ServiceDB;
import at.bitfire.ical4android.DateUtils;
-import lombok.Cleanup;
-import okhttp3.HttpUrl;
import yuku.ambilwarna.AmbilWarnaDialog;
-public class CreateCalendarActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks {
+public class CreateCalendarActivity extends AppCompatActivity {
public static final String EXTRA_ACCOUNT = "account";
protected Account account;
@@ -64,7 +49,7 @@ public class CreateCalendarActivity extends AppCompatActivity implements LoaderM
colorSquare.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- new AmbilWarnaDialog(CreateCalendarActivity.this, ((ColorDrawable)colorSquare.getBackground()).getColor(), true, new AmbilWarnaDialog.OnAmbilWarnaListener() {
+ new AmbilWarnaDialog(CreateCalendarActivity.this, ((ColorDrawable) colorSquare.getBackground()).getColor(), true, new AmbilWarnaDialog.OnAmbilWarnaListener() {
@Override
public void onCancel(AmbilWarnaDialog dialog) {
}
@@ -76,8 +61,6 @@ public class CreateCalendarActivity extends AppCompatActivity implements LoaderM
}).show();
}
});
-
- getSupportLoaderManager().initLoader(0, null, this);
}
@Override
@@ -101,122 +84,33 @@ public class CreateCalendarActivity extends AppCompatActivity implements LoaderM
boolean ok = true;
CollectionInfo info = new CollectionInfo();
- Spinner spinner = (Spinner)findViewById(R.id.home_sets);
- String homeSet = (String)spinner.getSelectedItem();
+ Spinner spinner;
- EditText edit = (EditText)findViewById(R.id.display_name);
+ EditText edit = (EditText) findViewById(R.id.display_name);
info.displayName = edit.getText().toString();
if (TextUtils.isEmpty(info.displayName)) {
edit.setError(getString(R.string.create_collection_display_name_required));
ok = false;
}
- edit = (EditText)findViewById(R.id.description);
+ edit = (EditText) findViewById(R.id.description);
info.description = StringUtils.trimToNull(edit.getText().toString());
View view = findViewById(R.id.color);
- info.color = ((ColorDrawable)view.getBackground()).getColor();
+ info.color = ((ColorDrawable) view.getBackground()).getColor();
- spinner = (Spinner)findViewById(R.id.time_zone);
- net.fortuna.ical4j.model.TimeZone tz = DateUtils.tzRegistry.getTimeZone((String)spinner.getSelectedItem());
+ spinner = (Spinner) findViewById(R.id.time_zone);
+ net.fortuna.ical4j.model.TimeZone tz = DateUtils.tzRegistry.getTimeZone((String) spinner.getSelectedItem());
if (tz != null) {
Calendar cal = new Calendar();
cal.getComponents().add(tz.getVTimeZone());
info.timeZone = cal.toString();
}
- RadioGroup typeGroup = (RadioGroup)findViewById(R.id.type);
- switch (typeGroup.getCheckedRadioButtonId()) {
- case R.id.type_events:
- info.supportsVEVENT = true;
- break;
- case R.id.type_tasks:
- info.supportsVTODO = true;
- break;
- case R.id.type_events_and_tasks:
- info.supportsVEVENT = true;
- info.supportsVTODO = true;
- break;
- }
-
if (ok) {
info.type = CollectionInfo.Type.CALENDAR;
- info.url = HttpUrl.parse(homeSet).resolve(UUID.randomUUID().toString() + "/").toString();
- CreateCollectionFragment.newInstance(account, info).show(getSupportFragmentManager(), null);
- }
- }
-
-
- @Override
- public Loader onCreateLoader(int id, Bundle args) {
- return new AccountInfoLoader(this, account);
- }
-
- @Override
- public void onLoadFinished(Loader loader, AccountInfo info) {
- Spinner spinner = (Spinner)findViewById(R.id.time_zone);
- String[] timeZones = TimeZone.getAvailableIDs();
- spinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, timeZones));
- // select system time zone
- String defaultTimeZone = TimeZone.getDefault().getID();
- for (int i = 0; i < timeZones.length; i++)
- if (timeZones[i].equals(defaultTimeZone)) {
- spinner.setSelection(i);
- break;
- }
-
- if (info != null) {
- spinner = (Spinner)findViewById(R.id.home_sets);
- spinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, info.homeSets));
- }
- }
-
- @Override
- public void onLoaderReset(Loader loader) {
- }
-
- protected static class AccountInfo {
- List homeSets = new LinkedList<>();
- }
-
- protected static class AccountInfoLoader extends AsyncTaskLoader {
- private final Account account;
- private final ServiceDB.OpenHelper dbHelper;
- public AccountInfoLoader(Context context, Account account) {
- super(context);
- this.account = account;
- dbHelper = new ServiceDB.OpenHelper(context);
- }
-
- @Override
- protected void onStartLoading() {
- forceLoad();
- }
-
- @Override
- public AccountInfo loadInBackground() {
- final AccountInfo info = new AccountInfo();
-
- // find DAV service and home sets
- SQLiteDatabase db = dbHelper.getReadableDatabase();
- try {
- @Cleanup Cursor cursorService = db.query(ServiceDB.Services._TABLE, new String[] { ServiceDB.Services.ID },
- ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?",
- new String[] { account.name, ServiceDB.Services.SERVICE_CALDAV }, null, null, null);
- if (!cursorService.moveToNext())
- return null;
- String strServiceID = cursorService.getString(0);
-
- @Cleanup Cursor cursorHomeSets = db.query(ServiceDB.HomeSets._TABLE, new String[] { ServiceDB.HomeSets.URL },
- ServiceDB.HomeSets.SERVICE_ID + "=?", new String[] { strServiceID }, null, null, null);
- while (cursorHomeSets.moveToNext())
- info.homeSets.add(cursorHomeSets.getString(0));
- } finally {
- dbHelper.close();
- }
-
- return info;
+ CreateCollectionFragment.newInstance(account, info).show(getSupportFragmentManager(), null);
}
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.java
index 852ceaf2..cdaf13e3 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.java
@@ -23,26 +23,16 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
-import org.apache.commons.lang3.BooleanUtils;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.logging.Level;
-
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.XmlUtils;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.davdroid.App;
-import at.bitfire.davdroid.DavUtils;
+import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.HttpClient;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalManager;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.model.ServiceDB;
import lombok.Cleanup;
import okhttp3.HttpUrl;
-import okhttp3.OkHttpClient;
public class CreateCollectionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks {
private static final String
@@ -127,95 +117,9 @@ public class CreateCollectionFragment extends DialogFragment implements LoaderMa
@Override
public Exception loadInBackground() {
- StringWriter writer = new StringWriter();
- try {
- XmlSerializer serializer = XmlUtils.newSerializer();
- serializer.setOutput(writer);
- serializer.startDocument("UTF-8", null);
- serializer.setPrefix("", XmlUtils.NS_WEBDAV);
- serializer.setPrefix("CAL", XmlUtils.NS_CALDAV);
- serializer.setPrefix("CARD", XmlUtils.NS_CARDDAV);
-
- serializer.startTag(XmlUtils.NS_WEBDAV, "mkcol");
- serializer.startTag(XmlUtils.NS_WEBDAV, "set");
- serializer.startTag(XmlUtils.NS_WEBDAV, "prop");
- serializer.startTag(XmlUtils.NS_WEBDAV, "resourcetype");
- serializer.startTag(XmlUtils.NS_WEBDAV, "collection");
- serializer.endTag(XmlUtils.NS_WEBDAV, "collection");
- if (info.type == CollectionInfo.Type.ADDRESS_BOOK) {
- serializer.startTag(XmlUtils.NS_CARDDAV, "addressbook");
- serializer.endTag(XmlUtils.NS_CARDDAV, "addressbook");
- } else if (info.type == CollectionInfo.Type.CALENDAR) {
- serializer.startTag(XmlUtils.NS_CALDAV, "calendar");
- serializer.endTag(XmlUtils.NS_CALDAV, "calendar");
- }
- serializer.endTag(XmlUtils.NS_WEBDAV, "resourcetype");
- if (info.displayName != null) {
- serializer.startTag(XmlUtils.NS_WEBDAV, "displayname");
- serializer.text(info.displayName);
- serializer.endTag(XmlUtils.NS_WEBDAV, "displayname");
- }
-
- // addressbook-specific properties
- if (info.type == CollectionInfo.Type.ADDRESS_BOOK) {
- if (info.description != null) {
- serializer.startTag(XmlUtils.NS_CARDDAV, "addressbook-description");
- serializer.text(info.description);
- serializer.endTag(XmlUtils.NS_CARDDAV, "addressbook-description");
- }
- }
-
- // calendar-specific properties
- if (info.type == CollectionInfo.Type.CALENDAR) {
- if (info.description != null) {
- serializer.startTag(XmlUtils.NS_CALDAV, "calendar-description");
- serializer.text(info.description);
- serializer.endTag(XmlUtils.NS_CALDAV, "calendar-description");
- }
-
- if (info.color != null) {
- serializer.startTag(XmlUtils.NS_APPLE_ICAL, "calendar-color");
- serializer.text(DavUtils.ARGBtoCalDAVColor(info.color));
- serializer.endTag(XmlUtils.NS_APPLE_ICAL, "calendar-color");
- }
-
- if (info.timeZone != null) {
- serializer.startTag(XmlUtils.NS_CALDAV, "calendar-timezone");
- serializer.cdsect(info.timeZone);
- serializer.endTag(XmlUtils.NS_CALDAV, "calendar-timezone");
- }
-
- serializer.startTag(XmlUtils.NS_CALDAV, "supported-calendar-component-set");
- if (BooleanUtils.isTrue(info.supportsVEVENT)) {
- serializer.startTag(XmlUtils.NS_CALDAV, "comp");
- serializer.attribute(null, "name", "VEVENT");
- serializer.endTag(XmlUtils.NS_CALDAV, "comp");
- }
- if (BooleanUtils.isTrue(info.supportsVTODO)) {
- serializer.startTag(XmlUtils.NS_CALDAV, "comp");
- serializer.attribute(null, "name", "VTODO");
- serializer.endTag(XmlUtils.NS_CALDAV, "comp");
- }
- serializer.endTag(XmlUtils.NS_CALDAV, "supported-calendar-component-set");
- }
-
- serializer.endTag(XmlUtils.NS_WEBDAV, "prop");
- serializer.endTag(XmlUtils.NS_WEBDAV, "set");
- serializer.endTag(XmlUtils.NS_WEBDAV, "mkcol");
- serializer.endDocument();
- } catch (IOException e) {
- App.log.log(Level.SEVERE, "Couldn't assemble Extended MKCOL request", e);
- }
-
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
try {
- OkHttpClient client = HttpClient.create(getContext(), account);
- DavResource collection = new DavResource(client, HttpUrl.parse(info.url));
-
- // create collection on remote server
- collection.mkCol(writer.toString());
-
// now insert collection into database:
SQLiteDatabase db = dbHelper.getWritableDatabase();
@@ -235,11 +139,19 @@ public class CreateCollectionFragment extends DialogFragment implements LoaderMa
throw new IllegalStateException();
long serviceID = c.getLong(0);
+ AccountSettings settings = new AccountSettings(getContext(), account);
+ HttpUrl principal = HttpUrl.get(settings.getUri());
+
+ JournalManager journalManager = new JournalManager(HttpClient.create(getContext(), account), principal);
+ journalManager.putJournal(new JournalManager.Journal(settings.password(), info.toJson(), info.url));
+
// 2. add collection to service
ContentValues values = info.toDB();
values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
db.insert(ServiceDB.Collections._TABLE, null, values);
- } catch(InvalidAccountException|IOException|HttpException|IllegalStateException e) {
+ } catch(IllegalStateException|Exceptions.HttpException e) {
+ return e;
+ } catch (InvalidAccountException e) {
return e;
} finally {
dbHelper.close();
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/DebugInfoActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/DebugInfoActivity.java
index aab4a0c0..dd8b128d 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/DebugInfoActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/DebugInfoActivity.java
@@ -38,13 +38,13 @@ import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
-import at.bitfire.dav4android.exception.HttpException;
import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.App;
import at.bitfire.davdroid.BuildConfig;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions.HttpException;
import at.bitfire.davdroid.model.ServiceDB;
import lombok.Cleanup;
@@ -159,21 +159,21 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
String logs = null,
authority = null;
Account account = null;
- int phase = -1;
+ String phase = null;
if (extras != null) {
throwable = (Throwable)extras.getSerializable(KEY_THROWABLE);
logs = extras.getString(KEY_LOGS);
account = extras.getParcelable(KEY_ACCOUNT);
authority = extras.getString(KEY_AUTHORITY);
- phase = extras.getInt(KEY_PHASE, -1);
+ phase = extras.getString(KEY_PHASE, null);
}
StringBuilder report = new StringBuilder();
// begin with most specific information
- if (phase != -1)
+ if (phase != null)
report.append("SYNCHRONIZATION INFO\nSynchronization phase: ").append(phase).append("\n");
if (account != null)
report.append("Account name: ").append(account.name).append("\n");
@@ -181,11 +181,13 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
report.append("Authority: ").append(authority).append("\n");
if (throwable instanceof HttpException) {
+ /* FIXME
HttpException http = (HttpException)throwable;
if (http.request != null)
report.append("\nHTTP REQUEST:\n").append(http.request).append("\n\n");
if (http.response != null)
report.append("HTTP RESPONSE:\n").append(http.response).append("\n");
+ */
}
if (throwable != null)
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/DeleteCollectionFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/DeleteCollectionFragment.java
index 2c63a1f5..3c7574db 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/DeleteCollectionFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/DeleteCollectionFragment.java
@@ -24,17 +24,15 @@ import android.support.v4.content.Loader;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
-import java.io.IOException;
-
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.exception.HttpException;
+import at.bitfire.davdroid.AccountSettings;
import at.bitfire.davdroid.HttpClient;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalManager;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.model.ServiceDB;
import okhttp3.HttpUrl;
-import okhttp3.OkHttpClient;
public class DeleteCollectionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks {
protected static final String
@@ -67,7 +65,7 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
@Override
public Loader onCreateLoader(int id, Bundle args) {
account = args.getParcelable(ARG_ACCOUNT);
- collectionInfo = (CollectionInfo)args.getSerializable(ARG_COLLECTION_INFO);
+ collectionInfo = (CollectionInfo) args.getSerializable(ARG_COLLECTION_INFO);
return new DeleteCollectionLoader(getContext(), account, collectionInfo);
}
@@ -82,7 +80,7 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
else {
Activity activity = getActivity();
if (activity instanceof AccountActivity)
- ((AccountActivity)activity).reload();
+ ((AccountActivity) activity).reload();
}
}
@@ -111,18 +109,21 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
@Override
public Exception loadInBackground() {
try {
- OkHttpClient httpClient = HttpClient.create(getContext(), account);
- DavResource collection = new DavResource(httpClient, HttpUrl.parse(collectionInfo.url));
-
- // delete collection from server
- collection.delete(null);
-
// delete collection locally
SQLiteDatabase db = dbHelper.getWritableDatabase();
- db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.ID + "=?", new String[] { String.valueOf(collectionInfo.id) });
+
+ AccountSettings settings = new AccountSettings(getContext(), account);
+ HttpUrl principal = HttpUrl.get(settings.getUri());
+
+ JournalManager journalManager = new JournalManager(HttpClient.create(getContext(), account), principal);
+ journalManager.deleteJournal(new JournalManager.Journal(settings.password(), collectionInfo.toJson(), collectionInfo.url));
+
+ db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.ID + "=?", new String[]{String.valueOf(collectionInfo.id)});
return null;
- } catch (InvalidAccountException|IOException|HttpException e) {
+ } catch (Exceptions.HttpException e) {
+ return e;
+ } catch (InvalidAccountException e) {
return e;
} finally {
dbHelper.close();
@@ -145,7 +146,7 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- CollectionInfo collectionInfo = (CollectionInfo)getArguments().getSerializable(ARG_COLLECTION_INFO);
+ CollectionInfo collectionInfo = (CollectionInfo) getArguments().getSerializable(ARG_COLLECTION_INFO);
String name = TextUtils.isEmpty(collectionInfo.displayName) ? collectionInfo.url : collectionInfo.displayName;
return new AlertDialog.Builder(getContext())
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/ExceptionInfoFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/ExceptionInfoFragment.java
index b39400f3..68c3e207 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/ExceptionInfoFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/ExceptionInfoFragment.java
@@ -19,8 +19,8 @@ import android.support.v7.app.AlertDialog;
import java.io.IOException;
-import at.bitfire.dav4android.exception.HttpException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Exceptions.HttpException;
public class ExceptionInfoFragment extends DialogFragment {
protected static final String
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java
index d0db8c3e..31ad0cc4 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java
@@ -14,9 +14,6 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -28,7 +25,6 @@ import android.support.v7.app.AlertDialog;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.logging.Level;
import at.bitfire.davdroid.App;
import at.bitfire.davdroid.BuildConfig;
@@ -139,7 +135,7 @@ public class StartupDialogFragment extends DialogFragment {
.setNeutralButton(R.string.startup_development_version_give_feedback, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));
+ startActivity(new Intent(Intent.ACTION_VIEW, Constants.feedbackUri));
}
})
.create();
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/DavResourceFinder.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/DavResourceFinder.java
index 403b891b..f8089e20 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/setup/DavResourceFinder.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/DavResourceFinder.java
@@ -10,61 +10,25 @@ package at.bitfire.davdroid.ui.setup;
import android.content.Context;
import android.support.annotation.NonNull;
-import org.xbill.DNS.Lookup;
-import org.xbill.DNS.Record;
-import org.xbill.DNS.SRVRecord;
-import org.xbill.DNS.TXTRecord;
-import org.xbill.DNS.Type;
-
-import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
-import java.net.URISyntaxException;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import at.bitfire.dav4android.Constants;
-import at.bitfire.dav4android.DavResource;
-import at.bitfire.dav4android.UrlUtils;
-import at.bitfire.dav4android.exception.DavException;
-import at.bitfire.dav4android.exception.HttpException;
-import at.bitfire.dav4android.exception.NotFoundException;
-import at.bitfire.dav4android.property.AddressbookDescription;
-import at.bitfire.dav4android.property.AddressbookHomeSet;
-import at.bitfire.dav4android.property.CalendarColor;
-import at.bitfire.dav4android.property.CalendarDescription;
-import at.bitfire.dav4android.property.CalendarHomeSet;
-import at.bitfire.dav4android.property.CalendarTimezone;
-import at.bitfire.dav4android.property.CalendarUserAddressSet;
-import at.bitfire.dav4android.property.CurrentUserPrincipal;
-import at.bitfire.dav4android.property.CurrentUserPrivilegeSet;
-import at.bitfire.dav4android.property.DisplayName;
-import at.bitfire.dav4android.property.ResourceType;
-import at.bitfire.dav4android.property.SupportedCalendarComponentSet;
import at.bitfire.davdroid.HttpClient;
+import at.bitfire.davdroid.journalmanager.Exceptions;
+import at.bitfire.davdroid.journalmanager.JournalAuthenticator;
import at.bitfire.davdroid.log.StringHandler;
import at.bitfire.davdroid.model.CollectionInfo;
+import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
public class DavResourceFinder {
- public enum Service {
- CALDAV("caldav"),
- CARDDAV("carddav");
-
- final String name;
- Service(String name) { this.name = name;}
- @Override public String toString() { return name; }
- }
-
protected final Context context;
protected final LoginCredentials credentials;
@@ -81,304 +45,42 @@ public class DavResourceFinder {
log.addHandler(logBuffer);
httpClient = HttpClient.create(context, log);
- httpClient = HttpClient.addAuthentication(httpClient, credentials.userName, credentials.password);
}
public Configuration findInitialConfiguration() {
- final Configuration.ServiceInfo
- cardDavConfig = findInitialConfiguration(Service.CARDDAV),
- calDavConfig = findInitialConfiguration(Service.CALDAV);
-
- return new Configuration(
- credentials.userName, credentials.password,
- cardDavConfig, calDavConfig,
- logBuffer.toString()
- );
- }
-
- protected Configuration.ServiceInfo findInitialConfiguration(@NonNull Service service) {
- // user-given base URI (either mailto: URI or http(s):// URL)
- final URI baseURI = credentials.uri;
-
- // domain for service discovery
- String discoveryFQDN = null;
-
- // put discovered information here
- final Configuration.ServiceInfo config = new Configuration.ServiceInfo();
- log.info("Finding initial " + service.name + " service configuration");
-
- if ("http".equalsIgnoreCase(baseURI.getScheme()) || "https".equalsIgnoreCase(baseURI.getScheme())) {
- final HttpUrl baseURL = HttpUrl.get(baseURI);
-
- // remember domain for service discovery
- // try service discovery only for https:// URLs because only secure service discovery is implemented
- if ("https".equalsIgnoreCase(baseURL.scheme()))
- discoveryFQDN = baseURI.getHost();
-
- checkUserGivenURL(baseURL, service, config);
-
- if (config.principal == null)
- try {
- config.principal = getCurrentUserPrincipal(baseURL.resolve("/.well-known/" + service.name), service);
- } catch (IOException|HttpException|DavException e) {
- log.log(Level.FINE, "Well-known URL detection failed", e);
- }
-
- } else if ("mailto".equalsIgnoreCase(baseURI.getScheme())) {
- String mailbox = baseURI.getSchemeSpecificPart();
-
- int posAt = mailbox.lastIndexOf("@");
- if (posAt != -1)
- discoveryFQDN = mailbox.substring(posAt + 1);
- }
-
- // Step 2: If user-given URL didn't reveal a principal, search for it: SERVICE DISCOVERY
- if (config.principal == null && discoveryFQDN != null) {
- log.info("No principal found at user-given URL, trying to discover");
- try {
- config.principal = discoverPrincipalUrl(discoveryFQDN, service);
- } catch (IOException|HttpException|DavException e) {
- log.log(Level.FINE, service.name + " service discovery failed", e);
- }
- }
-
- if (config.principal != null && service == Service.CALDAV) {
- // query email address (CalDAV scheduling: calendar-user-address-set)
- DavResource davPrincipal = new DavResource(httpClient, HttpUrl.get(config.principal), log);
- try {
- davPrincipal.propfind(0, CalendarUserAddressSet.NAME);
- CalendarUserAddressSet addressSet = (CalendarUserAddressSet)davPrincipal.properties.get(CalendarUserAddressSet.NAME);
- if (addressSet != null)
- for (String href : addressSet.hrefs)
- try {
- URI uri = new URI(href);
- if ("mailto".equals(uri.getScheme()))
- config.email = uri.getSchemeSpecificPart();
- } catch(URISyntaxException e) {
- Constants.log.log(Level.WARNING, "Unparseable user address", e);
- }
- } catch(IOException | HttpException | DavException e) {
- Constants.log.log(Level.WARNING, "Couldn't query user email address", e);
- }
- }
-
- // return config or null if config doesn't contain useful information
- boolean serviceAvailable = config.principal != null || !config.homeSets.isEmpty() || !config.collections.isEmpty();
- return serviceAvailable ? config : null;
- }
-
- protected void checkUserGivenURL(@NonNull HttpUrl baseURL, @NonNull Service service, @NonNull Configuration.ServiceInfo config) {
- log.info("Checking user-given URL: " + baseURL.toString());
-
- HttpUrl principal = null;
- try {
- DavResource davBase = new DavResource(httpClient, baseURL, log);
-
- if (service == Service.CARDDAV) {
- davBase.propfind(0,
- ResourceType.NAME, DisplayName.NAME, AddressbookDescription.NAME,
- AddressbookHomeSet.NAME,
- CurrentUserPrincipal.NAME
- );
- rememberIfAddressBookOrHomeset(davBase, config);
-
- } else if (service == Service.CALDAV) {
- davBase.propfind(0,
- ResourceType.NAME, DisplayName.NAME, CalendarColor.NAME, CalendarDescription.NAME, CalendarTimezone.NAME, CurrentUserPrivilegeSet.NAME, SupportedCalendarComponentSet.NAME,
- CalendarHomeSet.NAME,
- CurrentUserPrincipal.NAME
- );
- rememberIfCalendarOrHomeset(davBase, config);
- }
-
- // check for current-user-principal
- CurrentUserPrincipal currentUserPrincipal = (CurrentUserPrincipal)davBase.properties.get(CurrentUserPrincipal.NAME);
- if (currentUserPrincipal != null && currentUserPrincipal.href != null)
- principal = davBase.location.resolve(currentUserPrincipal.href);
-
- // check for resource type "principal"
- if (principal == null) {
- ResourceType resourceType = (ResourceType)davBase.properties.get(ResourceType.NAME);
- if (resourceType != null && resourceType.types.contains(ResourceType.PRINCIPAL))
- principal = davBase.location;
- }
-
- // If a principal has been detected successfully, ensure that it provides the required service.
- if (principal != null && providesService(principal, service))
- config.principal = principal.uri();
-
- } catch (IOException|HttpException|DavException e) {
- log.log(Level.FINE, "PROPFIND/OPTIONS on user-given URL failed", e);
- }
- }
-
- /**
- * If #dav is an address book or an address book home set, it will added to
- * config.collections or config.homesets. Only evaluates already known properties,
- * does not call dav.propfind()! URLs will be stored with trailing "/".
- * @param dav resource whose properties are evaluated
- * @param config structure where the address book (collection) and/or home set is stored into (if found)
- */
- protected void rememberIfAddressBookOrHomeset(@NonNull DavResource dav, @NonNull Configuration.ServiceInfo config) {
- // Is the collection an address book?
- ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
- if (resourceType != null && resourceType.types.contains(ResourceType.ADDRESSBOOK)) {
- dav.location = UrlUtils.withTrailingSlash(dav.location);
- log.info("Found address book at " + dav.location);
- config.collections.put(dav.location.uri(), CollectionInfo.fromDavResource(dav));
- }
-
- // Does the collection refer to address book homesets?
- AddressbookHomeSet homeSets = (AddressbookHomeSet)dav.properties.get(AddressbookHomeSet.NAME);
- if (homeSets != null)
- for (String href : homeSets.hrefs) {
- HttpUrl location = UrlUtils.withTrailingSlash(dav.location.resolve(href));
- log.info("Found addressbook home-set at " + location);
- config.homeSets.add(location.uri());
- }
- }
+ boolean failed = false;
+ Configuration.ServiceInfo
+ cardDavConfig = findInitialConfiguration(CollectionInfo.Type.ADDRESS_BOOK),
+ calDavConfig = findInitialConfiguration(CollectionInfo.Type.CALENDAR);
- protected void rememberIfCalendarOrHomeset(@NonNull DavResource dav, @NonNull Configuration.ServiceInfo config) {
- // Is the collection a calendar collection?
- ResourceType resourceType = (ResourceType)dav.properties.get(ResourceType.NAME);
- if (resourceType != null && resourceType.types.contains(ResourceType.CALENDAR)) {
- dav.location = UrlUtils.withTrailingSlash(dav.location);
- log.info("Found calendar collection at " + dav.location);
- config.collections.put(dav.location.uri(), CollectionInfo.fromDavResource(dav));
- }
-
- // Does the collection refer to calendar homesets?
- CalendarHomeSet homeSets = (CalendarHomeSet)dav.properties.get(CalendarHomeSet.NAME);
- if (homeSets != null)
- for (String href : homeSets.hrefs)
- config.homeSets.add(UrlUtils.withTrailingSlash(dav.location.resolve(href)).uri());
- }
+ JournalAuthenticator authenticator = new JournalAuthenticator(httpClient, HttpUrl.get(credentials.uri));
-
- protected boolean providesService(HttpUrl url, Service service) throws IOException {
- DavResource davPrincipal = new DavResource(httpClient, url, log);
+ String authtoken = null;
try {
- davPrincipal.options();
-
- if ((service == Service.CARDDAV && davPrincipal.capabilities.contains("addressbook")) ||
- (service == Service.CALDAV && davPrincipal.capabilities.contains("calendar-access")))
- return true;
+ authtoken = authenticator.getAuthToken(credentials.userName, credentials.password);
+ } catch (Exceptions.HttpException e) {
+ log.warning(e.getMessage());
- } catch (HttpException|DavException e) {
- log.log(Level.SEVERE, "Couldn't detect services on " + url, e);
+ failed = true;
}
- return false;
- }
-
-
- /**
- * Try to find the principal URL by performing service discovery on a given domain name.
- * Only secure services (caldavs, carddavs) will be discovered!
- * @param domain domain name, e.g. "icloud.com"
- * @param service service to discover (CALDAV or CARDDAV)
- * @return principal URL, or null if none found
- */
- protected URI discoverPrincipalUrl(@NonNull String domain, @NonNull Service service) throws IOException, HttpException, DavException {
- String scheme;
- String fqdn;
- Integer port = 443;
- List paths = new LinkedList<>(); // there may be multiple paths to try
-
- final String query = "_" + service.name + "s._tcp." + domain;
- log.fine("Looking up SRV records for " + query);
- Record[] records = new Lookup(query, Type.SRV).run();
- if (records != null && records.length >= 1) {
- // choose SRV record to use (query may return multiple SRV records)
- SRVRecord srv = selectSRVRecord(records);
-
- scheme = "https";
- fqdn = srv.getTarget().toString(true);
- port = srv.getPort();
- log.info("Found " + service + " service at https://" + fqdn + ":" + port);
-
- } else {
- // no SRV records, try domain name as FQDN
- log.info("Didn't find " + service + " service, trying at https://" + domain + ":" + port);
-
- scheme = "https";
- fqdn = domain;
- }
-
- // look for TXT record too (for initial context path)
- records = new Lookup(query, Type.TXT).run();
- if (records != null)
- for (Record record : records)
- if (record instanceof TXTRecord)
- for (String segment : (List)((TXTRecord)record).getStrings())
- if (segment.startsWith("path=")) {
- paths.add(segment.substring(5));
- log.info("Found TXT record; initial context path=" + paths);
- break;
- }
- // if there's TXT record and if it it's wrong, try well-known
- paths.add("/.well-known/" + service.name);
- // if this fails, too, try "/"
- paths.add("/");
-
- for (String path : paths)
- try {
- HttpUrl initialContextPath = new HttpUrl.Builder()
- .scheme(scheme)
- .host(fqdn).port(port)
- .encodedPath(path)
- .build();
-
- log.info("Trying to determine principal from initial context path=" + initialContextPath);
- URI principal = getCurrentUserPrincipal(initialContextPath, service);
-
- if (principal != null)
- return principal;
- } catch(NotFoundException|IllegalArgumentException e) {
- log.log(Level.WARNING, "No resource found", e);
- }
- return null;
+ return new Configuration(
+ credentials.uri,
+ credentials.userName, authtoken,
+ cardDavConfig, calDavConfig,
+ logBuffer.toString(), failed
+ );
}
- /**
- * Queries a given URL for current-user-principal
- * @param url URL to query with PROPFIND (Depth: 0)
- * @param service required service (may be null, in which case no service check is done)
- * @return current-user-principal URL that provides required service, or null if none
- */
- public URI getCurrentUserPrincipal(HttpUrl url, Service service) throws IOException, HttpException, DavException {
- DavResource dav = new DavResource(httpClient, url, log);
- dav.propfind(0, CurrentUserPrincipal.NAME);
-
- CurrentUserPrincipal currentUserPrincipal = (CurrentUserPrincipal)dav.properties.get(CurrentUserPrincipal.NAME);
- if (currentUserPrincipal != null && currentUserPrincipal.href != null) {
- HttpUrl principal = dav.location.resolve(currentUserPrincipal.href);
- if (principal != null) {
- log.info("Found current-user-principal: " + principal);
-
- // service check
- if (service != null && !providesService(principal, service)) {
- log.info(principal + " doesn't provide required " + service + " service");
- principal = null;
- }
+ protected Configuration.ServiceInfo findInitialConfiguration(@NonNull CollectionInfo.Type service) {
+ // put discovered information here
+ final Configuration.ServiceInfo config = new Configuration.ServiceInfo();
+ log.info("Finding initial " + service.toString() + " service configuration");
- return principal != null ? principal.uri() : null;
- }
- }
- return null;
+ return config;
}
-
- // helpers
-
- private SRVRecord selectSRVRecord(Record[] records) {
- if (records.length > 1)
- log.warning("Multiple SRV records not supported yet; using first one");
- return (SRVRecord)records[0];
- }
-
-
// data classes
@RequiredArgsConstructor
@@ -388,20 +90,22 @@ public class DavResourceFinder {
@ToString
public static class ServiceInfo implements Serializable {
- public URI principal;
- public final Set homeSets = new HashSet<>();
- public final Map collections = new HashMap<>();
-
- public String email;
+ public final Map collections = new HashMap<>();
}
- public final String userName, password;
+ public final URI url;
+
+ public final String userName, authtoken;
+ public String rawPassword;
+ public String password;
public final ServiceInfo cardDAV;
public final ServiceInfo calDAV;
public final String logs;
+ @Getter
+ private final boolean failed;
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.java
index 455bc3fc..49a28bee 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.java
@@ -64,7 +64,7 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
@Override
public void onLoadFinished(Loader loader, Configuration data) {
if (data != null) {
- if (data.calDAV == null && data.cardDAV == null)
+ if (data.isFailed())
// no service found: show error message
getFragmentManager().beginTransaction()
.add(NothingDetectedFragment.newInstance(data.logs), null)
@@ -72,7 +72,7 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
else
// service found: continue
getFragmentManager().beginTransaction()
- .replace(android.R.id.content, AccountDetailsFragment.newInstance(data))
+ .replace(android.R.id.content, EncryptionDetailsFragment.newInstance(data))
.addToBackStack(null)
.commitAllowingStateLoss();
} else
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/EncryptionDetailsFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/EncryptionDetailsFragment.java
new file mode 100644
index 00000000..a7bd6f97
--- /dev/null
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/EncryptionDetailsFragment.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Public License v3.0
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/gpl.html
+ */
+
+package at.bitfire.davdroid.ui.setup;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.ui.widget.EditPassword;
+
+public class EncryptionDetailsFragment extends Fragment {
+
+ private static final String KEY_CONFIG = "config";
+ EditPassword editPassword = null;
+
+
+ public static EncryptionDetailsFragment newInstance(DavResourceFinder.Configuration config) {
+ EncryptionDetailsFragment frag = new EncryptionDetailsFragment();
+ Bundle args = new Bundle(1);
+ args.putSerializable(KEY_CONFIG, config);
+ frag.setArguments(args);
+ return frag;
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View v = inflater.inflate(R.layout.login_encryption_details, container, false);
+
+ Button btnBack = (Button)v.findViewById(R.id.back);
+ btnBack.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getFragmentManager().popBackStack();
+ }
+ });
+
+ final DavResourceFinder.Configuration config = (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG);
+
+ TextView accountName = (TextView)v.findViewById(R.id.account_name);
+ accountName.setText(getString(R.string.login_encryption_account_label) + " " + config.userName);
+
+ editPassword = (EditPassword) v.findViewById(R.id.encryption_password);
+
+ Button btnCreate = (Button)v.findViewById(R.id.create_account);
+ btnCreate.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (validateEncryptionData(config) == null) {
+ return;
+ }
+
+ SetupEncryptionFragment.newInstance(config).show(getFragmentManager(), null);
+ }
+ });
+
+ return v;
+ }
+
+ private DavResourceFinder.Configuration validateEncryptionData(DavResourceFinder.Configuration config) {
+ boolean valid = true;
+ String password = editPassword.getText().toString();
+ if (password.isEmpty()) {
+ editPassword.setError(getString(R.string.login_password_required));
+ valid = false;
+ }
+
+ config.rawPassword = password;
+
+ return valid ? config : null;
+ }
+}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.java
index 8121f56e..48691790 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.java
@@ -23,16 +23,8 @@ import at.bitfire.davdroid.R;
* Fields for server/user data can be pre-filled with extras in the Intent.
*/
public class LoginActivity extends AppCompatActivity {
-
- /**
- * When set, "login by URL" will be activated by default, and the URL field will be set to this value.
- * When not set, "login by email" will be activated by default.
- */
- public static final String EXTRA_URL = "url";
-
/**
* When set, and {@link #EXTRA_PASSWORD} is set too, the user name field will be set to this value.
- * When set, and {@link #EXTRA_URL} is not set, the email address field will be set to this value.
*/
public static final String EXTRA_USERNAME = "username";
@@ -79,6 +71,6 @@ public class LoginActivity extends AppCompatActivity {
}
public void showHelp(MenuItem item) {
- startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("configuration/").build()));
+ startActivity(new Intent(Intent.ACTION_VIEW, Constants.helpUri));
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java
index 48fc2194..6bc6e1f0 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java
@@ -17,32 +17,24 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-import android.widget.CompoundButton;
import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
import org.apache.commons.lang3.StringUtils;
import java.net.IDN;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.util.logging.Level;
-import at.bitfire.dav4android.Constants;
+import at.bitfire.davdroid.App;
+import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.ui.widget.EditPassword;
-public class LoginCredentialsFragment extends Fragment implements CompoundButton.OnCheckedChangeListener {
-
- RadioButton radioUseEmail;
- LinearLayout emailDetails;
- EditText editEmailAddress;
- EditPassword editEmailPassword;
-
- RadioButton radioUseURL;
- LinearLayout urlDetails;
- EditText editBaseURL, editUserName;
+public class LoginCredentialsFragment extends Fragment {
+ EditText editUserName;
EditPassword editUrlPassword;
@@ -50,47 +42,33 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.login_credentials_fragment, container, false);
- radioUseEmail = (RadioButton)v.findViewById(R.id.login_type_email);
- emailDetails = (LinearLayout)v.findViewById(R.id.login_type_email_details);
- editEmailAddress = (EditText)v.findViewById(R.id.email_address);
- editEmailPassword = (EditPassword)v.findViewById(R.id.email_password);
-
- radioUseURL = (RadioButton)v.findViewById(R.id.login_type_url);
- urlDetails = (LinearLayout)v.findViewById(R.id.login_type_url_details);
- editBaseURL = (EditText)v.findViewById(R.id.base_url);
- editUserName = (EditText)v.findViewById(R.id.user_name);
- editUrlPassword = (EditPassword)v.findViewById(R.id.url_password);
-
- radioUseEmail.setOnCheckedChangeListener(this);
- radioUseURL.setOnCheckedChangeListener(this);
+ editUserName = (EditText) v.findViewById(R.id.user_name);
+ editUrlPassword = (EditPassword) v.findViewById(R.id.url_password);
if (savedInstanceState == null) {
- // first call
-
Activity activity = getActivity();
Intent intent = (activity != null) ? activity.getIntent() : null;
if (intent != null) {
// we've got initial login data
- String url = intent.getStringExtra(LoginActivity.EXTRA_URL),
- username = intent.getStringExtra(LoginActivity.EXTRA_USERNAME),
+ String username = intent.getStringExtra(LoginActivity.EXTRA_USERNAME),
password = intent.getStringExtra(LoginActivity.EXTRA_PASSWORD);
- if (url != null) {
- radioUseURL.setChecked(true);
- editBaseURL.setText(url);
- editUserName.setText(username);
- editUrlPassword.setText(password);
- } else {
- radioUseEmail.setChecked(true);
- editEmailAddress.setText(username);
- editEmailPassword.setText(password);
- }
-
- } else
- radioUseEmail.setChecked(true);
+ editUserName.setText(username);
+ editUrlPassword.setText(password);
+ }
}
- final Button login = (Button)v.findViewById(R.id.login);
+ final Button createAccount = (Button) v.findViewById(R.id.create_account);
+ createAccount.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Uri createUri = Constants.registrationUrl.buildUpon().appendQueryParameter("email", editUserName.getText().toString()).build();
+ Intent intent = new Intent(Intent.ACTION_VIEW, createUri);
+ startActivity(intent);
+ }
+ });
+
+ final Button login = (Button) v.findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -103,88 +81,29 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
return v;
}
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- boolean loginByEmail = buttonView == radioUseEmail;
- emailDetails.setVisibility(loginByEmail ? View.VISIBLE : View.GONE);
- urlDetails.setVisibility(loginByEmail ? View.GONE : View.VISIBLE);
- (loginByEmail ? editEmailAddress : editBaseURL).requestFocus();
- }
- }
-
protected LoginCredentials validateLoginData() {
- if (radioUseEmail.isChecked()) {
- URI uri = null;
- boolean valid = true;
-
- String email = editEmailAddress.getText().toString();
- if (!email.matches(".+@.+")) {
- editEmailAddress.setError(getString(R.string.login_email_address_error));
- valid = false;
- } else
- try {
- uri = new URI("mailto", email, null);
- } catch (URISyntaxException e) {
- editEmailAddress.setError(e.getLocalizedMessage());
- valid = false;
- }
-
- String password = editEmailPassword.getText().toString();
- if (password.isEmpty()) {
- editEmailPassword.setError(getString(R.string.login_password_required));
- valid = false;
- }
+ boolean valid = true;
- return valid ? new LoginCredentials(uri, email, password) : null;
-
- } else if (radioUseURL.isChecked()) {
- URI uri = null;
- boolean valid = true;
-
- Uri baseUrl = Uri.parse(editBaseURL.getText().toString());
- String scheme = baseUrl.getScheme();
- if ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme)) {
- String host = baseUrl.getHost();
- if (StringUtils.isEmpty(host)) {
- editBaseURL.setError(getString(R.string.login_url_host_name_required));
- valid = false;
- } else
- try {
- host = IDN.toASCII(host);
- } catch(IllegalArgumentException e) {
- Constants.log.log(Level.WARNING, "Host name not conforming to RFC 3490", e);
- }
-
- String path = baseUrl.getEncodedPath();
- int port = baseUrl.getPort();
- try {
- uri = new URI(baseUrl.getScheme(), null, host, port, path, null, null);
- } catch (URISyntaxException e) {
- editBaseURL.setError(e.getLocalizedMessage());
- valid = false;
- }
- } else {
- editBaseURL.setError(getString(R.string.login_url_must_be_http_or_https));
- valid = false;
- }
-
- String userName = editUserName.getText().toString();
- if (userName.isEmpty()) {
- editUserName.setError(getString(R.string.login_user_name_required));
- valid = false;
- }
+ URI uri = null;
+ try {
+ uri = new URI(Constants.serviceUrl.toString());
+ } catch (URISyntaxException e) {
+ App.log.severe("Should never happen, it's a constant");
+ }
- String password = editUrlPassword.getText().toString();
- if (password.isEmpty()) {
- editUrlPassword.setError(getString(R.string.login_password_required));
- valid = false;
- }
+ String userName = editUserName.getText().toString();
+ if (userName.isEmpty()) {
+ editUserName.setError(getString(R.string.login_user_name_required));
+ valid = false;
+ }
- return valid ? new LoginCredentials(uri, userName, password) : null;
+ String password = editUrlPassword.getText().toString();
+ if (password.isEmpty()) {
+ editUrlPassword.setError(getString(R.string.login_password_required));
+ valid = false;
}
- return null;
+ return valid ? new LoginCredentials(uri, userName, password) : null;
}
}
diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/SetupEncryptionFragment.java
similarity index 54%
rename from app/src/main/java/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.java
rename to app/src/main/java/at/bitfire/davdroid/ui/setup/SetupEncryptionFragment.java
index e75647df..2d76a52d 100644
--- a/app/src/main/java/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.java
+++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/SetupEncryptionFragment.java
@@ -11,23 +11,22 @@ package at.bitfire.davdroid.ui.setup;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.provider.ContactsContract;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.Spinner;
-
-import java.net.URI;
+import android.support.annotation.NonNull;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
+
import java.util.logging.Level;
import at.bitfire.davdroid.AccountSettings;
@@ -36,78 +35,93 @@ import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.DavService;
import at.bitfire.davdroid.InvalidAccountException;
import at.bitfire.davdroid.R;
+import at.bitfire.davdroid.journalmanager.Helpers;
import at.bitfire.davdroid.model.CollectionInfo;
-import at.bitfire.davdroid.model.ServiceDB.Collections;
-import at.bitfire.davdroid.model.ServiceDB.HomeSets;
-import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
-import at.bitfire.davdroid.model.ServiceDB.Services;
+import at.bitfire.davdroid.model.ServiceDB;
import at.bitfire.davdroid.resource.LocalTaskList;
+import at.bitfire.davdroid.ui.setup.DavResourceFinder.Configuration;
import at.bitfire.ical4android.TaskProvider;
-import at.bitfire.vcard4android.GroupMethod;
import lombok.Cleanup;
-public class AccountDetailsFragment extends Fragment {
-
+public class SetupEncryptionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks {
private static final String KEY_CONFIG = "config";
- Spinner spnrGroupMethod;
-
-
- public static AccountDetailsFragment newInstance(DavResourceFinder.Configuration config) {
- AccountDetailsFragment frag = new AccountDetailsFragment();
+ public static SetupEncryptionFragment newInstance(DavResourceFinder.Configuration config) {
+ SetupEncryptionFragment frag = new SetupEncryptionFragment();
Bundle args = new Bundle(1);
args.putSerializable(KEY_CONFIG, config);
frag.setArguments(args);
return frag;
}
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ ProgressDialog progress = new ProgressDialog(getActivity());
+ progress.setTitle(R.string.login_encryption_setup_title);
+ progress.setMessage(getString(R.string.login_encryption_setup));
+ progress.setIndeterminate(true);
+ progress.setCanceledOnTouchOutside(false);
+ setCancelable(false);
+ return progress;
+ }
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- final View v = inflater.inflate(R.layout.login_account_details, container, false);
-
- Button btnBack = (Button)v.findViewById(R.id.back);
- btnBack.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getFragmentManager().popBackStack();
- }
- });
-
- DavResourceFinder.Configuration config = (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG);
-
- final EditText editName = (EditText)v.findViewById(R.id.account_name);
- editName.setText((config.calDAV != null && config.calDAV.email != null) ? config.calDAV.email : config.userName);
-
- // CardDAV-specific
- v.findViewById(R.id.carddav).setVisibility(config.cardDAV != null ? View.VISIBLE : View.GONE);
- spnrGroupMethod = (Spinner)v.findViewById(R.id.contact_group_method);
-
- Button btnCreate = (Button)v.findViewById(R.id.create_account);
- btnCreate.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String name = editName.getText().toString();
- if (name.isEmpty())
- editName.setError(getString(R.string.login_account_name_required));
- else {
- if (createAccount(name, (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG))) {
- getActivity().setResult(Activity.RESULT_OK);
- getActivity().finish();
- } else
- Snackbar.make(v, R.string.login_account_not_created, Snackbar.LENGTH_LONG).show();
- }
- }
- });
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getLoaderManager().initLoader(0, getArguments(), this);
+ }
+
+ @Override
+ public Loader onCreateLoader(int id, Bundle args) {
+ return new SetupEncryptionLoader(getContext(), (Configuration)args.getSerializable(KEY_CONFIG));
+ }
+
+ @Override
+ public void onLoadFinished(Loader loader, Configuration config) {
+ if (createAccount(config.userName, config)) {
+ getActivity().setResult(Activity.RESULT_OK);
+ getActivity().finish();
+ } else {
+ App.log.severe("Account creation failed!");
+ }
- return v;
+ dismissAllowingStateLoss();
}
+ @Override
+ public void onLoaderReset(Loader loader) {
+ }
+
+ static class SetupEncryptionLoader extends AsyncTaskLoader {
+ final Context context;
+ final Configuration config;
+
+ public SetupEncryptionLoader(Context context, Configuration config) {
+ super(context);
+ this.context = context;
+ this.config = config;
+ }
+
+ @Override
+ protected void onStartLoading() {
+ forceLoad();
+ }
+
+ @Override
+ public Configuration loadInBackground() {
+ config.password = Helpers.deriveKey(config.userName, config.rawPassword);
+ return config;
+ }
+ }
+
+
protected boolean createAccount(String accountName, DavResourceFinder.Configuration config) {
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);
// create Android account
- Bundle userData = AccountSettings.initialUserData(config.userName);
+ Bundle userData = AccountSettings.initialUserData(config.url, config.userName);
App.log.log(Level.INFO, "Creating Android account with initial config", new Object[] { account, userData });
AccountManager accountManager = AccountManager.get(getContext());
@@ -116,7 +130,7 @@ public class AccountDetailsFragment extends Fragment {
// add entries for account to service DB
App.log.log(Level.INFO, "Writing account configuration to database", config);
- @Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
+ @Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
AccountSettings settings = new AccountSettings(getContext(), account);
@@ -124,19 +138,16 @@ public class AccountDetailsFragment extends Fragment {
Intent refreshIntent = new Intent(getActivity(), DavService.class);
refreshIntent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
+ settings.setAuthToken(config.authtoken);
+
if (config.cardDAV != null) {
// insert CardDAV service
- long id = insertService(db, accountName, Services.SERVICE_CARDDAV, config.cardDAV);
+ long id = insertService(db, accountName, ServiceDB.Services.SERVICE_CARDDAV, config.cardDAV);
// start CardDAV service detection (refresh collections)
refreshIntent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, id);
getActivity().startService(refreshIntent);
- // initial CardDAV account settings
- int idx = spnrGroupMethod.getSelectedItemPosition();
- String groupMethodName = getResources().getStringArray(R.array.settings_contact_group_method_values)[idx];
- settings.setGroupMethod(GroupMethod.valueOf(groupMethodName));
-
// enable contact sync
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1);
settings.setSyncInterval(ContactsContract.AUTHORITY, Constants.DEFAULT_SYNC_INTERVAL);
@@ -144,7 +155,7 @@ public class AccountDetailsFragment extends Fragment {
if (config.calDAV != null) {
// insert CalDAV service
- long id = insertService(db, accountName, Services.SERVICE_CALDAV, config.calDAV);
+ long id = insertService(db, accountName, ServiceDB.Services.SERVICE_CALDAV, config.calDAV);
// start CalDAV service detection (refresh collections)
refreshIntent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, id);
@@ -173,28 +184,17 @@ public class AccountDetailsFragment extends Fragment {
ContentValues values = new ContentValues();
// insert service
- values.put(Services.ACCOUNT_NAME, accountName);
- values.put(Services.SERVICE, service);
- if (info.principal != null)
- values.put(Services.PRINCIPAL, info.principal.toString());
- long serviceID = db.insertWithOnConflict(Services._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
-
- // insert home sets
- for (URI homeSet : info.homeSets) {
- values.clear();
- values.put(HomeSets.SERVICE_ID, serviceID);
- values.put(HomeSets.URL, homeSet.toString());
- db.insertWithOnConflict(HomeSets._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
- }
+ values.put(ServiceDB.Services.ACCOUNT_NAME, accountName);
+ values.put(ServiceDB.Services.SERVICE, service);
+ long serviceID = db.insertWithOnConflict(ServiceDB.Services._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
// insert collections
for (CollectionInfo collection : info.collections.values()) {
values = collection.toDB();
- values.put(Collections.SERVICE_ID, serviceID);
- db.insertWithOnConflict(Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
+ values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
+ db.insertWithOnConflict(ServiceDB.Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
return serviceID;
}
-
}
diff --git a/app/src/main/res/drawable/ic_bug_report.xml b/app/src/main/res/drawable/ic_bug_report.xml
new file mode 100644
index 00000000..986da822
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bug_report.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_email_black.xml b/app/src/main/res/drawable/ic_email_black.xml
new file mode 100644
index 00000000..b5a773fa
--- /dev/null
+++ b/app/src/main/res/drawable/ic_email_black.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/account_caldav_item.xml b/app/src/main/res/layout/account_caldav_item.xml
index 5fea3723..e9cff432 100644
--- a/app/src/main/res/layout/account_caldav_item.xml
+++ b/app/src/main/res/layout/account_caldav_item.xml
@@ -58,16 +58,4 @@
android:layout_height="32dp"
android:background="@drawable/ic_remove_circle_dark"/>
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/account_carddav_item.xml b/app/src/main/res/layout/account_carddav_item.xml
index 7024b74b..1d6e266d 100644
--- a/app/src/main/res/layout/account_carddav_item.xml
+++ b/app/src/main/res/layout/account_carddav_item.xml
@@ -14,15 +14,6 @@
android:padding="8dp"
android:gravity="center_vertical">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_credentials_fragment.xml b/app/src/main/res/layout/login_credentials_fragment.xml
index 3ea46896..b27ed169 100644
--- a/app/src/main/res/layout/login_credentials_fragment.xml
+++ b/app/src/main/res/layout/login_credentials_fragment.xml
@@ -13,90 +13,42 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
-
-
-
-
-
+ android:orientation="vertical">
-
+ style="@style/login_type_headline"
+ android:text="@string/login_enter_service_details"
+ android:layout_marginBottom="14dp"/>
-
-
-
-
-
+ android:text="@string/login_service_details_description"
+ android:layout_marginBottom="14dp"/>
-
-
-
+
-
-
-
-
-
-
+ android:hint="@string/login_password"/>
-
+
+
+
-
+ android:layout_height="wrap_content"/>
-
-
-
-
-
-
-
-
-
+ android:hint="@string/login_encryption_password"/>
@@ -85,7 +62,7 @@
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center"
- android:text="@string/login_create_account"
+ android:text="@string/login_signup"
style="@style/stepper_nav_button"/>
diff --git a/app/src/main/res/menu/activity_account.xml b/app/src/main/res/menu/activity_account.xml
index 6fc1c333..d591ff6f 100644
--- a/app/src/main/res/menu/activity_account.xml
+++ b/app/src/main/res/menu/activity_account.xml
@@ -20,10 +20,6 @@
android:title="@string/account_settings"
app:showAsAction="ifRoom"/>
-
-
diff --git a/app/src/main/res/menu/activity_accounts_drawer.xml b/app/src/main/res/menu/activity_accounts_drawer.xml
index df75714c..f399653e 100644
--- a/app/src/main/res/menu/activity_accounts_drawer.xml
+++ b/app/src/main/res/menu/activity_accounts_drawer.xml
@@ -19,16 +19,6 @@
android:icon="@drawable/ic_settings_dark"
android:title="@string/navigation_drawer_settings"/>
- -
-
-
-
-
-
-
+ android:id="@+id/nav_report_issue"
+ android:icon="@drawable/ic_bug_report"
+ android:title="@string/navigation_drawer_report_issue"/>
+ android:id="@+id/nav_contact"
+ android:icon="@drawable/ic_email_black"
+ android:title="@string/navigation_drawer_contact"/>
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 9dc20f5a..b4e67ebd 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -1,5 +1,5 @@
-
+
DAVdroid
Ajuda
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e7ebf720..16d304f3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -59,6 +59,8 @@
FAQ
Community
Donate
+ Report issue
+ Contact developer
Welcome to DAVdroid!\n\nYou can add a CalDAV/CardDAV account now.
@@ -125,6 +127,7 @@
Email address
Valid email address required
Password
+ Encryption Password
Password required
Login with URL and user name
URL must begin with http(s)://
@@ -132,9 +135,13 @@
User name
User name required
Base URL
- Login
+ Log In
+ Sign Up
Back
- Create account
+ Enter Login Details
+ Secret Encryption Password
+ Account:
+ This is your login password, *not* your encryption password!
Account name
Use your email address as account name because Android will use the account name as ORGANIZER field for events you create. You can\'t have two accounts with the same name.
Contact group method:
@@ -146,14 +153,21 @@
Couldn\'t find CalDAV or CardDAV service.
View logs
+ Setting up encryption
+ Please wait, setting up encryption…
+
Settings: %s
Authentication
+ Encryption
User name
Enter user name:
Password
- Update the password according to your server.
+ Change your authentication password.
Enter your password:
+ Encryption Password
+ Change your encryption password (not implemented)
+ Enter your encryption password:
Synchronization
Contacts sync. interval
Only manually
@@ -188,7 +202,7 @@
Will only synchronize over %s
All WiFi connections may be used
Enter the name of a WiFi network (SSID) to restrict synchronization to this network, or leave blank for all WiFi connections.
- CardDAV
+ Contacts
Contact group method
- GROUP_VCARDS
@@ -198,7 +212,7 @@
- Groups are separate VCards
- Groups are per-contact categories
- CalDAV
+ Calendar
Past event time limit
All events will be synchronized
@@ -220,7 +234,7 @@
Calendar (only events)
Task list (only tasks)
Combined (events and tasks)
- Set a collection color
+ Set the calendar\'s color
Creating collection
Display name (title) of this collection:
Title is required
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 058d47c7..8444dda6 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -10,14 +10,15 @@
- #388e3c
+
+ #ffa100
- #aed581
- #8bc34a
- #689f38
+ #ffd54f
+ #ffc107
+ #ffa100
- #ffa726
- #ff6d00
+ #29b6f6
+ #0288d1
#eeeeee
#616161
diff --git a/app/src/main/res/xml/contacts.xml b/app/src/main/res/xml/contacts.xml
index 1b98b37e..d4bda98a 100644
--- a/app/src/main/res/xml/contacts.xml
+++ b/app/src/main/res/xml/contacts.xml
@@ -7,7 +7,7 @@
~ http://www.gnu.org/licenses/gpl.html
-->
-
+
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/test/java/at/bitfire/davdroid/ArrayUtilsTest.java b/app/src/test/java/at/bitfire/davdroid/ArrayUtilsTest.java
deleted file mode 100644
index f2bf026d..00000000
--- a/app/src/test/java/at/bitfire/davdroid/ArrayUtilsTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package at.bitfire.davdroid;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-import static org.junit.Assert.assertTrue;
-
-
-public class ArrayUtilsTest {
-
- @Test
- public void testPartition() {
- // n == 0
- assertTrue(Arrays.deepEquals(
- new Long[0][0],
- ArrayUtils.partition(new Long[] {}, 5)));
-
- // n < max
- assertTrue(Arrays.deepEquals(
- new Long[][] { { 1l, 2l } },
- ArrayUtils.partition(new Long[] { 1l, 2l }, 5)));
-
- // n == max
- assertTrue(Arrays.deepEquals(
- new Long[][] { { 1l, 2l }, { 3l, 4l } },
- ArrayUtils.partition(new Long[] { 1l, 2l, 3l, 4l }, 2)));
-
- // n > max
- assertTrue(Arrays.deepEquals(
- new Long[][] { { 1l, 2l, 3l, 4l, 5l }, { 6l, 7l, 8l, 9l, 10l }, { 11l } },
- ArrayUtils.partition(new Long[] { 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l, 10l, 11l }, 5)));
- }
-
-}
diff --git a/app/src/test/java/at/bitfire/davdroid/TestDavUtils.java b/app/src/test/java/at/bitfire/davdroid/TestDavUtils.java
deleted file mode 100644
index 8a1d6266..00000000
--- a/app/src/test/java/at/bitfire/davdroid/TestDavUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-package at.bitfire.davdroid;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class TestDavUtils {
-
- private static final String exampleURL = "http://example.com/";
-
- @Test
- public void testLastSegmentOfUrl() {
- assertEquals("/", DavUtils.lastSegmentOfUrl(exampleURL));
- assertEquals("dir", DavUtils.lastSegmentOfUrl(exampleURL + "dir"));
- assertEquals("dir", DavUtils.lastSegmentOfUrl(exampleURL + "dir/"));
- assertEquals("file.html", DavUtils.lastSegmentOfUrl(exampleURL + "dir/file.html"));
- }
-
-}
diff --git a/dav4android b/dav4android
deleted file mode 160000
index 62ac4921..00000000
--- a/dav4android
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 62ac4921ec5d5f366d0d79169a4bba94eb65ef48
diff --git a/doc/.gitignore b/doc/.gitignore
deleted file mode 100644
index ba62ebb0..00000000
--- a/doc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-javadoc/
diff --git a/doc/DAVdroid-Linuxwochen-2016.odp b/doc/DAVdroid-Linuxwochen-2016.odp
deleted file mode 100644
index 129f0300..00000000
Binary files a/doc/DAVdroid-Linuxwochen-2016.odp and /dev/null differ
diff --git a/doc/NIST.SP.800-52r1.pdf b/doc/NIST.SP.800-52r1.pdf
deleted file mode 100644
index 0436449b..00000000
Binary files a/doc/NIST.SP.800-52r1.pdf and /dev/null differ
diff --git a/doc/caldav-proxy.txt b/doc/caldav-proxy.txt
deleted file mode 100644
index 2d96bfc8..00000000
--- a/doc/caldav-proxy.txt
+++ /dev/null
@@ -1,560 +0,0 @@
-
-
-
-Calendar Server Extension C. Daboo
- Apple Computer
- May 3, 2007
-
-
- Calendar User Proxy Functionality in CalDAV
- caldav-cu-proxy-02
-
-Abstract
-
- This specification defines an extension to CalDAV that makes it easy
- for clients to setup and manage calendar user proxies, using the
- WebDAV Access Control List extension as a basis.
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
- 2. Conventions Used in This Document . . . . . . . . . . . . . . 2
- 3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3.1. Server . . . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3.2. Client . . . . . . . . . . . . . . . . . . . . . . . . . . 3
- 4. Open Issues . . . . . . . . . . . . . . . . . . . . . . . . . 4
- 5. New features in CalDAV . . . . . . . . . . . . . . . . . . . . 4
- 5.1. Proxy Principal Resource . . . . . . . . . . . . . . . . . 4
- 5.2. Privilege Provisioning . . . . . . . . . . . . . . . . . . 8
- 6. Security Considerations . . . . . . . . . . . . . . . . . . . 9
- 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9
- 8. Normative References . . . . . . . . . . . . . . . . . . . . . 9
- Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . . 9
- Appendix B. Change History . . . . . . . . . . . . . . . . . . . 10
- Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo [Page 1]
-
- CalDAV Proxy May 2007
-
-
-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 protocol [RFC2518], it also includes the ability to manage
- access to calendar data via the WebDAV ACL extension [RFC3744].
-
- It is often common for a calendar user to delegate some form of
- responsibility for their calendar and schedules to another calendar
- user (e.g., a boss allows an assistant to check a calendar or to send
- and accept scheduling invites on his behalf). The user handling the
- calendar data on behalf of someone else is often referred to as a
- "calendar user proxy".
-
- Whilst CalDAV does have fine-grained access control features that can
- be used to setup complex sharing and management of calendars, often
- the proxy behavior required is an "all-or-nothing" approach - i.e.
- the proxy has access to all the calendars or to no calendars (in
- which case they are of course not a proxy). So a simple way to
- manage access to an entire set of calendars and scheduling ability
- would be handy.
-
- In addition, calendar user agents will often want to display to a
- user who has proxy access to their calendars, or to whom they are
- acting as a proxy. Again, CalDAV's access control discovery and
- report features can be used to do that, but with fine-grained control
- that exists, it can be hard to tell who is a "real" proxy as opposed
- to someone just granted rights to some subset of calendars. Again, a
- simple way to discover proxy information would be handy.
-
-
-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 namespace "DAV:" are referenced in this
- document outside of the context of an XML fragment, the string "DAV:"
- will be prefixed to the element type names.
-
- 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
-
-
-
-Daboo [Page 2]
-
- CalDAV Proxy May 2007
-
-
- this 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 respectively.
-
-
-3. Overview
-
-3.1. Server
-
- For each calendar user principal on the server, the server will
- generate two group principals - "proxy groups". One is used to hold
- the list of principals who have read-only proxy access to the main
- principal's calendars, the other holds the list of principals who
- have read-write and scheduling proxy access. NB these new group
- principals would have no equivalent in Open Directory.
-
- Privileges on each "proxy group" principal will be set so that the
- "owner" has the ability to change property values.
-
- The "proxy group" principals will be child resources of the user
- principal resource with specific resource types and thus are easy to
- discover. As a result the user principal resources will also be
- collection resources.
-
- When provisioning the calendar user home collection, the server will:
-
- a. Add an ACE to the calendar home collection giving the read-only
- "proxy group" inheritable read access.
-
- b. Add an ACE to the calendar home collection giving the read-write
- "proxy group" inheritable read-write access.
-
- c. Add an ACE to each of the calendar Inbox and Outbox collections
- giving the CALDAV:schedule privilege
- [I-D.desruisseaux-caldav-sched] to the read-write "proxy group".
-
-3.2. Client
-
- A client can see who the proxies are for the current principal by
- examining the principal resource for the two "proxy group" properties
- and then looking at the DAV:group-member-set property of each.
-
- The client can edit the list of proxies for the current principal by
- editing the DAV:group-member-set property on the relevant "proxy
- group" principal resource.
-
- The client can find out who the current principal is a proxy for by
- running a DAV:principal-match REPORT on the principal collection.
-
-
-
-Daboo [Page 3]
-
- CalDAV Proxy May 2007
-
-
- Alternatively, the client can find out who the current principal is a
- proxy for by examining the DAV:group-membership property on the
- current principal resource looking for membership in other users'
- "proxy groups".
-
-
-4. Open Issues
-
- 1. Do we want to separate read-write access to calendars vs the
- ability to schedule as a proxy?
-
- 2. We may want to restrict changing properties on the proxy group
- collections to just the DAV:group-member-set property?
-
- 3. There is no way for a proxy to be able to manage the list of
- proxies. We could allow the main calendar user DAV:write-acl on
- their "proxy group" principals, in which case they could grant
- others the right to modify the group membership.
-
- 4. Should the "proxy group" principals also be collections given
- that the regular principal resources will be?
-
-
-5. New features in CalDAV
-
-5.1. Proxy Principal Resource
-
- Each "regular" principal resource that needs to allow calendar user
- proxy support MUST be a collection resource. i.e. in addition to
- including the DAV:principal XML element in the DAV:resourcetype
- property on the resource, it MUST also include the DAV:collection XML
- element.
-
- Each "regular" principal resource MUST contain two child resources
- with names "calendar-proxy-read" and "calendar-proxy-write" (note
- that these are only suggested names - the server could choose any
- unique name for these). These resources are themselves principal
- resources that are groups contain the list of principals for calendar
- users who can act as a read-only or read-write proxy respectively.
-
- The server MUST include the CS:calendar-proxy-read or CS:calendar-
- proxy-write XML elements in the DAV:resourcetype property of the
- child resources, respectively. This allows clients to discover the
- "proxy group" principals by using a PROPFIND, Depth:1 request on the
- current user's principal resource and requesting the DAV:resourcetype
- property be returned. The element type declarations are:
-
-
-
-
-
-Daboo [Page 4]
-
- CalDAV Proxy May 2007
-
-
-
-
-
-
- The server MUST allow the "parent" principal to change the DAV:group-
- member-set property on each of the "child" "proxy group" principal
- resources. When a principal is listed as a member of the "child"
- resource, the server MUST include the "child" resource URI in the
- DAV:group-membership property on the included principal resource.
- Note that this is just "normal" behavior for a group principal.
-
- An example principal resource layout might be:
-
- + /
- + principals/
- + users/
- + cyrus/
- calendar-proxy-read
- calendar-proxy-write
- + red/
- calendar-proxy-read
- calendar-proxy-write
- + wilfredo/
- calendar-proxy-read
- calendar-proxy-write
-
- If the principal "cyrus" wishes to have the principal "red" act as a
- calendar user proxy on his behalf and have the ability to change
- items on his calendar or schedule meetings on his behalf, then he
- would add the principal resource URI for "red" to the DAV:group-
- member-set property of the principal resource /principals/users/
- cyrus/calendar-proxy-write, giving:
-
-
- /principals/users/red/
-
-
- The DAV:group-membership property on the resource /principals/users/
- red/ would be:
-
-
- /principals/users/cyrus/calendar-proxy-write
-
-
- If the principal "red" was also a read-only proxy for the principal
- "wilfredo", then the DA:group-membership property on the resource
- /principals/users/red/ would be:
-
-
-
-
-Daboo [Page 5]
-
- CalDAV Proxy May 2007
-
-
-
- /principals/users/cyrus/calendar-proxy-write
- /principals/users/wilfredo/calendar-proxy-read
-
-
- Thus a client can discover to which principals a particular principal
- is acting as a calendar user proxy for by examining the DAV:group-
- membership property.
-
- An alternative to discovering which principals a user can proxy as is
- to use the WebDAV ACL principal-match report, targeted at the
- principal collections available on the server.
-
- Example:
-
- >> Request <<
-
- REPORT /principals/ HTTP/1.1
- Host: cal.example.com
- Depth: 0
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="red",
- realm="cal.example.com", nonce="...",
- uri="/principals/", response="...", opaque="..."
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo [Page 6]
-
- CalDAV Proxy May 2007
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Fri, 10 Nov 2006 09:32:12 GMT
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /principals/users/red/
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
- /principals/users/cyrus/calendar-proxy-write
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
- /principals/users/wilfredo/calendar-proxy-read
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-Daboo [Page 7]
-
- CalDAV Proxy May 2007
-
-
-5.2. Privilege Provisioning
-
- In order for a calendar user proxy to be able to access the calendars
- of the user they are proxying for the server MUST ensure that the
- privileges on the relevant calendars are setup accordingly:
-
- The DAV:read privilege MUST be granted for read-only and read-
- write calendar user proxy principals
-
- The DAV:write privilege MUST be granted for read-write calendar
- user proxy principals.
-
- Additionally, the CalDAV scheduling Inbox and Outbox calendar
- collections for the user allowing proxy access, MUST have the CALDAV:
- schedule privilege [I-D.desruisseaux-caldav-sched] granted for read-
- write calendar user proxy principals.
-
- Note that with a suitable repository layout, a server may be able to
- grant the appropriate privileges on a parent collection and ensure
- that all the contained collections and resources inherit that. For
- example, given the following repository layout:
-
- + /
- + calendars/
- + users/
- + cyrus/
- inbox
- outbox
- home
- work
- + red/
- inbox
- outbox
- work
- soccer
- + wilfredo/
- inbox
- outbox
- home
- work
- flying
-
- In order for the principal "red" to act as a read-write proxy for the
- principal "cyrus", the following WebDAV ACE will need to be granted
- on the resource /calendars/users/cyrus/ and all children of that
- resource:
-
-
-
-
-
-Daboo [Page 8]
-
- CalDAV Proxy May 2007
-
-
-
-
- /principals/users/cyrus/calendar-proxy-write
-
-
-
-
-
-
-
-6. Security Considerations
-
- TBD
-
-
-7. IANA Considerations
-
- This document does not require any actions on the part of IANA.
-
-
-8. Normative References
-
- [I-D.desruisseaux-caldav-sched]
- Desruisseaux, B., "Scheduling Extensions to CalDAV",
- draft-desruisseaux-caldav-sched-03 (work in progress),
- January 2007.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, S., and D.
- Jensen, "HTTP Extensions for Distributed Authoring --
- WEBDAV", RFC 2518, February 1999.
-
- [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.
-
-
-Appendix A. Acknowledgments
-
- This specification is the result of discussions between the Apple
- calendar server and client teams.
-
-
-
-
-Daboo [Page 9]
-
- CalDAV Proxy May 2007
-
-
-Appendix B. Change History
-
- Changes from -00:
-
- 1. Updated to RFC 4791 reference.
-
- Changes from -00:
-
- 1. Added more details on actual CalDAV protocol changes.
-
- 2. Changed namespace from http://apple.com/ns/calendarserver/ to
- http://calendarserver.org/ns/.
-
- 3. Made "proxy group" principals child resources of their "owner"
- principals.
-
- 4. The "proxy group" principals now have their own resourcetype.
-
-
-Author's Address
-
- Cyrus Daboo
- Apple Computer, Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- Email: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo [Page 10]
-
diff --git a/doc/how_davdroid_works.svgz b/doc/how_davdroid_works.svgz
deleted file mode 100644
index 93b51e46..00000000
Binary files a/doc/how_davdroid_works.svgz and /dev/null differ
diff --git a/doc/rfc3744-webdav-access-control-protocol.txt b/doc/rfc3744-webdav-access-control-protocol.txt
deleted file mode 100644
index afcdb2a3..00000000
--- a/doc/rfc3744-webdav-access-control-protocol.txt
+++ /dev/null
@@ -1,4035 +0,0 @@
-
-
-
-
-
-
-Network Working Group G. Clemm
-Request for Comments: 3744 IBM
-Category: Standards Track J. Reschke
- greenbytes
- E. Sedlar
- Oracle Corporation
- J. Whitehead
- U.C. Santa Cruz
- May 2004
-
-
- Web Distributed Authoring and Versioning (WebDAV)
- Access Control Protocol
-
-Status of this Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2004). All Rights Reserved.
-
-Abstract
-
- This document specifies a set of methods, headers, message bodies,
- properties, and reports that define Access Control extensions to the
- WebDAV Distributed Authoring Protocol. This protocol permits a
- client to read and modify access control lists that instruct a server
- whether to allow or deny operations upon a resource (such as
- HyperText Transfer Protocol (HTTP) method invocations) by a given
- principal. A lightweight representation of principals as Web
- resources supports integration of a wide range of user management
- repositories. Search operations allow discovery and manipulation of
- principals using human names.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 1]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4
- 1.1. Terms. . . . . . . . . . . . . . . . . . . . . . . . . . 6
- 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 8
- 2. Principals . . . . . . . . . . . . . . . . . . . . . . . . . . 8
- 3. Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . 8
- 3.1. DAV:read Privilege . . . . . . . . . . . . . . . . . . . 10
- 3.2. DAV:write Privilege. . . . . . . . . . . . . . . . . . . 10
- 3.3. DAV:write-properties Privilege . . . . . . . . . . . . . 10
- 3.4. DAV:write-content Privilege. . . . . . . . . . . . . . . 11
- 3.5. DAV:unlock Privilege . . . . . . . . . . . . . . . . . . 11
- 3.6. DAV:read-acl Privilege . . . . . . . . . . . . . . . . . 11
- 3.7. DAV:read-current-user-privilege-set Privilege. . . . . . 12
- 3.8. DAV:write-acl Privilege. . . . . . . . . . . . . . . . . 12
- 3.9. DAV:bind Privilege . . . . . . . . . . . . . . . . . . . 12
- 3.10. DAV:unbind Privilege . . . . . . . . . . . . . . . . . . 12
- 3.11. DAV:all Privilege. . . . . . . . . . . . . . . . . . . . 13
- 3.12. Aggregation of Predefined Privileges . . . . . . . . . . 13
- 4. Principal Properties . . . . . . . . . . . . . . . . . . . . . 13
- 4.1. DAV:alternate-URI-set. . . . . . . . . . . . . . . . . . 14
- 4.2. DAV:principal-URL. . . . . . . . . . . . . . . . . . . . 14
- 4.3. DAV:group-member-set . . . . . . . . . . . . . . . . . . 14
- 4.4. DAV:group-membership . . . . . . . . . . . . . . . . . . 14
- 5. Access Control Properties. . . . . . . . . . . . . . . . . . . 15
- 5.1. DAV:owner. . . . . . . . . . . . . . . . . . . . . . . . 15
- 5.1.1. Example: Retrieving DAV:owner . . . . . . . . . . 15
- 5.1.2. Example: An Attempt to Set DAV:owner. . . . . . . 16
- 5.2. DAV:group. . . . . . . . . . . . . . . . . . . . . . . . 18
- 5.3. DAV:supported-privilege-set. . . . . . . . . . . . . . . 18
- 5.3.1. Example: Retrieving a List of Privileges
- Supported on a Resource . . . . . . . . . . . . . 19
- 5.4. DAV:current-user-privilege-set . . . . . . . . . . . . . 21
- 5.4.1. Example: Retrieving the User's Current Set of
- Assigned Privileges . . . . . . . . . . . . . . . 22
- 5.5. DAV:acl. . . . . . . . . . . . . . . . . . . . . . . . . 23
- 5.5.1. ACE Principal . . . . . . . . . . . . . . . . . . 23
- 5.5.2. ACE Grant and Deny. . . . . . . . . . . . . . . . 25
- 5.5.3. ACE Protection. . . . . . . . . . . . . . . . . . 25
- 5.5.4. ACE Inheritance . . . . . . . . . . . . . . . . . 25
- 5.5.5. Example: Retrieving a Resource's Access Control
- List. . . . . . . . . . . . . . . . . . . . . . . 25
- 5.6. DAV:acl-restrictions . . . . . . . . . . . . . . . . . . 27
- 5.6.1. DAV:grant-only. . . . . . . . . . . . . . . . . . 27
- 5.6.2. DAV:no-invert ACE Constraint. . . . . . . . . . . 28
- 5.6.3. DAV:deny-before-grant . . . . . . . . . . . . . . 28
- 5.6.4. Required Principals . . . . . . . . . . . . . . . 28
- 5.6.5. Example: Retrieving DAV:acl-restrictions. . . . . 28
-
-
-
-Clemm, et al. Standards Track [Page 2]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- 5.7. DAV:inherited-acl-set. . . . . . . . . . . . . . . . . . 29
- 5.8. DAV:principal-collection-set . . . . . . . . . . . . . . 30
- 5.8.1. Example: Retrieving DAV:principal-collection-set. 30
- 5.9. Example: PROPFIND to retrieve access control properties. 32
- 6. ACL Evaluation . . . . . . . . . . . . . . . . . . . . . . . . 36
- 7. Access Control and existing methods. . . . . . . . . . . . . . 37
- 7.1. Any HTTP method. . . . . . . . . . . . . . . . . . . . . 37
- 7.1.1. Error Handling. . . . . . . . . . . . . . . . . . 37
- 7.2. OPTIONS. . . . . . . . . . . . . . . . . . . . . . . . . 38
- 7.2.1. Example - OPTIONS . . . . . . . . . . . . . . . . 39
- 7.3. MOVE . . . . . . . . . . . . . . . . . . . . . . . . . . 39
- 7.4. COPY . . . . . . . . . . . . . . . . . . . . . . . . . . 39
- 7.5. LOCK . . . . . . . . . . . . . . . . . . . . . . . . . . 39
- 8. Access Control Methods . . . . . . . . . . . . . . . . . . . . 40
- 8.1. ACL. . . . . . . . . . . . . . . . . . . . . . . . . . . 40
- 8.1.1. ACL Preconditions . . . . . . . . . . . . . . . . 40
- 8.1.2. Example: the ACL method . . . . . . . . . . . . . 42
- 8.1.3. Example: ACL method failure due to protected
- ACE conflict. . . . . . . . . . . . . . . . . . . 43
- 8.1.4. Example: ACL method failure due to an
- inherited ACE conflict. . . . . . . . . . . . . . 44
- 8.1.5. Example: ACL method failure due to an attempt
- to set grant and deny in a single ACE . . . . . . 45
- 9. Access Control Reports . . . . . . . . . . . . . . . . . . . . 46
- 9.1. REPORT Method. . . . . . . . . . . . . . . . . . . . . . 46
- 9.2. DAV:acl-principal-prop-set Report. . . . . . . . . . . . 47
- 9.2.1. Example: DAV:acl-principal-prop-set Report. . . . 48
- 9.3. DAV:principal-match REPORT . . . . . . . . . . . . . . . 49
- 9.3.1. Example: DAV:principal-match REPORT . . . . . . . 50
- 9.4. DAV:principal-property-search REPORT . . . . . . . . . . 51
- 9.4.1. Matching. . . . . . . . . . . . . . . . . . . . . 53
- 9.4.2. Example: successful DAV:principal-property-search
- REPORT. . . . . . . . . . . . . . . . . . . . . . 54
- 9.5. DAV:principal-search-property-set REPORT . . . . . . . . 56
- 9.5.1. Example: DAV:principal-search-property-set
- REPORT. . . . . . . . . . . . . . . . . . . . . . 58
- 10. XML Processing . . . . . . . . . . . . . . . . . . . . . . . . 59
- 11. Internationalization Considerations. . . . . . . . . . . . . . 59
- 12. Security Considerations. . . . . . . . . . . . . . . . . . . . 60
- 12.1. Increased Risk of Compromised Users. . . . . . . . . . . 60
- 12.2. Risks of the DAV:read-acl and
- DAV:current-user-privilege-set Privileges. . . . . . . . 60
- 12.3. No Foreknowledge of Initial ACL. . . . . . . . . . . . . 61
- 13. Authentication . . . . . . . . . . . . . . . . . . . . . . . . 61
- 14. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 62
- 15. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 62
-
-
-
-
-
-Clemm, et al. Standards Track [Page 3]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- 16. References . . . . . . . . . . . . . . . . . . . . . . . . . . 62
- 16.1. Normative References . . . . . . . . . . . . . . . . . . 62
- 16.2. Informative References . . . . . . . . . . . . . . . . . 63
- Appendices
- A. WebDAV XML Document Type Definition Addendum . . . . . . . . . 64
- B. WebDAV Method Privilege Table (Normative). . . . . . . . . . . 67
- Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 71
- Full Copyright Statement. . . . . . . . . . . . . . . . . . . . . 72
-
-1. Introduction
-
- The goal of the WebDAV access control extensions is to provide an
- interoperable mechanism for handling discretionary access control for
- content and metadata managed by WebDAV servers. WebDAV access
- control can be implemented on content repositories with security as
- simple as that of a UNIX file system, as well as more sophisticated
- models. The underlying principle of access control is that who you
- are determines what operations you can perform on a resource. The
- "who you are" is defined by a "principal" identifier; users, client
- software, servers, and groups of the previous have principal
- identifiers. The "operations you can perform" are determined by a
- single "access control list" (ACL) associated with a resource. An
- ACL contains a set of "access control entries" (ACEs), where each ACE
- specifies a principal and a set of privileges that are either granted
- or denied to that principal. When a principal submits an operation
- (such as an HTTP or WebDAV method) to a resource for execution, the
- server evaluates the ACEs in the ACL to determine if the principal
- has permission for that operation.
-
- Since every ACE contains the identifier of a principal, client
- software operated by a human must provide a mechanism for selecting
- this principal. This specification uses http(s) scheme URLs to
- identify principals, which are represented as WebDAV-capable
- resources. There is no guarantee that the URLs identifying
- principals will be meaningful to a human. For example,
- http://www.example.com/u/256432 and
- http://www.example.com/people/Greg.Stein are both valid URLs that
- could be used to identify the same principal. To remedy this, every
- principal resource has the DAV:displayname property containing a
- human-readable name for the principal.
-
- Since a principal can be identified by multiple URLs, it raises the
- problem of determining exactly which principal is being referenced in
- a given ACE. It is impossible for a client to determine that an ACE
- granting the read privilege to http://www.example.com/people/
- Greg.Stein also affects the principal at http://www.example.com/u/
- 256432. That is, a client has no mechanism for determining that two
-
-
-
-Clemm, et al. Standards Track [Page 4]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- URLs identify the same principal resource. As a result, this
- specification requires clients to use just one of the many possible
- URLs for a principal when creating ACEs. A client can discover which
- URL to use by retrieving the DAV:principal-URL property (Section 4.2)
- from a principal resource. No matter which of the principal's URLs
- is used with PROPFIND, the property always returns the same URL.
-
- With a system having hundreds to thousands of principals, the problem
- arises of how to allow a human operator of client software to select
- just one of these principals. One approach is to use broad
- collection hierarchies to spread the principals over a large number
- of collections, yielding few principals per collection. An example
- of this is a two level hierarchy with the first level containing 36
- collections (a-z, 0-9), and the second level being another 36,
- creating collections /a/a/, /a/b/, ..., /a/z/, such that a principal
- with last name "Stein" would appear at /s/t/Stein. In effect, this
- pre-computes a common query, search on last name, and encodes it into
- a hierarchy. The drawback with this scheme is that it handles only a
- small set of predefined queries, and drilling down through the
- collection hierarchy adds unnecessary steps (navigate down/up) when
- the user already knows the principal's name. While organizing
- principal URLs into a hierarchy is a valid namespace organization,
- users should not be forced to navigate this hierarchy to select a
- principal.
-
- This specification provides the capability to perform substring
- searches over a small set of properties on the resources representing
- principals. This permits searches based on last name, first name,
- user name, job title, etc. Two separate searches are supported, both
- via the REPORT method, one to search principal resources
- (DAV:principal-property-search, Section 9.4), the other to determine
- which properties may be searched at all (DAV:principal-search-
- property-set, Section 9.5).
-
- Once a principal has been identified in an ACE, a server evaluating
- that ACE must know the identity of the principal making a protocol
- request, and must validate that that principal is who they claim to
- be, a process known as authentication. This specification
- intentionally omits discussion of authentication, as the HTTP
- protocol already has a number of authentication mechanisms [RFC2617].
- Some authentication mechanism (such as HTTP Digest Authentication,
- which all WebDAV compliant implementations are required to support)
- must be available to validate the identity of a principal.
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 5]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The following issues are out of scope for this document:
-
- o Access control that applies only to a particular property on a
- resource (excepting the access control properties DAV:acl and
- DAV:current-user-privilege-set), rather than the entire resource,
-
- o Role-based security (where a role can be seen as a dynamically
- defined group of principals),
-
- o Specification of the ways an ACL on a resource is initialized,
-
- o Specification of an ACL that applies globally to all resources,
- rather than to a particular resource.
-
- o Creation and maintenance of resources representing people or
- computational agents (principals), and groups of these.
-
- This specification is organized as follows. Section 1.1 defines key
- concepts used throughout the specification, and is followed by a more
- in-depth discussion of principals (Section 2), and privileges
- (Section 3). Properties defined on principals are specified in
- Section 4, and access control properties for content resources are
- specified in Section 5. The ways ACLs are to be evaluated is
- described in Section 6. Client discovery of access control
- capability using OPTIONS is described in Section 7.2. Interactions
- between access control functionality and existing HTTP and WebDAV
- methods are described in the remainder of Section 7. The access
- control setting method, ACL, is specified in Section 8. Four reports
- that provide limited server-side searching capabilities are described
- in Section 9. Sections on XML processing (Section 10),
- Internationalization considerations (Section 11), security
- considerations (Section 12), and authentication (Section 13) round
- out the specification. An appendix (Appendix A) provides an XML
- Document Type Definition (DTD) for the XML elements defined in the
- specification.
-
-1.1. Terms
-
- This document uses the terms defined in HTTP [RFC2616] and WebDAV
- [RFC2518]. In addition, the following terms are defined:
-
- principal
-
- A "principal" is a distinct human or computational actor that
- initiates access to network resources. In this protocol, a
- principal is an HTTP resource that represents such an actor.
-
-
-
-
-
-Clemm, et al. Standards Track [Page 6]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- group
-
- A "group" is a principal that represents a set of other
- principals.
-
- privilege
-
- A "privilege" controls access to a particular set of HTTP
- operations on a resource.
-
- aggregate privilege
-
- An "aggregate privilege" is a privilege that contains a set of
- other privileges.
-
- abstract privilege
-
- The modifier "abstract", when applied to a privilege on a
- resource, means the privilege cannot be set in an access control
- element (ACE) on that resource.
-
- access control list (ACL)
-
- An "ACL" is a list of access control elements that define access
- control to a particular resource.
-
- access control element (ACE)
-
- An "ACE" either grants or denies a particular set of (non-
- abstract) privileges for a particular principal.
-
- inherited ACE
-
- An "inherited ACE" is an ACE that is dynamically shared from the
- ACL of another resource. When a shared ACE changes on the primary
- resource, it is also changed on inheriting resources.
-
- protected property
-
- A "protected property" is one whose value cannot be updated except
- by a method explicitly defined as updating that specific property.
- In particular, a protected property cannot be updated with a
- PROPPATCH request.
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 7]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-1.2. Notational Conventions
-
- The augmented BNF used by this document to describe protocol elements
- is described in Section 2.1 of [RFC2616]. Because this augmented BNF
- uses the basic production rules provided in Section 2.2 of [RFC2616],
- those rules apply to this document as well.
-
- 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].
-
- Definitions of XML elements in this document use XML element type
- declarations (as found in XML Document Type Declarations), described
- in Section 3.2 of [REC-XML]. When an XML element type in the "DAV:"
- namespace is referenced in this document outside of the context of an
- XML fragment, the string "DAV:" will be prefixed to the element name.
-
-2. Principals
-
- A principal is a network resource that represents a distinct human or
- computational actor that initiates access to network resources.
- Users and groups are represented as principals in many
- implementations; other types of principals are also possible. A URI
- of any scheme MAY be used to identify a principal resource. However,
- servers implementing this specification MUST expose principal
- resources at an http(s) URL, which is a privileged scheme that points
- to resources that have additional properties, as described in Section
- 4. So, a principal resource can have multiple URIs, one of which has
- to be an http(s) scheme URL. Although an implementation SHOULD
- support PROPFIND and MAY support PROPPATCH to access and modify
- information about a principal, it is not required to do so.
-
- A principal resource may be a group, where a group is a principal
- that represents a set of other principals, called the members of the
- group. If a person or computational agent matches a principal
- resource that is a member of a group, they also match the group.
- Membership in a group is recursive, so if a principal is a member of
- group GRPA, and GRPA is a member of group GRPB, then the principal is
- also a member of GRPB.
-
-3. Privileges
-
- Ability to perform a given method on a resource MUST be controlled by
- one or more privileges. Authors of protocol extensions that define
- new HTTP methods SHOULD specify which privileges (by defining new
- privileges, or mapping to ones below) are required to perform the
- method. A principal with no privileges to a resource MUST be denied
- any HTTP access to that resource, unless the principal matches an ACE
-
-
-
-Clemm, et al. Standards Track [Page 8]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- constructed using the DAV:all, DAV:authenticated, or
- DAV:unauthenticated pseudo-principals (see Section 5.5.1). Servers
- MUST report a 403 "Forbidden" error if access is denied, except in
- the case where the privilege restricts the ability to know the
- resource exists, in which case 404 "Not Found" may be returned.
-
- Privileges may be containers of other privileges, in which case they
- are termed "aggregate privileges". If a principal is granted or
- denied an aggregate privilege, it is semantically equivalent to
- granting or denying each of the aggregated privileges individually.
- For example, an implementation may define add-member and remove-
- member privileges that control the ability to add and remove a member
- of a group. Since these privileges control the ability to update the
- state of a group, these privileges would be aggregated by the
- DAV:write privilege on a group, and granting the DAV:write privilege
- on a group would also grant the add-member and remove-member
- privileges.
-
- Privileges may be declared to be "abstract" for a given resource, in
- which case they cannot be set in an ACE on that resource. Aggregate
- and non-aggregate privileges are both capable of being abstract.
- Abstract privileges are useful for modeling privileges that otherwise
- would not be exposed via the protocol. Abstract privileges also
- provide server implementations with flexibility in implementing the
- privileges defined in this specification. For example, if a server
- is incapable of separating the read resource capability from the read
- ACL capability, it can still model the DAV:read and DAV:read-acl
- privileges defined in this specification by declaring them abstract,
- and containing them within a non-abstract aggregate privilege (say,
- read-all) that holds DAV:read, and DAV:read-acl. In this way, it is
- possible to set the aggregate privilege, read-all, thus coupling the
- setting of DAV:read and DAV:read-acl, but it is not possible to set
- DAV:read, or DAV:read-acl individually. Since aggregate privileges
- can be abstract, it is also possible to use abstract privileges to
- group or organize non-abstract privileges. Privilege containment
- loops are not allowed; therefore, a privilege MUST NOT contain
- itself. For example, DAV:read cannot contain DAV:read.
-
- The set of privileges that apply to a particular resource may vary
- with the DAV:resourcetype of the resource, as well as between
- different server implementations. To promote interoperability,
- however, this specification defines a set of well-known privileges
- (e.g., DAV:read, DAV:write, DAV:read-acl, DAV:write-acl, DAV:read-
- current-user-privilege-set, and DAV:all), which can at least be used
- to classify the other privileges defined on a particular resource.
- The access permissions on null resources (defined in [RFC2518],
- Section 3) are solely those they inherit (if any), and they are not
- discoverable (i.e., the access control properties specified in
-
-
-
-Clemm, et al. Standards Track [Page 9]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Section 5 are not defined on null resources). On the transition from
- null to stateful resource, the initial access control list is set by
- the server's default ACL value policy (if any).
-
- Server implementations MAY define new privileges beyond those defined
- in this specification. Privileges defined by individual
- implementations MUST NOT use the DAV: namespace, and instead should
- use a namespace that they control, such as an http scheme URL.
-
-3.1. DAV:read Privilege
-
- The read privilege controls methods that return information about the
- state of the resource, including the resource's properties. Affected
- methods include GET and PROPFIND. Any implementation-defined
- privilege that also controls access to GET and PROPFIND must be
- aggregated under DAV:read - if an ACL grants access to DAV:read, the
- client may expect that no other privilege needs to be granted to have
- access to GET and PROPFIND. Additionally, the read privilege MUST
- control the OPTIONS method.
-
-
-
-3.2. DAV:write Privilege
-
- The write privilege controls methods that lock a resource or modify
- the content, dead properties, or (in the case of a collection)
- membership of the resource, such as PUT and PROPPATCH. Note that
- state modification is also controlled via locking (see section 5.3 of
- [RFC2518]), so effective write access requires that both write
- privileges and write locking requirements are satisfied. Any
- implementation-defined privilege that also controls access to methods
- modifying content, dead properties or collection membership must be
- aggregated under DAV:write, e.g., if an ACL grants access to
- DAV:write, the client may expect that no other privilege needs to be
- granted to have access to PUT and PROPPATCH.
-
-
-
-3.3. DAV:write-properties Privilege
-
- The DAV:write-properties privilege controls methods that modify the
- dead properties of the resource, such as PROPPATCH. Whether this
- privilege may be used to control access to any live properties is
- determined by the implementation. Any implementation-defined
- privilege that also controls access to methods modifying dead
- properties must be aggregated under DAV:write-properties - e.g., if
-
-
-
-
-
-Clemm, et al. Standards Track [Page 10]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- an ACL grants access to DAV:write-properties, the client can safely
- expect that no other privilege needs to be granted to have access to
- PROPPATCH.
-
-
-
-3.4. DAV:write-content Privilege
-
- The DAV:write-content privilege controls methods that modify the
- content of an existing resource, such as PUT. Any implementation-
- defined privilege that also controls access to content must be
- aggregated under DAV:write-content - e.g., if an ACL grants access to
- DAV:write-content, the client can safely expect that no other
- privilege needs to be granted to have access to PUT. Note that PUT -
- when applied to an unmapped URI - creates a new resource and
- therefore is controlled by the DAV:bind privilege on the parent
- collection.
-
-
-
-3.5. DAV:unlock Privilege
-
- The DAV:unlock privilege controls the use of the UNLOCK method by a
- principal other than the lock owner (the principal that created a
- lock can always perform an UNLOCK). While the set of users who may
- lock a resource is most commonly the same set of users who may modify
- a resource, servers may allow various kinds of administrators to
- unlock resources locked by others. Any privilege controlling access
- by non-lock owners to UNLOCK MUST be aggregated under DAV:unlock.
-
- A lock owner can always remove a lock by issuing an UNLOCK with the
- correct lock token and authentication credentials. That is, even if
- a principal does not have DAV:unlock privilege, they can still remove
- locks they own. Principals other than the lock owner can remove a
- lock only if they have DAV:unlock privilege and they issue an UNLOCK
- with the correct lock token. Lock timeout is not affected by the
- DAV:unlock privilege.
-
-
-
-3.6. DAV:read-acl Privilege
-
- The DAV:read-acl privilege controls the use of PROPFIND to retrieve
- the DAV:acl property of the resource.
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 11]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-3.7. DAV:read-current-user-privilege-set Privilege
-
- The DAV:read-current-user-privilege-set privilege controls the use of
- PROPFIND to retrieve the DAV:current-user-privilege-set property of
- the resource.
-
- Clients are intended to use this property to visually indicate in
- their UI items that are dependent on the permissions of a resource,
- for example, by graying out resources that are not writable.
-
- This privilege is separate from DAV:read-acl because there is a need
- to allow most users access to the privileges permitted the current
- user (due to its use in creating the UI), while the full ACL contains
- information that may not be appropriate for the current authenticated
- user. As a result, the set of users who can view the full ACL is
- expected to be much smaller than those who can read the current user
- privilege set, and hence distinct privileges are needed for each.
-
-
-
-3.8. DAV:write-acl Privilege
-
- The DAV:write-acl privilege controls use of the ACL method to modify
- the DAV:acl property of the resource.
-
-
-
-3.9. DAV:bind Privilege
-
- The DAV:bind privilege allows a method to add a new member URL to the
- specified collection (for example via PUT or MKCOL). It is ignored
- for resources that are not collections.
-
-
-
-3.10. DAV:unbind Privilege
-
- The DAV:unbind privilege allows a method to remove a member URL from
- the specified collection (for example via DELETE or MOVE). It is
- ignored for resources that are not collections.
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 12]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-3.11. DAV:all Privilege
-
- DAV:all is an aggregate privilege that contains the entire set of
- privileges that can be applied to the resource.
-
-
-
-3.12. Aggregation of Predefined Privileges
-
- Server implementations are free to aggregate the predefined
- privileges (defined above in Sections 3.1-3.10) subject to the
- following limitations:
-
- DAV:read-acl MUST NOT contain DAV:read, DAV:write, DAV:write-acl,
- DAV:write-properties, DAV:write-content, or DAV:read-current-user-
- privilege-set.
-
- DAV:write-acl MUST NOT contain DAV:write, DAV:read, DAV:read-acl, or
- DAV:read-current-user-privilege-set.
-
- DAV:read-current-user-privilege-set MUST NOT contain DAV:write,
- DAV:read, DAV:read-acl, or DAV:write-acl.
-
- DAV:write MUST NOT contain DAV:read, DAV:read-acl, or DAV:read-
- current-user-privilege-set.
-
- DAV:read MUST NOT contain DAV:write, DAV:write-acl, DAV:write-
- properties, or DAV:write-content.
-
- DAV:write MUST contain DAV:bind, DAV:unbind, DAV:write-properties and
- DAV:write-content.
-
-4. Principal Properties
-
- Principals are manifested to clients as a WebDAV resource, identified
- by a URL. A principal MUST have a non-empty DAV:displayname property
- (defined in Section 13.2 of [RFC2518]), and a DAV:resourcetype
- property (defined in Section 13.9 of [RFC2518]). Additionally, a
- principal MUST report the DAV:principal XML element in the value of
- the DAV:resourcetype property. The element type declaration for
- DAV:principal is:
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 13]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- This protocol defines the following additional properties for a
- principal. Since it can be expensive for a server to retrieve access
- control information, the name and value of these properties SHOULD
- NOT be returned by a PROPFIND allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
-4.1. DAV:alternate-URI-set
-
- This protected property, if non-empty, contains the URIs of network
- resources with additional descriptive information about the
- principal. This property identifies additional network resources
- (i.e., it contains one or more URIs) that may be consulted by a
- client to gain additional knowledge concerning a principal. One
- expected use for this property is the storage of an LDAP [RFC2255]
- scheme URL. A user-agent encountering an LDAP URL could use LDAP
- [RFC2251] to retrieve additional machine-readable directory
- information about the principal, and display that information in its
- user interface. Support for this property is REQUIRED, and the value
- is empty if no alternate URI exists for the principal.
-
-
-
-4.2. DAV:principal-URL
-
- A principal may have many URLs, but there must be one "principal URL"
- that clients can use to uniquely identify a principal. This
- protected property contains the URL that MUST be used to identify
- this principal in an ACL request. Support for this property is
- REQUIRED.
-
-
-
-4.3. DAV:group-member-set
-
- This property of a group principal identifies the principals that are
- direct members of this group. Since a group may be a member of
- another group, a group may also have indirect members (i.e., the
- members of its direct members). A URL in the DAV:group-member-set
- for a principal MUST be the DAV:principal-URL of that principal.
-
-
-
-4.4. DAV:group-membership
-
- This protected property identifies the groups in which the principal
- is directly a member. Note that a server may allow a group to be a
- member of another group, in which case the DAV:group-membership of
-
-
-
-
-Clemm, et al. Standards Track [Page 14]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- those other groups would need to be queried in order to determine the
- groups in which the principal is indirectly a member. Support for
- this property is REQUIRED.
-
-
-
-5. Access Control Properties
-
- This specification defines a number of new properties for WebDAV
- resources. Access control properties may be retrieved just like
- other WebDAV properties, using the PROPFIND method. Since it is
- expensive, for many servers, to retrieve access control information,
- a PROPFIND allprop request (as defined in Section 12.14.1 of
- [RFC2518]) SHOULD NOT return the names and values of the properties
- defined in this section.
-
- Access control properties (especially DAV:acl and DAV:inherited-acl-
- set) are defined on the resource identified by the Request-URI of a
- PROPFIND request. A direct consequence is that if the resource is
- accessible via multiple URI, the value of access control properties
- is the same across these URI.
-
- HTTP resources that support the WebDAV Access Control Protocol MUST
- contain the following properties. Null resources (described in
- Section 3 of [RFC2518]) MUST NOT contain the following properties.
-
-5.1. DAV:owner
-
- This property identifies a particular principal as being the "owner"
- of the resource. Since the owner of a resource often has special
- access control capabilities (e.g., the owner frequently has permanent
- DAV:write-acl privilege), clients might display the resource owner in
- their user interface.
-
- Servers MAY implement DAV:owner as protected property and MAY return
- an empty DAV:owner element as property value in case no owner
- information is available.
-
-
-
-5.1.1. Example: Retrieving DAV:owner
-
- This example shows a client request for the value of the DAV:owner
- property from a collection resource with URL http://www.example.com/
- papers/. The principal making the request is authenticated using
- Digest authentication. The value of DAV:owner is the URL http://
- www.example.com/acl/users/gstein, wrapped in the DAV:href XML
- element.
-
-
-
-Clemm, et al. Standards Track [Page 15]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="jim",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
-
- http://www.example.com/acl/users/gstein
-
-
- HTTP/1.1 200 OK
-
-
-
-
-5.1.2. Example: An Attempt to Set DAV:owner
-
- The following example shows a client request to modify the value of
- the DAV:owner property on the resource with URL . Since DAV:owner is a protected property on
- this particular server, it responds with a 207 (Multi-Status)
- response that contains a 403 (Forbidden) status code for the act of
- setting DAV:owner. Section 8.2.1 of [RFC2518] describes PROPPATCH
- status code information, Section 11 of [RFC2518] describes the
-
-
-
-Clemm, et al. Standards Track [Page 16]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Multi-Status response and Sections 1.6 and 3.12 of [RFC3253] describe
- additional error marshaling for PROPPATCH attempts on protected
- properties.
-
- >> Request <<
-
- PROPPATCH /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="jim",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
- http://www.example.com/acl/users/jim
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
- HTTP/1.1 403 Forbidden
-
-
- Failure to set protected property (DAV:owner)
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 17]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.2. DAV:group
-
- This property identifies a particular principal as being the "group"
- of the resource. This property is commonly found on repositories
- that implement the Unix privileges model.
-
- Servers MAY implement DAV:group as protected property and MAY return
- an empty DAV:group element as property value in case no group
- information is available.
-
-
-
-5.3. DAV:supported-privilege-set
-
- This is a protected property that identifies the privileges defined
- for the resource.
-
-
-
- Each privilege appears as an XML element, where aggregate privileges
- list as sub-elements all of the privileges that they aggregate.
-
-
-
-
- An abstract privilege MUST NOT be used in an ACE for that resource.
- Servers MUST fail an attempt to set an abstract privilege.
-
-
-
- A description is a human-readable description of what this privilege
- controls access to. Servers MUST indicate the human language of the
- description using the xml:lang attribute and SHOULD consider the HTTP
- Accept-Language request header when selecting one of multiple
- available languages.
-
-
-
- It is envisioned that a WebDAV ACL-aware administrative client would
- list the supported privileges in a dialog box, and allow the user to
- choose non-abstract privileges to apply in an ACE. The privileges
- tree is useful programmatically to map well-known privileges (defined
- by WebDAV or other standards groups) into privileges that are
- supported by any particular server implementation. The privilege
- tree also serves to hide complexity in implementations allowing large
- number of privileges to be defined by displaying aggregates to the
- user.
-
-
-
-Clemm, et al. Standards Track [Page 18]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.3.1. Example: Retrieving a List of Privileges Supported on a Resource
-
- This example shows a client request for the DAV:supported-privilege-
- set property on the resource http://www.example.com/papers/. The
- value of the DAV:supported-privilege-set property is a tree of
- supported privileges (using "[XML Namespace , localname]" to identify
- each privilege):
-
- [DAV:, all] (aggregate, abstract)
- |
- +-- [DAV:, read] (aggregate)
- |
- +-- [DAV:, read-acl] (abstract)
- +-- [DAV:, read-current-user-privilege-set] (abstract)
- |
- +-- [DAV:, write] (aggregate)
- |
- +-- [DAV:, write-acl] (abstract)
- +-- [DAV:, write-properties]
- +-- [DAV:, write-content]
- |
- +-- [DAV:, unlock]
-
- This privilege tree is not normative (except that it reflects the
- normative aggregation rules given in Section 3.12), and many possible
- privilege trees are possible.
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="gclemm",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 19]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
-
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
-
-
-
-
-
- Any operation
-
-
-
-
- Read any object
-
-
-
-
- Read ACL
-
-
-
-
-
-
-
- Read current user privilege set property
-
-
-
-
-
-
- Write any object
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 20]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Write ACL
-
-
-
-
-
-
- Write properties
-
-
-
-
-
- Write resource content
-
-
-
-
-
-
- Unlock resource
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-5.4. DAV:current-user-privilege-set
-
- DAV:current-user-privilege-set is a protected property containing the
- exact set of privileges (as computed by the server) granted to the
- currently authenticated HTTP user. Aggregate privileges and their
- contained privileges are listed. A user-agent can use the value of
- this property to adjust its user interface to make actions
- inaccessible (e.g., by graying out a menu item or button) for which
- the current principal does not have permission. This property is
- also useful for determining what operations the current principal can
- perform, without having to actually execute an operation.
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 21]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- If the current user is granted a specific privilege, that privilege
- must belong to the set of privileges that may be set on this
- resource. Therefore, each element in the DAV:current-user-
- privilege-set property MUST identify a non-abstract privilege from
- the DAV:supported-privilege-set property.
-
-5.4.1. Example: Retrieving the User's Current Set of Assigned
- Privileges
-
- Continuing the example from Section 5.3.1, this example shows a
- client requesting the DAV:current-user-privilege-set property from
- the resource with URL http://www.example.com/papers/. The username
- of the principal making the request is "khare", and Digest
- authentication is used in the request. The principal with username
- "khare" has been granted the DAV:read privilege. Since the DAV:read
- privilege contains the DAV:read-acl and DAV:read-current-user-
- privilege-set privileges (see Section 5.3.1), the principal with
- username "khare" can read the ACL property, and the DAV:current-
- user-privilege-set property. However, the DAV:all, DAV:read-acl,
- DAV:write-acl and DAV:read-current-user-privilege-set privileges are
- not listed in the value of DAV:current-user-privilege-set, since (for
- this example) they are abstract privileges. DAV:write is not listed
- since the principal with username "khare" is not listed in an ACE
- granting that principal write permission.
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="khare",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 22]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-5.5. DAV:acl
-
- This is a protected property that specifies the list of access
- control entries (ACEs), which define what principals are to get what
- privileges for this resource.
-
-
-
- Each DAV:ace element specifies the set of privileges to be either
- granted or denied to a single principal. If the DAV:acl property is
- empty, no principal is granted any privilege.
-
-
-
-5.5.1. ACE Principal
-
- The DAV:principal element identifies the principal to which this ACE
- applies.
-
-
-
- The current user matches DAV:href only if that user is authenticated
- as being (or being a member of) the principal identified by the URL
- contained by that DAV:href.
-
-
-
-
-Clemm, et al. Standards Track [Page 23]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The current user always matches DAV:all.
-
-
-
- The current user matches DAV:authenticated only if authenticated.
-
-
-
- The current user matches DAV:unauthenticated only if not
- authenticated.
-
-
-
- DAV:all is the union of DAV:authenticated, and DAV:unauthenticated.
- For a given request, the user matches either DAV:authenticated, or
- DAV:unauthenticated, but not both (that is, DAV:authenticated and
- DAV:unauthenticated are disjoint sets).
-
- The current user matches a DAV:property principal in a DAV:acl
- property of a resource only if the value of the identified property
- of that resource contains at most one DAV:href XML element, the URI
- value of DAV:href identifies a principal, and the current user is
- authenticated as being (or being a member of) that principal. For
- example, if the DAV:property element contained , the
- current user would match the DAV:property principal only if the
- current user is authenticated as matching the principal identified by
- the DAV:owner property of the resource.
-
-
-
- The current user matches DAV:self in a DAV:acl property of the
- resource only if that resource is a principal and that principal
- matches the current user or, if the principal is a group, a member of
- that group matches the current user.
-
-
-
- Some servers may support ACEs applying to those users NOT matching
- the current principal, e.g., all users not in a particular group.
- This can be done by wrapping the DAV:principal element with
- DAV:invert.
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 24]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.5.2. ACE Grant and Deny
-
- Each DAV:grant or DAV:deny element specifies the set of privileges to
- be either granted or denied to the specified principal. A DAV:grant
- or DAV:deny element of the DAV:acl of a resource MUST only contain
- non-abstract elements specified in the DAV:supported-privilege-set of
- that resource.
-
-
-
-
-
-5.5.3. ACE Protection
-
- A server indicates an ACE is protected by including the DAV:protected
- element in the ACE. If the ACL of a resource contains an ACE with a
- DAV:protected element, an attempt to remove that ACE from the ACL
- MUST fail.
-
-
-
-5.5.4. ACE Inheritance
-
- The presence of a DAV:inherited element indicates that this ACE is
- inherited from another resource that is identified by the URL
- contained in a DAV:href element. An inherited ACE cannot be modified
- directly, but instead the ACL on the resource from which it is
- inherited must be modified.
-
- Note that ACE inheritance is not the same as ACL initialization. ACL
- initialization defines the ACL that a newly created resource will use
- (if not specified). ACE inheritance refers to an ACE that is
- logically shared - where an update to the resource containing an ACE
- will affect the ACE of each resource that inherits that ACE. The
- method by which ACLs are initialized or by which ACEs are inherited
- is not defined by this document.
-
-
-
-5.5.5. Example: Retrieving a Resource's Access Control List
-
- Continuing the example from Sections 5.3.1 and 5.4.1, this example
- shows a client requesting the DAV:acl property from the resource with
- URL http://www.example.com/papers/. There are two ACEs defined in
- this ACL:
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 25]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- ACE #1: The group identified by URL http://www.example.com/acl/
- groups/maintainers (the group of site maintainers) is granted
- DAV:write privilege. Since (for this example) DAV:write contains the
- DAV:write-acl privilege (see Section 5.3.1), this means the
- "maintainers" group can also modify the access control list.
-
- ACE #2: All principals (DAV:all) are granted the DAV:read privilege.
- Since (for this example) DAV:read contains DAV:read-acl and
- DAV:read-current-user-privilege-set, this means all users (including
- all members of the "maintainers" group) can read the DAV:acl property
- and the DAV:current-user-privilege-set property.
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="masinter",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
- http://www.example.com/papers/
-
-
-
-
-
- http://www.example.com/acl/groups/maintainers
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 26]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-5.6. DAV:acl-restrictions
-
- This protected property defines the types of ACLs supported by this
- server, to avoid clients needlessly getting errors. When a client
- tries to set an ACL via the ACL method, the server may reject the
- attempt to set the ACL as specified. The following properties
- indicate the restrictions the client must observe before setting an
- ACL:
-
- Deny ACEs are not supported
-
- Inverted ACEs are not supported
-
- All deny ACEs must occur before any grant ACEs
-
- Indicates which principals are required to be
- present
-
-
-
-
-5.6.1. DAV:grant-only
-
- This element indicates that ACEs with deny clauses are not allowed.
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 27]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.6.2. DAV:no-invert ACE Constraint
-
- This element indicates that ACEs with the element are not
- allowed.
-
-
-
-5.6.3. DAV:deny-before-grant
-
- This element indicates that all deny ACEs must precede all grant
- ACEs.
-
-
-
-5.6.4. Required Principals
-
- The required principal elements identify which principals must have
- an ACE defined in the ACL.
-
-
-
- For example, the following element requires that the ACL contain a
-
- DAV:owner property ACE:
-
-
-
-
-
-5.6.5. Example: Retrieving DAV:acl-restrictions
-
- In this example, the client requests the value of the DAV:acl-
- restrictions property. Digest authentication provides credentials
- for the principal operating the client.
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="srcarter",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-Clemm, et al. Standards Track [Page 28]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-5.7. DAV:inherited-acl-set
-
- This protected property contains a set of URLs that identify other
- resources that also control the access to this resource. To have a
- privilege on a resource, not only must the ACL on that resource
- (specified in the DAV:acl property of that resource) grant the
- privilege, but so must the ACL of each resource identified in the
- DAV:inherited-acl-set property of that resource. Effectively, the
- privileges granted by the current ACL are ANDed with the privileges
- granted by each inherited ACL.
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 29]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.8. DAV:principal-collection-set
-
- This protected property of a resource contains a set of URLs that
- identify the root collections that contain the principals that are
- available on the server that implements this resource. A WebDAV
- Access Control Protocol user agent could use the contents of
- DAV:principal-collection-set to retrieve the DAV:displayname property
- (specified in Section 13.2 of [RFC2518]) of all principals on that
- server, thereby yielding human-readable names for each principal that
- could be displayed in a user interface.
-
-
-
- Since different servers can control different parts of the URL
- namespace, different resources on the same host MAY have different
- DAV:principal-collection-set values. The collections specified in
- the DAV:principal-collection-set MAY be located on different hosts
- from the resource. The URLs in DAV:principal-collection-set SHOULD be
- http or https scheme URLs. For security and scalability reasons, a
- server MAY report only a subset of the entire set of known principal
- collections, and therefore clients should not assume they have
- retrieved an exhaustive listing. Additionally, a server MAY elect to
- report none of the principal collections it knows about, in which
- case the property value would be empty.
-
- The value of DAV:principal-collection-set gives the scope of the
- DAV:principal-property-search REPORT (defined in Section 9.4).
- Clients use the DAV:principal-property-search REPORT to populate
- their user interface with a list of principals. Therefore, servers
- that limit a client's ability to obtain principal information will
- interfere with the client's ability to manipulate access control
- lists, due to the difficulty of getting the URL of a principal for
- use in an ACE.
-
-5.8.1. Example: Retrieving DAV:principal-collection-set
-
- In this example, the client requests the value of the DAV:principal-
- collection-set property on the collection resource identified by URL
- http://www.example.com/papers/. The property contains the two URLs,
- http://www.example.com/acl/users/ and http://
- www.example.com/acl/groups/, both wrapped in DAV:href XML elements.
- Digest authentication provides credentials for the principal
- operating the client.
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 30]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The client might reasonably follow this request with two separate
- PROPFIND requests to retrieve the DAV:displayname property of the
- members of the two collections (/acl/users and /acl/groups). This
- information could be used when displaying a user interface for
- creating access control entries.
-
- >> Request <<
-
- PROPFIND /papers/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="yarong",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/papers/
-
-
-
- http://www.example.com/acl/users/
- http://www.example.com/acl/groups/
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 31]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-5.9. Example: PROPFIND to retrieve access control properties
-
- The following example shows how access control information can be
- retrieved by using the PROPFIND method to fetch the values of the
- DAV:owner, DAV:supported-privilege-set, DAV:current-user-privilege-
- set, and DAV:acl properties.
-
- >> Request <<
-
- PROPFIND /top/container/ HTTP/1.1
- Host: www.example.com
- Content-type: text/xml; charset="utf-8"
- Content-Length: xxx
- Depth: 0
- Authorization: Digest username="ejw",
- realm="users@example.com", nonce="...",
- uri="/top/container/", response="...", opaque="..."
-
-
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- http://www.example.com/top/container/
-
-
-
- http://www.example.com/users/gclemm
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 32]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
- Any operation
-
-
-
-
- Read any object
-
-
-
-
-
-
- Write any object
-
-
-
-
- Create an object
-
-
-
-
-
- Update an object
-
-
-
-
-
-
- Delete an object
-
-
-
-
-
- Read the ACL
-
-
-
-
-
- Write the ACL
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 33]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
- http://www.example.com/users/esedlar
-
-
-
-
-
-
-
-
-
- http://www.example.com/groups/mrktng
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- http://www.example.com/top
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 34]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The value of the DAV:owner property is a single DAV:href XML element
- containing the URL of the principal that owns this resource.
-
- The value of the DAV:supported-privilege-set property is a tree of
- supported privileges (using "[XML Namespace , localname]" to identify
- each privilege):
-
- [DAV:, all] (aggregate, abstract)
- |
- +-- [DAV:, read]
- +-- [DAV:, write] (aggregate, abstract)
- |
- +-- [http://www.example.com/acl, create]
- +-- [http://www.example.com/acl, update]
- +-- [http://www.example.com/acl, delete]
- +-- [DAV:, read-acl]
- +-- [DAV:, write-acl]
-
- The DAV:current-user-privilege-set property contains two privileges,
- DAV:read, and DAV:read-acl. This indicates that the current
- authenticated user only has the ability to read the resource, and
- read the DAV:acl property on the resource. The DAV:acl property
- contains a set of four ACEs:
-
- ACE #1: The principal identified by the URL http://www.example.com/
- users/esedlar is granted the DAV:read, DAV:write, and DAV:read-acl
- privileges.
-
- ACE #2: The principals identified by the URL http://www.example.com/
- groups/mrktng are denied the DAV:read privilege. In this example,
- the principal URL identifies a group.
-
- ACE #3: In this ACE, the principal is a property principal,
- specifically the DAV:owner property. When evaluating this ACE, the
- value of the DAV:owner property is retrieved, and is examined to see
- if it contains a DAV:href XML element. If so, the URL within the
- DAV:href element is read, and identifies a principal. In this ACE,
- the owner is granted DAV:read-acl, and DAV:write-acl privileges.
-
- ACE #4: This ACE grants the DAV:all principal (all users) the
- DAV:read privilege. This ACE is inherited from the resource http://
- www.example.com/top, the parent collection of this resource.
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 35]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-6. ACL Evaluation
-
- WebDAV ACLs are evaluated in similar manner as ACLs on Windows NT and
- in NFSv4 [RFC3530]). An ACL is evaluated to determine whether or not
- access will be granted for a WebDAV request. ACEs are maintained in
- a particular order, and are evaluated until all of the permissions
- required by the current request have been granted, at which point the
- ACL evaluation is terminated and access is granted. If, during ACL
- evaluation, a ACE (matching the current user) is encountered
- for a privilege which has not yet been granted, the ACL evaluation is
- terminated and access is denied. Failure to have all required
- privileges granted results in access being denied.
-
- Note that the semantics of many other existing ACL systems may be
- represented via this mechanism, by mixing deny and grant ACEs. For
- example, consider the standard "rwx" privilege scheme used by UNIX.
- In this scheme, if the current user is the owner of the file, access
- is granted if the corresponding privilege bit is set and denied if
- not set, regardless of the permissions set on the file's group and
- for the world. An ACL for UNIX permissions of "r--rw-r--" might be
- constructed like:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 36]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- and the would be defined as:
-
-
-
-
-
-
-
-
- Note that the client can still get errors from a UNIX server in spite
- of obeying the , including
- (adding an ACE specifying a principal other than the ones in the ACL
- above) or (by trying to reorder the ACEs in the
- example above), as these particular implementation semantics are too
- complex to be captured with the simple (but general) declarative
- restrictions.
-
-7. Access Control and existing methods
-
- This section defines the impact of access control functionality on
- existing methods.
-
-7.1. Any HTTP method
-
-7.1.1. Error Handling
-
- The WebDAV ACL mechanism requires the usage of HTTP method
- "preconditions" as described in section 1.6 of RFC3253 for ALL HTTP
- methods. All HTTP methods have an additional precondition called
- DAV:need-privileges. If an HTTP method fails due to insufficient
- privileges, the response body to the "403 Forbidden" error MUST
- contain the element, which in turn contains the
-
-
-
-Clemm, et al. Standards Track [Page 37]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- element, which contains one or more
- elements indicating which resource had insufficient
- privileges, and what the lacking privileges were:
-
-
-
-
- Since some methods require multiple permissions on multiple
- resources, this information is needed to resolve any ambiguity.
- There is no requirement that all privilege violations be reported -
- for implementation reasons, some servers may only report the first
- privilege violation. For example:
-
- >> Request <<
-
- MOVE /a/b/ HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/c/d
-
- >> Response <<
-
- HTTP/1.1 403 Forbidden
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
- /a
-
-
-
- /c
-
-
-
-
-
-7.2. OPTIONS
-
- If the server supports access control, it MUST return "access-
- control" as a field in the DAV response header from an OPTIONS
- request on any resource implemented by that server. A value of
- "access-control" in the DAV header MUST indicate that the server
- supports all MUST level requirements and REQUIRED features specified
- in this document.
-
-
-
-
-
-Clemm, et al. Standards Track [Page 38]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-7.2.1. Example - OPTIONS
-
- >> Request <<
-
- OPTIONS /foo.html HTTP/1.1
- Host: www.example.com
- Content-Length: 0
-
- >> Response <<
-
- HTTP/1.1 200 OK
- DAV: 1, 2, access-control
- Allow: OPTIONS, GET, PUT, PROPFIND, PROPPATCH, ACL
-
- In this example, the OPTIONS response indicates that the server
- supports access control and that /foo.html can have its access
- control list modified by the ACL method.
-
-7.3. MOVE
-
- When a resource is moved from one location to another due to a MOVE
- request, the non-inherited and non-protected ACEs in the DAV:acl
- property of the resource MUST NOT be modified, or the MOVE request
- fails. Handling of inherited and protected ACEs is intentionally
- undefined to give server implementations flexibility in how they
- implement ACE inheritance and protection.
-
-7.4. COPY
-
- The DAV:acl property on the resource at the destination of a COPY
- MUST be the same as if the resource was created by an individual
- resource creation request (e.g., MKCOL, PUT). Clients wishing to
- preserve the DAV:acl property across a copy need to read the DAV:acl
- property prior to the COPY, then perform an ACL operation on the new
- resource at the destination to restore, insofar as this is possible,
- the original access control list.
-
-7.5. LOCK
-
- A lock on a resource ensures that only the lock owner can modify ACEs
- that are not inherited and not protected (these are the only ACEs
- that a client can modify with an ACL request). A lock does not
- protect inherited or protected ACEs, since a client cannot modify
- them with an ACL request on that resource.
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 39]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-8. Access Control Methods
-
-8.1. ACL
-
- The ACL method modifies the access control list (which can be read
- via the DAV:acl property) of a resource. Specifically, the ACL
- method only permits modification to ACEs that are not inherited, and
- are not protected. An ACL method invocation modifies all non-
- inherited and non-protected ACEs in a resource's access control list
- to exactly match the ACEs contained within in the DAV:acl XML element
- (specified in Section 5.5) of the request body. An ACL request body
- MUST contain only one DAV:acl XML element. Unless the non-inherited
- and non-protected ACEs of the DAV:acl property of the resource can be
- updated to be exactly the value specified in the ACL request, the ACL
- request MUST fail.
-
- It is possible that the ACEs visible to the current user in the
- DAV:acl property may only be a portion of the complete set of ACEs on
- that resource. If this is the case, an ACL request only modifies the
- set of ACEs visible to the current user, and does not affect any
- non-visible ACE.
-
- In order to avoid overwriting DAV:acl changes by another client, a
- client SHOULD acquire a WebDAV lock on the resource before retrieving
- the DAV:acl property of a resource that it intends on updating.
-
- Implementation Note: Two common operations are to add or remove an
- ACE from an existing access control list. To accomplish this, a
- client uses the PROPFIND method to retrieve the value of the
- DAV:acl property, then parses the returned access control list to
- remove all inherited and protected ACEs (these ACEs are tagged
- with the DAV:inherited and DAV:protected XML elements). In the
- remaining set of non-inherited, non-protected ACEs, the client can
- add or remove one or more ACEs before submitting the final ACE set
- in the request body of the ACL method.
-
-8.1.1. ACL Preconditions
-
- An implementation MUST enforce the following constraints on an ACL
- request. If the constraint is violated, a 403 (Forbidden) or 409
- (Conflict) response MUST be returned and the indicated XML element
- MUST be returned as a child of a top level DAV:error element in an
- XML response body.
-
- Though these status elements are generally expressed as empty XML
- elements (and are defined as EMPTY in the DTD), implementations MAY
- return additional descriptive XML elements as children of the status
-
-
-
-
-Clemm, et al. Standards Track [Page 40]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- element. Clients MUST be able to accept children of these status
- elements. Clients that do not understand the additional XML elements
- should ignore them.
-
- (DAV:no-ace-conflict): The ACEs submitted in the ACL request MUST NOT
- conflict with each other. This is a catchall error code indicating
- that an implementation-specific ACL restriction has been violated.
-
- (DAV:no-protected-ace-conflict): The ACEs submitted in the ACL
- request MUST NOT conflict with the protected ACEs on the resource.
- For example, if the resource has a protected ACE granting DAV:write
- to a given principal, then it would not be consistent if the ACL
- request submitted an ACE denying DAV:write to the same principal.
-
- (DAV:no-inherited-ace-conflict): The ACEs submitted in the ACL
- request MUST NOT conflict with the inherited ACEs on the resource.
- For example, if the resource inherits an ACE from its parent
- collection granting DAV:write to a given principal, then it would not
- be consistent if the ACL request submitted an ACE denying DAV:write
- to the same principal. Note that reporting of this error will be
- implementation-dependent. Implementations MUST either report this
- error or allow the ACE to be set, and then let normal ACE evaluation
- rules determine whether the new ACE has any impact on the privileges
- available to a specific principal.
-
- (DAV:limited-number-of-aces): The number of ACEs submitted in the ACL
- request MUST NOT exceed the number of ACEs allowed on that resource.
- However, ACL-compliant servers MUST support at least one ACE granting
- privileges to a single principal, and one ACE granting privileges to
- a group.
-
- (DAV:deny-before-grant): All non-inherited deny ACEs MUST precede all
- non-inherited grant ACEs.
-
- (DAV:grant-only): The ACEs submitted in the ACL request MUST NOT
- include a deny ACE. This precondition applies only when the ACL
- restrictions of the resource include the DAV:grant-only constraint
- (defined in Section 5.6.1).
-
- (DAV:no-invert): The ACL request MUST NOT include a DAV:invert
- element. This precondition applies only when the ACL semantics of
- the resource includes the DAV:no-invert constraint (defined in
- Section 5.6.2).
-
- (DAV:no-abstract): The ACL request MUST NOT attempt to grant or deny
- an abstract privilege (see Section 5.3).
-
-
-
-
-
-Clemm, et al. Standards Track [Page 41]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- (DAV:not-supported-privilege): The ACEs submitted in the ACL request
- MUST be supported by the resource.
-
- (DAV:missing-required-principal): The result of the ACL request MUST
- have at least one ACE for each principal identified in a
- DAV:required-principal XML element in the ACL semantics of that
- resource (see Section 5.5).
-
- (DAV:recognized-principal): Every principal URL in the ACL request
- MUST identify a principal resource.
-
- (DAV:allowed-principal): The principals specified in the ACEs
- submitted in the ACL request MUST be allowed as principals for the
- resource. For example, a server where only authenticated principals
- can access resources would not allow the DAV:all or
- DAV:unauthenticated principals to be used in an ACE, since these
- would allow unauthenticated access to resources.
-
-8.1.2. Example: the ACL method
-
- In the following example, user "fielding", authenticated by
- information in the Authorization header, grants the principal
- identified by the URL http://www.example.com/users/esedlar (i.e., the
- user "esedlar") read and write privileges, grants the owner of the
- resource read-acl and write-acl privileges, and grants everyone read
- privileges.
-
- >> Request <<
-
- ACL /top/container/ HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="fielding",
- realm="users@example.com", nonce="...",
- uri="/top/container/", response="...", opaque="..."
-
-
-
-
-
- http://www.example.com/users/esedlar
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 42]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 200 OK
-
-8.1.3. Example: ACL method failure due to protected ACE conflict
-
- In the following request, user "fielding", authenticated by
- information in the Authorization header, attempts to deny the
- principal identified by the URL http://www.example.com/users/esedlar
- (i.e., the user "esedlar") write privileges. Prior to the request,
- the DAV:acl property on the resource contained a protected ACE (see
- Section 5.5.3) granting DAV:owner the DAV:read and DAV:write
- privileges. The principal identified by URL http://www.example.com/
- users/esedlar is the owner of the resource. The ACL method
- invocation fails because the submitted ACE conflicts with the
- protected ACE, thus violating the semantics of ACE protection.
-
- >> Request <<
-
- ACL /top/container/ HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="fielding",
- realm="users@example.com", nonce="...",
- uri="/top/container/", response="...", opaque="..."
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 43]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- http://www.example.com/users/esedlar
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 403 Forbidden
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
-
-
-8.1.4. Example: ACL method failure due to an inherited ACE conflict
-
- In the following request, user "ejw", authenticated by information in
- the Authorization header, tries to change the access control list on
- the resource http://www.example.com/top/index.html. This resource
- has two inherited ACEs.
-
- Inherited ACE #1 grants the principal identified by URL http://
- www.example.com/users/ejw (i.e., the user "ejw") http://
- www.example.com/privs/write-all and DAV:read-acl privileges. On this
- server, http://www.example.com/privs/write-all is an aggregate
- privilege containing DAV:write, and DAV:write-acl.
-
- Inherited ACE #2 grants principal DAV:all the DAV:read privilege.
-
- The request attempts to set a (non-inherited) ACE, denying the
- principal identified by the URL http://www.example.com/users/ejw
- (i.e., the user "ejw") DAV:write permission. This conflicts with
- inherited ACE #1. Note that the decision to report an inherited ACE
- conflict is specific to this server implementation. Another server
- implementation could have allowed the new ACE to be set, and then
- used normal ACE evaluation rules to determine whether the new ACE has
- any impact on the privileges available to a principal.
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 44]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Request <<
-
- ACL /top/index.html HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="ejw",
- realm="users@example.com", nonce="...",
- uri="/top/index.html", response="...", opaque="..."
-
-
-
-
-
- http://www.example.com/users/ejw
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 403 Forbidden
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
-
-
-8.1.5. Example: ACL method failure due to an attempt to set grant and
- deny in a single ACE
-
- In this example, user "ygoland", authenticated by information in the
- Authorization header, tries to change the access control list on the
- resource http://www.example.com/diamond/engagement-ring.gif. The ACL
- request includes a single, syntactically and semantically incorrect
- ACE, which attempts to grant the group identified by the URL http://
- www.example.com/users/friends DAV:read privilege and deny the
- principal identified by URL http://www.example.com/users/ygoland-so
- (i.e., the user "ygoland-so") DAV:read privilege. However, it is
- illegal to have multiple principal elements, as well as both a grant
- and deny element in the same ACE, so the request fails due to poor
- syntax.
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 45]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Request <<
-
- ACL /diamond/engagement-ring.gif HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="ygoland",
- realm="users@example.com", nonce="...",
- uri="/diamond/engagement-ring.gif", response="...",
- opaque="..."
-
-
-
-
-
- http://www.example.com/users/friends
-
-
-
- http://www.example.com/users/ygoland-so
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 400 Bad Request
- Content-Length: 0
-
- Note that if the request had been divided into two ACEs, one to
- grant, and one to deny, the request would have been syntactically
- well formed.
-
-9. Access Control Reports
-
-9.1. REPORT Method
-
- The REPORT method (defined in Section 3.6 of [RFC3253]) provides an
- extensible mechanism for obtaining information about a resource.
- Unlike the PROPFIND method, which returns the value of one or more
- named properties, the REPORT method can involve more complex
- processing. REPORT is valuable in cases where the server has access
- to all of the information needed to perform the complex request (such
- as a query), and where it would require multiple requests for the
- client to retrieve the information needed to perform the same
- request.
-
-
-
-
-Clemm, et al. Standards Track [Page 46]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- A server that supports the WebDAV Access Control Protocol MUST
- support the DAV:expand-property report (defined in Section 3.8 of
- [RFC3253]).
-
-9.2. DAV:acl-principal-prop-set Report
-
- The DAV:acl-principal-prop-set report returns, for all principals in
- the DAV:acl property (of the Request-URI) that are identified by
- http(s) URLs or by a DAV:property principal, the value of the
- properties specified in the REPORT request body. In the case where a
- principal URL appears multiple times, the DAV:acl-principal-prop-set
- report MUST return the properties for that principal only once.
- Support for this report is REQUIRED.
-
- One expected use of this report is to retrieve the human readable
- name (found in the DAV:displayname property) of each principal found
- in an ACL. This is useful for constructing user interfaces that show
- each ACE in a human readable form.
-
- Marshalling
-
- The request body MUST be a DAV:acl-principal-prop-set XML element.
-
-
- ANY value: a sequence of one or more elements, with at most one
- DAV:prop element.
- prop: see RFC 2518, Section 12.11
-
- This report is only defined when the Depth header has value "0";
- other values result in a 400 (Bad Request) error response. Note
- that [RFC3253], Section 3.6, states that if the Depth header is
- not present, it defaults to a value of "0".
-
- The response body for a successful request MUST be a
- DAV:multistatus XML element (i.e., the response uses the same
- format as the response for PROPFIND). In the case where there are
- no response elements, the returned multistatus XML element is
- empty.
-
- multistatus: see RFC 2518, Section 12.9
-
- The response body for a successful DAV:acl-principal-prop-set
- REPORT request MUST contain a DAV:response element for each
- principal identified by an http(s) URL listed in a DAV:principal
- XML element of an ACE within the DAV:acl property of the resource
- identified by the Request-URI.
-
-
-
-
-
-Clemm, et al. Standards Track [Page 47]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Postconditions:
-
- (DAV:number-of-matches-within-limits): The number of matching
- principals must fall within server-specific, predefined limits.
- For example, this condition might be triggered if a search
- specification would cause the return of an extremely large number
- of responses.
-
-9.2.1. Example: DAV:acl-principal-prop-set Report
-
- Resource http://www.example.com/index.html has an ACL with three
- ACEs:
-
- ACE #1: All principals (DAV:all) have DAV:read and DAV:read-current-
- user-privilege-set access.
-
- ACE #2: The principal identified by http://www.example.com/people/
- gstein (the user "gstein") is granted DAV:write, DAV:write-acl,
- DAV:read-acl privileges.
-
- ACE #3: The group identified by http://www.example.com/groups/authors
- (the "authors" group) is granted DAV:write and DAV:read-acl
- privileges.
-
- The following example shows a DAV:acl-principal-prop-set report
- requesting the DAV:displayname property. It returns the value of
- DAV:displayname for resources http://www.example.com/people/gstein
- and http://www.example.com/groups/authors , but not for DAV:all,
- since this is not an http(s) URL.
-
- >> Request <<
-
- REPORT /index.html HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Depth: 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 48]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/people/gstein
-
-
- Greg Stein
-
- HTTP/1.1 200 OK
-
-
-
- http://www.example.com/groups/authors
-
-
- Site authors
-
- HTTP/1.1 200 OK
-
-
-
-
-9.3. DAV:principal-match REPORT
-
- The DAV:principal-match REPORT is used to identify all members (at
- any depth) of the collection identified by the Request-URI that are
- principals and that match the current user. In particular, if the
- collection contains principals, the report can be used to identify
- all members of the collection that match the current user.
- Alternatively, if the collection contains resources that have a
- property that identifies a principal (e.g., DAV:owner), the report
- can be used to identify all members of the collection whose property
- identifies a principal that matches the current user. For example,
- this report can return all of the resources in a collection hierarchy
- that are owned by the current user. Support for this report is
- REQUIRED.
-
- Marshalling:
-
- The request body MUST be a DAV:principal-match XML element.
-
-
-
-
-
-Clemm, et al. Standards Track [Page 49]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- ANY value: an element whose value identifies a property. The
- expectation is the value of the named property typically contains
- an href element that contains the URI of a principal
-
- prop: see RFC 2518, Section 12.11
-
- This report is only defined when the Depth header has value "0";
- other values result in a 400 (Bad Request) error response. Note
- that [RFC3253], Section 3.6, states that if the Depth header is
- not present, it defaults to a value of "0". The response body for
- a successful request MUST be a DAV:multistatus XML element. In
- the case where there are no response elements, the returned
- multistatus XML element is empty.
-
- multistatus: see RFC 2518, Section 12.9
-
- The response body for a successful DAV:principal-match REPORT
- request MUST contain a DAV:response element for each member of the
- collection that matches the current user. When the
- DAV:principal-property element is used, a match occurs if the
- current user is matched by the principal identified by the URI
- found in the DAV:href element of the property identified by the
- DAV:principal-property element. When the DAV:self element is used
- in a DAV:principal-match report issued against a group, it matches
- the group if a member identifies the same principal as the current
- user.
-
- If DAV:prop is specified in the request body, the properties
- specified in the DAV:prop element MUST be reported in the
- DAV:response elements.
-
-9.3.1. Example: DAV:principal-match REPORT
-
- The following example identifies the members of the collection
- identified by the URL http://www.example.com/doc that are owned by
- the current user. The current user ("gclemm") is authenticated using
- Digest authentication.
-
- >> Request <<
-
- REPORT /doc/ HTTP/1.1
- Host: www.example.com
- Authorization: Digest username="gclemm",
- realm="users@example.com", nonce="...",
- uri="/papers/", response="...", opaque="..."
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
- Depth: 0
-
-
-
-Clemm, et al. Standards Track [Page 50]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/doc/foo.html
- HTTP/1.1 200 OK
-
-
- http://www.example.com/doc/img/bar.gif
- HTTP/1.1 200 OK
-
-
-
-9.4. DAV:principal-property-search REPORT
-
- The DAV:principal-property-search REPORT performs a search for all
- principals whose properties contain character data that matches the
- search criteria specified in the request. One expected use of this
- report is to discover the URL of a principal associated with a given
- person or group by searching for them by name. This is done by
- searching over DAV:displayname, which is defined on all principals.
-
- The actual search method (exact matching vs. substring matching vs,
- prefix-matching, case-sensitivity) deliberately is left to the server
- implementation to allow implementation on a wide set of possible user
- management systems. In cases where the implementation of
- DAV:principal-property-search is not constrained by the semantics of
- an underlying user management repository, preferred default semantics
- are caseless substring matches.
-
- For implementation efficiency, servers do not typically support
- searching on all properties. A search requesting properties that are
- not searchable for a particular principal will not match that
- principal.
-
- Support for the DAV:principal-property-search report is REQUIRED.
-
-
-
-Clemm, et al. Standards Track [Page 51]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Implementation Note: The value of a WebDAV property is a sequence
- of well-formed XML, and hence can include any character in the
- Unicode/ISO-10646 standard, that is, most known characters in
- human languages. Due to the idiosyncrasies of case mapping across
- human languages, implementation of case-insensitive matching is
- non-trivial. Implementors of servers that do perform substring
- matching are strongly encouraged to consult "The Unicode Standard"
- [UNICODE4], especially Section 5.18, Subsection "Caseless
- Matching", for guidance when implementing their case-insensitive
- matching algorithms.
-
- Implementation Note: Some implementations of this protocol will
- use an LDAP repository for storage of principal metadata. The
- schema describing each attribute (akin to a WebDAV property) in an
- LDAP repository specifies whether it supports case-sensitive or
- caseless searching. One of the benefits of leaving the search
- method to the discretion of the server implementation is the
- default LDAP attribute search behavior can be used when
- implementing the DAV:principal-property-search report.
-
- Marshalling:
-
- The request body MUST be a DAV:principal-property-search XML
- element containing a search specification and an optional list of
- properties. For every principal that matches the search
- specification, the response will contain the value of the
- requested properties on that principal.
-
-
-
- By default, the report searches all members (at any depth) of the
- collection identified by the Request-URI. If DAV:apply-to-
- principal-collection-set is specified in the request body, the
- request is applied instead to each collection identified by the
- DAV:principal-collection-set property of the resource identified
- by the Request-URI.
-
- The DAV:property-search element contains a prop element
- enumerating the properties to be searched and a match element,
- containing the search string.
-
-
- prop: see RFC 2518, Section 12.11
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 52]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Multiple property-search elements or multiple elements within a
- DAV:prop element will be interpreted with a logical AND.
-
- This report is only defined when the Depth header has value "0";
- other values result in a 400 (Bad Request) error response. Note
- that [RFC3253], Section 3.6, states that if the Depth header is
- not present, it defaults to a value of "0".
-
- The response body for a successful request MUST be a
- DAV:multistatus XML element. In the case where there are no
- response elements, the returned multistatus XML element is empty.
-
- multistatus: see RFC 2518, Section 12.9
-
- The response body for a successful DAV:principal-property-search
- REPORT request MUST contain a DAV:response element for each
- principal whose property values satisfy the search specification
- given in DAV:principal-property-search.
-
- If DAV:prop is specified in the request body, the properties
- specified in the DAV:prop element MUST be reported in the
- DAV:response elements.
-
- Preconditions:
-
- None
-
- Postconditions:
-
- (DAV:number-of-matches-within-limits): The number of matching
- principals must fall within server-specific, predefined limits.
- For example, this condition might be triggered if a search
- specification would cause the return of an extremely large number
- of responses.
-
-9.4.1. Matching
-
- There are several cases to consider when matching strings. The
- easiest case is when a property value is "simple" and has only
- character information item content (see [REC-XML-INFOSET]). For
- example, the search string "julian" would match the DAV:displayname
- property with value "Julian Reschke". Note that the on-the-wire
- marshaling of DAV:displayname in this case is:
-
- Julian Reschke
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 53]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The name of the property is encoded into the XML element information
- item, and the character information item content of the property is
- "Julian Reschke".
-
- A more complicated case occurs when properties have mixed content
- (that is, compound values consisting of multiple child element items,
- other types of information items, and character information item
- content). Consider the property "aprop" in the namespace "http://
- www.example.com/props/", marshaled as:
-
-
- {cdata 0}{cdata 1}
- {cdata 2} {cdata 3}
-
-
- In this case, matching is performed on each individual contiguous
- sequence of character information items. In the example above, a
- search string would be compared to the four following strings:
-
- {cdata 0}
- {cdata 1}
- {cdata 2}
- {cdata 3}
-
- That is, four individual matches would be performed, one each for
- {cdata 0}, {cdata 1}, {cdata 2}, and {cdata 3}.
-
-9.4.2. Example: successful DAV:principal-property-search REPORT
-
- In this example, the client requests the principal URLs of all users
- whose DAV:displayname property contains the substring "doE" and whose
- "title" property in the namespace "http://BigCorp.com/ns/" (that is,
- their professional title) contains "Sales". In addition, the client
- requests five properties to be returned with the matching principals:
-
- In the DAV: namespace: displayname
-
- In the http://www.example.com/ns/ namespace: department, phone,
- office, salary
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 54]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The response shows that two principal resources meet the search
- specification, "John Doe" and "Zygdoebert Smith". The property
- "salary" in namespace "http://www.example.com/ns/" is not returned,
- since the principal making the request does not have sufficient
- access permissions to read this property.
-
- >> Request <<
-
- REPORT /users/ HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset=utf-8
- Content-Length: xxxx
- Depth: 0
-
-
-
-
-
-
-
- doE
-
-
-
-
-
- Sales
-
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: text/xml; charset=utf-8
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/users/jdoe
-
-
-
-
-Clemm, et al. Standards Track [Page 55]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
- John Doe
- Widget Sales
- 234-4567
- 209
-
- HTTP/1.1 200 OK
-
-
-
-
-
- HTTP/1.1 403 Forbidden
-
-
-
- http://www.example.com/users/zsmith
-
-
- Zygdoebert Smith
- Gadget Sales
- 234-7654
- 114
-
- HTTP/1.1 200 OK
-
-
-
-
-
- HTTP/1.1 403 Forbidden
-
-
-
-
-9.5. DAV:principal-search-property-set REPORT
-
- The DAV:principal-search-property-set REPORT identifies those
- properties that may be searched using the DAV:principal-property-
- search REPORT (defined in Section 9.4).
-
- Servers MUST support the DAV:principal-search-property-set REPORT on
- all collections identified in the value of a DAV:principal-
- collection-set property.
-
- An access control protocol user agent could use the results of the
- DAV:principal-search-property-set REPORT to present a query interface
- to the user for retrieving principals.
-
-
-
-Clemm, et al. Standards Track [Page 56]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- Support for this report is REQUIRED.
-
- Implementation Note: Some clients will have only limited screen
- real estate for the display of lists of searchable properties. In
- this case, a user might appreciate having the most frequently
- searched properties be displayed on-screen, rather than having to
- scroll through a long list of searchable properties. One
- mechanism for signaling the most frequently searched properties is
- to return them towards the start of a list of properties. A
- client can then preferentially display the list of properties in
- order, increasing the likelihood that the most frequently searched
- properties will appear on-screen, and will not require scrolling
- for their selection.
-
- Marshalling:
-
- The request body MUST be an empty DAV:principal-search-property-
- set XML element.
-
- This report is only defined when the Depth header has value "0";
- other values result in a 400 (Bad Request) error response. Note
- that [RFC3253], Section 3.6, states that if the Depth header is
- not present, it defaults to a value of "0".
-
- The response body MUST be a DAV:principal-search-property-set XML
- element, containing a DAV:principal-search-property XML element
- for each property that may be searched with the DAV:principal-
- property-search REPORT. A server MAY limit its response to just a
- subset of the searchable properties, such as those likely to be
- useful to an interactive access control client.
-
-
-
- Each DAV:principal-search-property XML element contains exactly
- one searchable property, and a description of the property.
-
-
-
- The DAV:prop element contains one principal property on which the
- server is able to perform a DAV:principal-property-search REPORT.
-
- prop: see RFC 2518, Section 12.11
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 57]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- The description element is a human-readable description of what
- information this property represents. Servers MUST indicate the
- human language of the description using the xml:lang attribute and
- SHOULD consider the HTTP Accept-Language request header when
- selecting one of multiple available languages.
-
-
-
-9.5.1. Example: DAV:principal-search-property-set REPORT
-
- In this example, the client determines the set of searchable
- principal properties by requesting the DAV:principal-search-
- property-set REPORT on the root of the server's principal URL
- collection set, identified by http://www.example.com/users/.
-
- >> Request <<
-
- REPORT /users/ HTTP/1.1
- Host: www.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
- Accept-Language: en, de
- Authorization: BASIC d2FubmFtYWs6cGFzc3dvcmQ=
- Depth: 0
-
-
-
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
-
-
-
- Full name
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 58]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
- Job title
-
-
-
-10. XML Processing
-
- Implementations of this specification MUST support the XML element
- ignore rule, as specified in Section 23.3.2 of [RFC2518], and the XML
- Namespace recommendation [REC-XML-NAMES].
-
- Note that use of the DAV namespace is reserved for XML elements and
- property names defined in a standards-track or Experimental IETF RFC.
-
-11. Internationalization Considerations
-
- In this specification, the only human-readable content can be found
- in the description XML element, found within the DAV:supported-
- privilege-set property. This element contains a human-readable
- description of the capabilities controlled by a privilege. As a
- result, the description element must be capable of representing
- descriptions in multiple character sets. Since the description
- element is found within a WebDAV property, it is represented on the
- wire as XML [REC-XML], and hence can leverage XML's language tagging
- and character set encoding capabilities. Specifically, XML
- processors at minimum must be able to read XML elements encoded using
- the UTF-8 [RFC3629] encoding of the ISO 10646 multilingual plane.
- XML examples in this specification demonstrate use of the charset
- parameter of the Content-Type header, as defined in [RFC3023], as
- well as the XML "encoding" attribute, which together provide charset
- identification information for MIME and XML processors. Furthermore,
- this specification requires server implementations to tag description
- fields with the xml:lang attribute (see Section 2.12 of [REC-XML]),
- which specifies the human language of the description. Additionally,
- server implementations should take into account the value of the
- Accept-Language HTTP header to determine which description string to
- return.
-
- For XML elements other than the description element, it is expected
- that implementations will treat the property names, privilege names,
- and values as tokens, and convert these tokens into human-readable
- text in the user's language and character set when displayed to a
- person. Only a generic WebDAV property display utility would display
- these values in their raw form to a human user.
-
- For error reporting, we follow the convention of HTTP/1.1 status
- codes, including with each status code a short, English description
- of the code (e.g., 200 (OK)). While the possibility exists that a
-
-
-
-Clemm, et al. Standards Track [Page 59]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- poorly crafted user agent would display this message to a user,
- internationalized applications will ignore this message, and display
- an appropriate message in the user's language and character set.
-
- Further internationalization considerations for this protocol are
- described in the WebDAV Distributed Authoring protocol specification
- [RFC2518].
-
-12. Security Considerations
-
- Applications and users of this access control protocol should be
- aware of several security considerations, detailed below. In
- addition to the discussion in this document, the security
- considerations detailed in the HTTP/1.1 specification [RFC2616], the
- WebDAV Distributed Authoring Protocol specification [RFC2518], and
- the XML Media Types specification [RFC3023] should be considered in a
- security analysis of this protocol.
-
-12.1. Increased Risk of Compromised Users
-
- In the absence of a mechanism for remotely manipulating access
- control lists, if a single user's authentication credentials are
- compromised, only those resources for which the user has access
- permission can be read, modified, moved, or deleted. With the
- introduction of this access control protocol, if a single compromised
- user has the ability to change ACLs for a broad range of other users
- (e.g., a super-user), the number of resources that could be altered
- by a single compromised user increases. This risk can be mitigated
- by limiting the number of people who have write-acl privileges across
- a broad range of resources.
-
-12.2. Risks of the DAV:read-acl and DAV:current-user-privilege-set
- Privileges
-
- The ability to read the access privileges (stored in the DAV:acl
- property), or the privileges permitted the currently authenticated
- user (stored in the DAV:current-user-privilege-set property) on a
- resource may seem innocuous, since reading an ACL cannot possibly
- affect the resource's state. However, if all resources have world-
- readable ACLs, it is possible to perform an exhaustive search for
- those resources that have inadvertently left themselves in a
- vulnerable state, such as being world-writable. In particular, the
- property retrieval method PROPFIND, executed with Depth infinity on
- an entire hierarchy, is a very efficient way to retrieve the DAV:acl
- or DAV:current-user-privilege-set properties. Once found, this
- vulnerability can be exploited by a denial of service attack in which
- the open resource is repeatedly overwritten. Alternately, writable
- resources can be modified in undesirable ways.
-
-
-
-Clemm, et al. Standards Track [Page 60]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- To reduce this risk, read-acl privileges should not be granted to
- unauthenticated principals, and restrictions on read-acl and read-
- current-user-privilege-set privileges for authenticated principals
- should be carefully analyzed when deploying this protocol. Access to
- the current-user-privilege-set property will involve a tradeoff of
- usability versus security. When the current-user-privilege-set is
- visible, user interfaces are expected to provide enhanced information
- concerning permitted and restricted operations, yet this information
- may also indicate a vulnerability that could be exploited.
- Deployment of this protocol will need to evaluate this tradeoff in
- light of the requirements of the deployment environment.
-
-12.3. No Foreknowledge of Initial ACL
-
- In an effort to reduce protocol complexity, this protocol
- specification intentionally does not address the issue of how to
- manage or discover the initial ACL that is placed upon a resource
- when it is created. The only way to discover the initial ACL is to
- create a new resource, then retrieve the value of the DAV:acl
- property. This assumes the principal creating the resource also has
- been granted the DAV:read-acl privilege.
-
- As a result, it is possible that a principal could create a resource,
- and then discover that its ACL grants privileges that are
- undesirable. Furthermore, this protocol makes it possible (though
- unlikely) that the creating principal could be unable to modify the
- ACL, or even delete the resource. Even when the ACL can be modified,
- there will be a short period of time when the resource exists with
- the initial ACL before its new ACL can be set.
-
- Several factors mitigate this risk. Human principals are often aware
- of the default access permissions in their editing environments and
- take this into account when writing information. Furthermore,
- default privilege policies are usually very conservative, limiting
- the privileges granted by the initial ACL.
-
-13. Authentication
-
- Authentication mechanisms defined for use with HTTP and WebDAV also
- apply to this WebDAV Access Control Protocol, in particular the Basic
- and Digest authentication mechanisms defined in [RFC2617].
- Implementation of the ACL spec requires that Basic authentication, if
- used, MUST only be supported over secure transport such as TLS.
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 61]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-14. IANA Considerations
-
- This document uses the namespace defined by [RFC2518] for XML
- elements. That is, this specification uses the "DAV:" URI namespace,
- previously registered in the URI schemes registry. All other IANA
- considerations mentioned in [RFC2518] are also applicable to this
- specification.
-
-15. Acknowledgements
-
- This protocol is the collaborative product of the WebDAV ACL design
- team: Bernard Chester, Geoff Clemm, Anne Hopkins, Barry Lind, Sean
- Lyndersay, Eric Sedlar, Greg Stein, and Jim Whitehead. The authors
- are grateful for the detailed review and comments provided by Jim
- Amsden, Dylan Barrell, Gino Basso, Murthy Chintalapati, Lisa
- Dusseault, Stefan Eissing, Tim Ellison, Yaron Goland, Dennis
- Hamilton, Laurie Harper, Eckehard Hermann, Ron Jacobs, Chris Knight,
- Remy Maucherat, Larry Masinter, Joe Orton, Peter Raymond, and Keith
- Wannamaker. We thank Keith Wannamaker for the initial text of the
- principal property search sections. Prior work on WebDAV access
- control protocols has been performed by Yaron Goland, Paul Leach,
- Lisa Dusseault, Howard Palmer, and Jon Radoff. We would like to
- acknowledge the foundation laid for us by the authors of the DeltaV,
- WebDAV and HTTP protocols upon which this protocol is layered, and
- the invaluable feedback from the WebDAV working group.
-
-16. References
-
-16.1. Normative References
-
- [REC-XML] Bray, T., Paoli, J., Sperberg-McQueen, C. and E.
- Maler, "Extensible Markup Language (XML) 1.0
- ((Third ed)", W3C REC REC-xml-20040204, February
- 2004, .
-
- [REC-XML-INFOSET] Cowan, J. and R. Tobin, "XML Information Set
- (Second Edition)", W3C REC REC-xml-infoset-
- 20040204, February 2004,
- .
-
- [REC-XML-NAMES] Bray, T., Hollander, D. and A. Layman, "Namespaces
- in XML", W3C REC REC-xml-names-19990114, January
- 1999, .
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-
-
-Clemm, et al. Standards Track [Page 62]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- [RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, S.
- and D. Jensen, "HTTP Extensions for Distributed
- Authoring -- WEBDAV", RFC 2518, February 1999.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P. and T. Berners-Lee,
- "Hypertext 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.
-
- [RFC3023] Murata, M., St.Laurent, S. and D. Kohn, "XML Media
- Types", RFC 3023, January 2001.
-
- [RFC3253] Clemm, G., Amsden, J., Ellison, T., Kaler, C. and
- J. Whitehead, "Versioning Extensions to WebDAV",
- RFC 3253, March 2002.
-
- [RFC3530] Shepler, S., Ed., Callaghan, B., Robinson, D.,
- Thurlow, R., Beame, C., Eisler, M. and D. Noveck,
- "Network File System (NFS) version 4 Protocol", RFC
- 3530, April 2003.
-
- [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", STD 63, RFC 3629 November 2003.
-
-16.2. Informative References
-
- [RFC2251] Wahl, M., Howes, T. and S. Kille, "Lightweight
- Directory Access Protocol (v3)", RFC 2251, December
- 1997.
-
- [RFC2255] Howes, T. and M. Smith, "The LDAP URL Format", RFC
- 2255, December 1997.
-
- [UNICODE4] The Unicode Consortium, "The Unicode Standard -
- Version 4.0", Addison-Wesley , August 2003,
- .
- ISBN 0321185781.
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 63]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-Appendix A. WebDAV XML Document Type Definition Addendum
-
- All XML elements defined in this Document Type Definition (DTD)
- belong to the DAV namespace. This DTD should be viewed as an addendum
- to the DTD provided in [RFC2518], section 23.1.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 64]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 65]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ANY value: a sequence of one or more elements, with at most one
- DAV:prop element.
-
-
-
- ANY value: an element whose value identifies a property. The
- expectation is the value of the named property typically contains
- an href element that contains the URI of a principal
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 66]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-Appendix B. WebDAV Method Privilege Table (Normative)
-
- The following table of WebDAV methods (as defined in RFC 2518, 2616,
- and 3253) clarifies which privileges are required for access for each
- method. Note that the privileges listed, if denied, MUST cause
- access to be denied. However, given that a specific implementation
- MAY define an additional custom privilege to control access to
- existing methods, having all of the indicated privileges does not
- mean that access will be granted. Note that lack of the indicated
- privileges does not imply that access will be denied, since a
- particular implementation may use a sub-privilege aggregated under
- the indicated privilege to control access. Privileges required refer
- to the current resource being processed unless otherwise specified.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 67]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- +---------------------------------+---------------------------------+
- | METHOD | PRIVILEGES |
- +---------------------------------+---------------------------------+
- | GET | |
- | HEAD | |
- | OPTIONS | |
- | PUT (target exists) | on target |
- | | resource |
- | PUT (no target exists) | on parent collection |
- | | of target |
- | PROPPATCH | |
- | ACL | |
- | PROPFIND | (plus and |
- | | as needed) |
- | COPY (target exists) | , and |
- | | on target |
- | | resource |
- | COPY (no target exists) | , on target |
- | | collection |
- | MOVE (no target exists) | on source collection |
- | | and on target |
- | | collection |
- | MOVE (target exists) | As above, plus on |
- | | the target collection |
- | DELETE | on parent collection |
- | LOCK (target exists) | |
- | LOCK (no target exists) | on parent collection |
- | MKCOL | on parent collection |
- | UNLOCK | |
- | CHECKOUT | |
- | CHECKIN | |
- | REPORT | (on all referenced |
- | | resources) |
- | VERSION-CONTROL | |
- | MERGE | |
- | MKWORKSPACE | on parent |
- | | collection |
- | BASELINE-CONTROL | and |
- | | |
- | MKACTIVITY | on parent |
- | | collection |
- +---------------------------------+---------------------------------+
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 68]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-Index
-
- A
- ACL method 40
-
- C
- Condition Names
- DAV:allowed-principal (pre) 42
- DAV:deny-before-grant (pre) 41
- DAV:grant-only (pre) 41
- DAV:limited-number-of-aces (pre) 41
- DAV:missing-required-principal (pre) 42
- DAV:no-abstract (pre) 41
- DAV:no-ace-conflict (pre) 41
- DAV:no-inherited-ace-conflict (pre) 41
- DAV:no-invert (pre) 41
- DAV:no-protected-ace-conflict (pre) 41
- DAV:not-supported-privilege (pre) 42
- DAV:number-of-matches-within-limits (post) 48, 53
- DAV:recognized-principal (pre) 42
-
- D
- DAV header
- compliance class 'access-control' 38
- DAV:acl property 23
- DAV:acl-principal-prop-set report 48
- DAV:acl-restrictions property 27
- DAV:all privilege 13
- DAV:allowed-principal precondition 42
- DAV:alternate-URI-set property 14
- DAV:bind privilege 12
- DAV:current-user-privilege-set property 21
- DAV:deny-before-grant precondition 41
- DAV:grant-only precondition 41
- DAV:group property 18
- DAV:group-member-set property 14
- DAV:group-membership property 14
- DAV:inherited-acl-set property 29
- DAV:limited-number-of-aces precondition 41
- DAV:missing-required-principal precondition 42
- DAV:no-abstract precondition 41
- DAV:no-ace-conflict precondition 41
- DAV:no-inherited-ace-conflict precondition 41
- DAV:no-invert precondition 41
- DAV:no-protected-ace-conflict precondition 41
- DAV:not-supported-privilege precondition 42
- DAV:number-of-matches-within-limits postcondition 48, 53
- DAV:owner property 15
-
-
-
-Clemm, et al. Standards Track [Page 69]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- DAV:principal resource type 13
- DAV:principal-collection-set property 30
- DAV:principal-match report 50
- DAV:principal-property-search 51
- DAV:principal-search-property-set 56
- DAV:principal-URL property 14
- DAV:read privilege 10
- DAV:read-acl privilege 11
- DAV:read-current-user-privilege-set privilege 12
- DAV:recognized-principal precondition 42
- DAV:supported-privilege-set property 18
- DAV:unbind privilege 12
- DAV:unlock privilege 11
- DAV:write privilege 10
- DAV:write-acl privilege 12
- DAV:write-content privilege 10
- DAV:write-properties privilege 10
-
- M
- Methods
- ACL 40
-
- P
- Privileges
- DAV:all 13
- DAV:bind 12
- DAV:read 10
- DAV:read-acl 11
- DAV:read-current-user-privilege-set 12
- DAV:unbind 12
- DAV:unlock 11
- DAV:write 10
- DAV:write-acl 12
- DAV:write-content 11
- DAV:write-properties 10
- Properties
- DAV:acl 23
- DAV:acl-restrictions 27
- DAV:alternate-URI-set 14
- DAV:current-user-privilege-set 21
- DAV:group 18
- DAV:group-member-set 14
- DAV:group-membership 14
- DAV:inherited-acl-set 29
- DAV:owner 15
- DAV:principal-collection-set 30
- DAV:principal-URL 14
- DAV:supported-privilege-set 18
-
-
-
-Clemm, et al. Standards Track [Page 70]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
- R
- Reports
- DAV:acl-principal-prop-set 47
- DAV:principal-match 49
- DAV:principal-property-search 51
- DAV:principal-search-property-set 56
- Resource Types
- DAV:principal 13
-
-Authors' Addresses
-
- Geoffrey Clemm
- IBM
- 20 Maguire Road
- Lexington, MA 02421
-
- EMail: geoffrey.clemm@us.ibm.com
-
-
- Julian F. Reschke
- greenbytes GmbH
- Salzmannstrasse 152
- Muenster, NW 48159
- Germany
-
- EMail: julian.reschke@greenbytes.de
-
-
- Eric Sedlar
- Oracle Corporation
- 500 Oracle Parkway
- Redwood Shores, CA 94065
-
- EMail: eric.sedlar@oracle.com
-
-
- Jim Whitehead
- U.C. Santa Cruz, Dept. of Computer Science
- 1156 High Street
- Santa Cruz, CA 95064
-
- EMail: ejw@cse.ucsc.edu
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 71]
-
-RFC 3744 WebDAV Access Control Protocol May 2004
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2004). This document is subject
- to the rights, licenses and restrictions contained in BCP 78, and
- except as set forth therein, the authors retain all their rights.
-
- This document and the information contained herein are provided on an
- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE
- REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
- INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
- THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- Intellectual Property Rights or other rights that might be claimed
- to pertain to the implementation or use of the technology
- described in this document or the extent to which any license
- under such rights might or might not be available; nor does it
- represent that it has made any independent effort to identify any
- such rights. Information on the procedures with respect to
- rights in RFC documents can be found in BCP 78 and BCP 79.
-
- Copies of IPR disclosures made to the IETF Secretariat and any
- assurances of licenses to be made available, or the result of an
- attempt made to obtain a general license or permission for the use
- of such proprietary rights by implementers or users of this
- specification can be obtained from the IETF on-line IPR repository
- at http://www.ietf.org/ipr.
-
- The IETF invites any interested party to bring to its attention
- any copyrights, patents or patent applications, or other
- proprietary rights that may cover technology that may be required
- to implement this standard. Please address the information to the
- IETF at ietf-ipr@ietf.org.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-Clemm, et al. Standards Track [Page 72]
-
diff --git a/doc/rfc4791-caldav.txt b/doc/rfc4791-caldav.txt
deleted file mode 100644
index 7a30bb21..00000000
--- a/doc/rfc4791-caldav.txt
+++ /dev/null
@@ -1,5995 +0,0 @@
-
-
-
-
-
-
-Network Working Group C. Daboo
-Request for Comments: 4791 Apple
-Category: Standards Track B. Desruisseaux
- Oracle
- L. Dusseault
- CommerceNet
- March 2007
-
-
- Calendaring Extensions to WebDAV (CalDAV)
-
-Status of This Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The IETF Trust (2007).
-
-Abstract
-
- This document defines extensions to the Web Distributed Authoring and
- Versioning (WebDAV) protocol to specify a standard way of accessing,
- managing, and sharing calendaring and scheduling information based on
- the iCalendar format. This document defines the "calendar-access"
- feature of CalDAV.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 1]
-
-RFC 4791 CalDAV March 2007
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 5
- 1.1. Notational Conventions . . . . . . . . . . . . . . . . . . 5
- 1.2. XML Namespaces and Processing . . . . . . . . . . . . . . 5
- 1.3. Method Preconditions and Postconditions . . . . . . . . . 6
- 2. Requirements Overview . . . . . . . . . . . . . . . . . . . . 6
- 3. Calendaring Data Model . . . . . . . . . . . . . . . . . . . . 7
- 3.1. Calendar Server . . . . . . . . . . . . . . . . . . . . . 7
- 3.2. Recurrence and the Data Model . . . . . . . . . . . . . . 8
- 4. Calendar Resources . . . . . . . . . . . . . . . . . . . . . . 9
- 4.1. Calendar Object Resources . . . . . . . . . . . . . . . . 9
- 4.2. Calendar Collection . . . . . . . . . . . . . . . . . . . 10
- 5. Calendar Access Feature . . . . . . . . . . . . . . . . . . . 11
- 5.1. Calendar Access Support . . . . . . . . . . . . . . . . . 11
- 5.1.1. Example: Using OPTIONS for the Discovery of
- Calendar Access Support . . . . . . . . . . . . . . . 12
- 5.2. Calendar Collection Properties . . . . . . . . . . . . . . 12
- 5.2.1. CALDAV:calendar-description Property . . . . . . . . . 12
- 5.2.2. CALDAV:calendar-timezone Property . . . . . . . . . . 13
- 5.2.3. CALDAV:supported-calendar-component-set Property . . . 14
- 5.2.4. CALDAV:supported-calendar-data Property . . . . . . . 15
- 5.2.5. CALDAV:max-resource-size Property . . . . . . . . . . 16
- 5.2.6. CALDAV:min-date-time Property . . . . . . . . . . . . 17
- 5.2.7. CALDAV:max-date-time Property . . . . . . . . . . . . 18
- 5.2.8. CALDAV:max-instances Property . . . . . . . . . . . . 19
- 5.2.9. CALDAV:max-attendees-per-instance Property . . . . . . 19
- 5.2.10. Additional Precondition for PROPPATCH . . . . . . . . 20
- 5.3. Creating Resources . . . . . . . . . . . . . . . . . . . . 20
- 5.3.1. MKCALENDAR Method . . . . . . . . . . . . . . . . . . 20
- 5.3.1.1. Status Codes . . . . . . . . . . . . . . . . . . . 22
- 5.3.1.2. Example: Successful MKCALENDAR Request . . . . . . 23
- 5.3.2. Creating Calendar Object Resources . . . . . . . . . . 25
- 5.3.2.1. Additional Preconditions for PUT, COPY, and
- MOVE . . . . . . . . . . . . . . . . . . . . . . . 26
- 5.3.3. Non-Standard Components, Properties, and Parameters . 28
- 5.3.4. Calendar Object Resource Entity Tag . . . . . . . . . 28
- 6. Calendaring Access Control . . . . . . . . . . . . . . . . . . 29
- 6.1. Calendaring Privilege . . . . . . . . . . . . . . . . . . 29
- 6.1.1. CALDAV:read-free-busy Privilege . . . . . . . . . . . 29
- 6.2. Additional Principal Property . . . . . . . . . . . . . . 30
- 6.2.1. CALDAV:calendar-home-set Property . . . . . . . . . . 30
- 7. Calendaring Reports . . . . . . . . . . . . . . . . . . . . . 31
- 7.1. REPORT Method . . . . . . . . . . . . . . . . . . . . . . 31
- 7.2. Ordinary Collections . . . . . . . . . . . . . . . . . . . 31
- 7.3. Date and Floating Time . . . . . . . . . . . . . . . . . . 32
- 7.4. Time Range Filtering . . . . . . . . . . . . . . . . . . . 32
- 7.5. Searching Text: Collations . . . . . . . . . . . . . . . . 33
-
-
-
-Daboo, et al. Standards Track [Page 2]
-
-RFC 4791 CalDAV March 2007
-
-
- 7.5.1. CALDAV:supported-collation-set Property . . . . . . . 34
- 7.6. Partial Retrieval . . . . . . . . . . . . . . . . . . . . 34
- 7.7. Non-Standard Components, Properties, and Parameters . . . 35
- 7.8. CALDAV:calendar-query REPORT . . . . . . . . . . . . . . . 36
- 7.8.1. Example: Partial Retrieval of Events by Time Range . . 38
- 7.8.2. Example: Partial Retrieval of Recurring Events . . . . 42
- 7.8.3. Example: Expanded Retrieval of Recurring Events . . . 45
- 7.8.4. Example: Partial Retrieval of Stored Free Busy
- Components . . . . . . . . . . . . . . . . . . . . . . 48
- 7.8.5. Example: Retrieval of To-Dos by Alarm Time Range . . . 50
- 7.8.6. Example: Retrieval of Event by UID . . . . . . . . . . 51
- 7.8.7. Example: Retrieval of Events by PARTSTAT . . . . . . . 53
- 7.8.8. Example: Retrieval of Events Only . . . . . . . . . . 55
- 7.8.9. Example: Retrieval of All Pending To-Dos . . . . . . . 59
- 7.8.10. Example: Attempt to Query Unsupported Property . . . . 62
- 7.9. CALDAV:calendar-multiget REPORT . . . . . . . . . . . . . 63
- 7.9.1. Example: Successful CALDAV:calendar-multiget REPORT . 64
- 7.10. CALDAV:free-busy-query REPORT . . . . . . . . . . . . . . 66
- 7.10.1. Example: Successful CALDAV:free-busy-query REPORT . . 68
- 8. Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . 69
- 8.1. Client-to-Client Interoperability . . . . . . . . . . . . 69
- 8.2. Synchronization Operations . . . . . . . . . . . . . . . . 69
- 8.2.1. Use of Reports . . . . . . . . . . . . . . . . . . . . 69
- 8.2.1.1. Restrict the Time Range . . . . . . . . . . . . . 69
- 8.2.1.2. Synchronize by Time Range . . . . . . . . . . . . 70
- 8.2.1.3. Synchronization Process . . . . . . . . . . . . . 70
- 8.2.2. Restrict the Properties Returned . . . . . . . . . . . 72
- 8.3. Use of Locking . . . . . . . . . . . . . . . . . . . . . . 72
- 8.4. Finding Calendars . . . . . . . . . . . . . . . . . . . . 72
- 8.5. Storing and Using Attachments . . . . . . . . . . . . . . 74
- 8.5.1. Inline Attachments . . . . . . . . . . . . . . . . . . 74
- 8.5.2. External Attachments . . . . . . . . . . . . . . . . . 75
- 8.6. Storing and Using Alarms . . . . . . . . . . . . . . . . . 76
- 9. XML Element Definitions . . . . . . . . . . . . . . . . . . . 77
- 9.1. CALDAV:calendar XML Element . . . . . . . . . . . . . . . 77
- 9.2. CALDAV:mkcalendar XML Element . . . . . . . . . . . . . . 77
- 9.3. CALDAV:mkcalendar-response XML Element . . . . . . . . . . 78
- 9.4. CALDAV:supported-collation XML Element . . . . . . . . . . 78
- 9.5. CALDAV:calendar-query XML Element . . . . . . . . . . . . 78
- 9.6. CALDAV:calendar-data XML Element . . . . . . . . . . . . . 79
- 9.6.1. CALDAV:comp XML Element . . . . . . . . . . . . . . . 80
- 9.6.2. CALDAV:allcomp XML Element . . . . . . . . . . . . . . 81
- 9.6.3. CALDAV:allprop XML Element . . . . . . . . . . . . . . 81
- 9.6.4. CALDAV:prop XML Element . . . . . . . . . . . . . . . 82
- 9.6.5. CALDAV:expand XML Element . . . . . . . . . . . . . . 82
- 9.6.6. CALDAV:limit-recurrence-set XML Element . . . . . . . 83
- 9.6.7. CALDAV:limit-freebusy-set XML Element . . . . . . . . 84
- 9.7. CALDAV:filter XML Element . . . . . . . . . . . . . . . . 85
-
-
-
-Daboo, et al. Standards Track [Page 3]
-
-RFC 4791 CalDAV March 2007
-
-
- 9.7.1. CALDAV:comp-filter XML Element . . . . . . . . . . . . 85
- 9.7.2. CALDAV:prop-filter XML Element . . . . . . . . . . . . 86
- 9.7.3. CALDAV:param-filter XML Element . . . . . . . . . . . 87
- 9.7.4. CALDAV:is-not-defined XML Element . . . . . . . . . . 88
- 9.7.5. CALDAV:text-match XML Element . . . . . . . . . . . . 88
- 9.8. CALDAV:timezone XML Element . . . . . . . . . . . . . . . 89
- 9.9. CALDAV:time-range XML Element . . . . . . . . . . . . . . 90
- 9.10. CALDAV:calendar-multiget XML Element . . . . . . . . . . . 94
- 9.11. CALDAV:free-busy-query XML Element . . . . . . . . . . . . 95
- 10. Internationalization Considerations . . . . . . . . . . . . . 95
- 11. Security Considerations . . . . . . . . . . . . . . . . . . . 95
- 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 96
- 12.1. Namespace Registration . . . . . . . . . . . . . . . . . . 96
- 13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 96
- 14. References . . . . . . . . . . . . . . . . . . . . . . . . . . 97
- 14.1. Normative References . . . . . . . . . . . . . . . . . . . 97
- 14.2. Informative References . . . . . . . . . . . . . . . . . . 98
- Appendix A. CalDAV Method Privilege Table (Normative) . . . . . . 99
- Appendix B. Calendar Collections Used in the Examples . . . . . . 99
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 4]
-
-RFC 4791 CalDAV March 2007
-
-
-1. Introduction
-
- The concept of using HTTP [RFC2616] and WebDAV [RFC2518] as a basis
- for a calendar access protocol is by no means a new concept: it was
- discussed in the IETF CALSCH working group as early as 1997 or 1998.
- Several companies have implemented calendar access protocols using
- HTTP to upload and download iCalendar [RFC2445] objects, and using
- WebDAV to get listings of resources. However, those implementations
- do not interoperate because there are many small and big decisions to
- be made in how to model calendaring data as WebDAV resources, as well
- as how to implement required features that aren't already part of
- WebDAV. This document proposes a way to model calendar data in
- WebDAV, with additional features to make an interoperable calendar
- access protocol.
-
-1.1. Notational Conventions
-
- 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].
-
- The term "protected" is used in the Conformance field of property
- definitions as defined in Section 1.4.2 of [RFC3253].
-
- 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.
-
-1.2. XML Namespaces and Processing
-
- Definitions of XML elements in this document use XML element type
- declarations (as found in XML Document Type Declarations), described
- in Section 3.2 of [W3C.REC-xml-20060816].
-
- The namespace "urn:ietf:params:xml:ns:caldav" is reserved for the XML
- elements defined in this specification, its revisions, and related
- CalDAV specifications. XML elements defined by individual
- implementations MUST NOT use the "urn:ietf:params:xml:ns:caldav"
- namespace, and instead should use a namespace that they control.
-
- The XML declarations used in this document do not include namespace
- information. Thus, implementers must not use these declarations as
- the only way to create valid CalDAV properties or to validate CalDAV
- XML element types. Some of the declarations refer to XML elements
- defined by WebDAV [RFC2518], which use the "DAV:" namespace.
- Wherever such XML elements appear, they are explicitly prefixed with
- "DAV:" to avoid confusion.
-
-
-
-Daboo, et al. Standards Track [Page 5]
-
-RFC 4791 CalDAV March 2007
-
-
- Also note that some CalDAV XML element names are identical to WebDAV
- XML element names, though their namespace differs. Care must be
- taken not to confuse the two sets of names.
-
- Processing of XML by CalDAV clients and servers MUST follow the rules
- described in [RFC2518]; in particular, Section 14, and Appendix 3 of
- that specification.
-
-1.3. Method Preconditions and Postconditions
-
- A "precondition" of a method describes the state of the server that
- must be true for that method to be performed. A "postcondition" of a
- method describes the state of the server that must be true after that
- method has been completed. If a method precondition or postcondition
- for a request is not satisfied, the response status of the request
- MUST either be 403 (Forbidden), if the request should not be repeated
- because it will always fail, or 409 (Conflict), if it is expected
- that the user might be able to resolve the conflict and resubmit the
- request.
-
- In order to allow better client handling of 403 and 409 responses, a
- distinct XML element type is associated with each method precondition
- and postcondition of a request. When a particular precondition is
- not satisfied or a particular postcondition cannot be achieved, the
- appropriate XML element MUST be returned as the child of a top-level
- DAV:error element in the response body, unless otherwise negotiated
- by the request.
-
-2. Requirements Overview
-
- This section lists what functionality is required of a CalDAV server.
- To advertise support for CalDAV, a server:
-
- o MUST support iCalendar [RFC2445] as a media type for the calendar
- object resource format;
-
- o MUST support WebDAV Class 1 [RFC2518] (note that [rfc2518bis]
- describes clarifications to [RFC2518] that aid interoperability);
-
- o MUST support WebDAV ACL [RFC3744] with the additional privilege
- defined in Section 6.1 of this document;
-
- o MUST support transport over TLS [RFC2246] as defined in [RFC2818]
- (note that [RFC2246] has been obsoleted by [RFC4346]);
-
- o MUST support ETags [RFC2616] with additional requirements
- specified in Section 5.3.4 of this document;
-
-
-
-
-Daboo, et al. Standards Track [Page 6]
-
-RFC 4791 CalDAV March 2007
-
-
- o MUST support all calendaring reports defined in Section 7 of this
- document; and
-
- o MUST advertise support on all calendar collections and calendar
- object resources for the calendaring reports in the DAV:supported-
- report-set property, as defined in Versioning Extensions to WebDAV
- [RFC3253].
-
- In addition, a server:
-
- o SHOULD support the MKCALENDAR method defined in Section 5.3.1 of
- this document.
-
-3. Calendaring Data Model
-
- One of the features that has made WebDAV a successful protocol is its
- firm data model. This makes it a useful framework for other
- applications such as calendaring. This specification follows the
- same pattern by developing all features based on a well-described
- data model.
-
- As a brief overview, a CalDAV calendar is modeled as a WebDAV
- collection with a defined structure; each calendar collection
- contains a number of resources representing calendar objects as its
- direct child resource. Each resource representing a calendar object
- (event, to-do, journal entry, or other calendar components) is called
- a "calendar object resource". Each calendar object resource and each
- calendar collection can be individually locked and have individual
- WebDAV properties. Requirements derived from this model are provided
- in Section 4.1 and Section 4.2.
-
-3.1. Calendar Server
-
- A CalDAV server is a calendaring-aware engine combined with a WebDAV
- repository. A WebDAV repository is a set of WebDAV collections,
- containing other WebDAV resources, within a unified URL namespace.
- For example, the repository "http://www.example.com/webdav/" may
- contain WebDAV collections and resources, all of which have URLs
- beginning with "http://www.example.com/webdav/". Note that the root
- URL, "http://www.example.com/", may not itself be a WebDAV repository
- (for example, if the WebDAV support is implemented through a servlet
- or other Web server extension).
-
- A WebDAV repository MAY include calendar data in some parts of its
- URL namespace, and non-calendaring data in other parts.
-
- A WebDAV repository can advertise itself as a CalDAV server if it
- supports the functionality defined in this specification at any point
-
-
-
-Daboo, et al. Standards Track [Page 7]
-
-RFC 4791 CalDAV March 2007
-
-
- within the root of the repository. That might mean that calendaring
- data is spread throughout the repository and mixed with non-calendar
- data in nearby collections (e.g., calendar data may be found in
- /home/lisa/calendars/ as well as in /home/bernard/calendars/, and
- non-calendar data in /home/lisa/contacts/). Or, it might mean that
- calendar data can be found only in certain sections of the repository
- (e.g., /calendar/). Calendaring features are only required in the
- repository sections that are or contain calendar object resources.
- Therefore, a repository confining calendar data to the /calendar/
- collection would only need to support the CalDAV required features
- within that collection.
-
- The CalDAV server or repository is the canonical location for
- calendar data and state information. Clients may submit requests to
- change data or download data. Clients may store calendar objects
- offline and attempt to synchronize at a later time. However, clients
- MUST be prepared for calendar data on the server to change between
- the time of last synchronization and when attempting an update, as
- calendar collections may be shared and accessible via multiple
- clients. Entity tags and other features make this possible.
-
-3.2. Recurrence and the Data Model
-
- Recurrence is an important part of the data model because it governs
- how many resources are expected to exist. This specification models
- a recurring calendar component and its recurrence exceptions as a
- single resource. In this model, recurrence rules, recurrence dates,
- exception rules, and exception dates are all part of the data in a
- single calendar object resource. This model avoids problems of
- limiting how many recurrence instances to store in the repository,
- how to keep recurrence instances in sync with the recurring calendar
- component, and how to link recurrence exceptions with the recurring
- calendar component. It also results in less data to synchronize
- between client and server, and makes it easier to make changes to all
- recurrence instances or to a recurrence rule. It makes it easier to
- create a recurring calendar component and to delete all recurrence
- instances.
-
- Clients are not forced to retrieve information about all recurrence
- instances of a recurring component. The CALDAV:calendar-query and
- CALDAV:calendar-multiget reports defined in this document allow
- clients to retrieve only recurrence instances that overlap a given
- time range.
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 8]
-
-RFC 4791 CalDAV March 2007
-
-
-4. Calendar Resources
-
-4.1. Calendar Object Resources
-
- Calendar object resources contained in calendar collections MUST NOT
- contain more than one type of calendar component (e.g., VEVENT,
- VTODO, VJOURNAL, VFREEBUSY, etc.) with the exception of VTIMEZONE
- components, which MUST be specified for each unique TZID parameter
- value specified in the iCalendar object. For instance, a calendar
- object resource can contain one VEVENT component and one VTIMEZONE
- component, but it cannot contain one VEVENT component and one VTODO
- component. Instead, the VEVENT and VTODO components would have to be
- stored in separate calendar object resources in the same collection.
-
- Calendar object resources contained in calendar collections MUST NOT
- specify the iCalendar METHOD property.
-
- The UID property value of the calendar components contained in a
- calendar object resource MUST be unique in the scope of the calendar
- collection in which they are stored.
-
- Calendar components in a calendar collection that have different UID
- property values MUST be stored in separate calendar object resources.
-
- Calendar components with the same UID property value, in a given
- calendar collection, MUST be contained in the same calendar object
- resource. This ensures that all components in a recurrence "set" are
- contained in the same calendar object resource. It is possible for a
- calendar object resource to just contain components that represent
- "overridden" instances (ones that modify the behavior of a regular
- instance, and thus include a RECURRENCE-ID property) without also
- including the "master" recurring component (the one that defines the
- recurrence "set" and does not contain any RECURRENCE-ID property).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 9]
-
-RFC 4791 CalDAV March 2007
-
-
- For example, given the following iCalendar object:
-
- BEGIN:VCALENDAR
- PRODID:-//Example Corp.//CalDAV Client//EN
- VERSION:2.0
- BEGIN:VEVENT
- UID:1@example.com
- SUMMARY:One-off Meeting
- DTSTAMP:20041210T183904Z
- DTSTART:20041207T120000Z
- DTEND:20041207T130000Z
- END:VEVENT
- BEGIN:VEVENT
- UID:2@example.com
- SUMMARY:Weekly Meeting
- DTSTAMP:20041210T183838Z
- DTSTART:20041206T120000Z
- DTEND:20041206T130000Z
- RRULE:FREQ=WEEKLY
- END:VEVENT
- BEGIN:VEVENT
- UID:2@example.com
- SUMMARY:Weekly Meeting
- RECURRENCE-ID:20041213T120000Z
- DTSTAMP:20041210T183838Z
- DTSTART:20041213T130000Z
- DTEND:20041213T140000Z
- END:VEVENT
- END:VCALENDAR
-
- The VEVENT component with the UID value "1@example.com" would be
- stored in its own calendar object resource. The two VEVENT
- components with the UID value "2@example.com", which represent a
- recurring event where one recurrence instance has been overridden,
- would be stored in the same calendar object resource.
-
-4.2. Calendar Collection
-
- A calendar collection contains calendar object resources that
- represent calendar components within a calendar. A calendar
- collection is manifested to clients as a WebDAV resource collection
- identified by a URL. A calendar collection MUST report the DAV:
- collection and CALDAV:calendar XML elements in the value of the DAV:
- resourcetype property. The element type declaration for CALDAV:
- calendar is:
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 10]
-
-RFC 4791 CalDAV March 2007
-
-
- A calendar collection can be created through provisioning (i.e.,
- automatically created when a user's account is provisioned), or it
- can be created with the MKCALENDAR method (see Section 5.3.1). This
- method can be useful for a user to create additional calendars (e.g.,
- soccer schedule) or for users to share a calendar (e.g., team events
- or conference rooms). However, note that this document doesn't
- define the purpose of extra calendar collections. Users must rely on
- non-standard cues to find out what a calendar collection is for, or
- use the CALDAV:calendar-description property defined in Section 5.2.1
- to provide such a cue.
-
- The following restrictions are applied to the resources within a
- calendar collection:
-
- a. Calendar collections MUST only contain calendar object resources
- and collections that are not calendar collections, i.e., the only
- "top-level" non-collection resources allowed in a calendar
- collection are calendar object resources. This ensures that
- calendar clients do not have to deal with non-calendar data in a
- calendar collection, though they do have to distinguish between
- calendar object resources and collections when using standard
- WebDAV techniques to examine the contents of a collection.
-
- b. Collections contained in calendar collections MUST NOT contain
- calendar collections at any depth, i.e., "nesting" of calendar
- collections within other calendar collections at any depth is not
- allowed. This specification does not define how collections
- contained in a calendar collection are used or how they relate to
- any calendar object resources contained in the calendar
- collection.
-
- Multiple calendar collections MAY be children of the same collection.
-
-5. Calendar Access Feature
-
-5.1. Calendar Access Support
-
- A server supporting the features described in this document MUST
- include "calendar-access" as a field in the DAV response header from
- an OPTIONS request on any resource that supports any calendar
- properties, reports, method, or privilege. A value of "calendar-
- access" in the DAV response header MUST indicate that the server
- supports all MUST level requirements specified in this document.
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 11]
-
-RFC 4791 CalDAV March 2007
-
-
-5.1.1. Example: Using OPTIONS for the Discovery of Calendar Access
- Support
-
- >> Request <<
-
- OPTIONS /home/bernard/calendars/ HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
- Allow: PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
- DAV: 1, 2, access-control, calendar-access
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Length: 0
-
- In this example, the OPTIONS method returns the value "calendar-
- access" in the DAV response header to indicate that the collection
- "/home/bernard/calendars/" supports the properties, reports, method,
- or privilege defined in this specification.
-
-5.2. Calendar Collection Properties
-
- This section defines properties for calendar collections.
-
-5.2.1. CALDAV:calendar-description Property
-
- Name: calendar-description
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a human-readable description of the calendar
- collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MAY be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]). An xml:lang attribute indicating the human
- language of the description SHOULD be set for this property by
- clients or through server provisioning. Servers MUST return any
- xml:lang attribute if set for the property.
-
- Description: If present, the property contains a description of the
- calendar collection that is suitable for presentation to a user.
- If not present, the client should assume no description for the
- calendar collection.
-
-
-
-
-Daboo, et al. Standards Track [Page 12]
-
-RFC 4791 CalDAV March 2007
-
-
- Definition:
-
-
- PCDATA value: string
-
- Example:
-
- Calendrier de Mathilde Desruisseaux
-
-5.2.2. CALDAV:calendar-timezone Property
-
- Name: calendar-timezone
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a time zone on a calendar collection.
-
- Conformance: This property SHOULD be defined on all calendar
- collections. If defined, it SHOULD NOT be returned by a PROPFIND
- DAV:allprop request (as defined in Section 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:calendar-timezone property is used to
- specify the time zone the server should rely on to resolve "date"
- values and "date with local time" values (i.e., floating time) to
- "date with UTC time" values. The server will require this
- information to determine if a calendar component scheduled with
- "date" values or "date with local time" values overlaps a CALDAV:
- time-range specified in a CALDAV:calendar-query REPORT. The
- server will also require this information to compute the proper
- FREEBUSY time period as "date with UTC time" in the VFREEBUSY
- component returned in a response to a CALDAV:free-busy-query
- REPORT request that takes into account calendar components
- scheduled with "date" values or "date with local time" values. In
- the absence of this property, the server MAY rely on the time zone
- of their choice.
-
- Note: The iCalendar data embedded within the CALDAV:calendar-
- timezone XML element MUST follow the standard XML character data
- encoding rules, including use of <, >, & etc. entity
- encoding or the use of a construct. In the
- later case, the iCalendar data cannot contain the character
- sequence "]]>", which is the end delimiter for the CDATA section.
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 13]
-
-RFC 4791 CalDAV March 2007
-
-
- Definition:
-
-
- PCDATA value: an iCalendar object with exactly one VTIMEZONE
- component.
-
- Example:
-
- BEGIN:VCALENDAR
- PRODID:-//Example Corp.//CalDAV Client//EN
- VERSION:2.0
- BEGIN:VTIMEZONE
- TZID:US-Eastern
- LAST-MODIFIED:19870101T000000Z
- BEGIN:STANDARD
- DTSTART:19671029T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- TZNAME:Eastern Standard Time (US & Canada)
- END:STANDARD
- BEGIN:DAYLIGHT
- DTSTART:19870405T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- TZNAME:Eastern Daylight Time (US & Canada)
- END:DAYLIGHT
- END:VTIMEZONE
- END:VCALENDAR
-
-
-5.2.3. CALDAV:supported-calendar-component-set Property
-
- Name: supported-calendar-component-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies the calendar component types (e.g., VEVENT,
- VTODO, etc.) that calendar object resources can contain in the
- calendar collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
-
-
-
-Daboo, et al. Standards Track [Page 14]
-
-RFC 4791 CalDAV March 2007
-
-
- Description: The CALDAV:supported-calendar-component-set property is
- used to specify restrictions on the calendar component types that
- calendar object resources may contain in a calendar collection.
- Any attempt by the client to store calendar object resources with
- component types not listed in this property, if it exists, MUST
- result in an error, with the CALDAV:supported-calendar-component
- precondition (Section 5.3.2.1) being violated. Since this
- property is protected, it cannot be changed by clients using a
- PROPPATCH request. However, clients can initialize the value of
- this property when creating a new calendar collection with
- MKCALENDAR. The empty-element tag MUST
- only be specified if support for calendar object resources that
- only contain VTIMEZONE components is provided or desired. Support
- for VTIMEZONE components in calendar object resources that contain
- VEVENT or VTODO components is always assumed. In the absence of
- this property, the server MUST accept all component types, and the
- client can assume that all component types are accepted.
-
- Definition:
-
-
-
- Example:
-
-
-
-
-
-
-5.2.4. CALDAV:supported-calendar-data Property
-
- Name: supported-calendar-data
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies what media types are allowed for calendar object
- resources in a calendar collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:supported-calendar-data property is used to
- specify the media type supported for the calendar object resources
- contained in a given calendar collection (e.g., iCalendar version
- 2.0). Any attempt by the client to store calendar object
-
-
-
-Daboo, et al. Standards Track [Page 15]
-
-RFC 4791 CalDAV March 2007
-
-
- resources with a media type not listed in this property MUST
- result in an error, with the CALDAV:supported-calendar-data
- precondition (Section 5.3.2.1) being violated. In the absence of
- this property, the server MUST only accept data with the media
- type "text/calendar" and iCalendar version 2.0, and clients can
- assume that the server will only accept this data.
-
- Definition:
-
-
-
- Example:
-
-
-
-
-
-5.2.5. CALDAV:max-resource-size Property
-
- Name: max-resource-size
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a numeric value indicating the maximum size of a
- resource in octets that the server is willing to accept when a
- calendar object resource is stored in a calendar collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:max-resource-size is used to specify a
- numeric value that represents the maximum size in octets that the
- server is willing to accept when a calendar object resource is
- stored in a calendar collection. Any attempt to store a calendar
- object resource exceeding this size MUST result in an error, with
- the CALDAV:max-resource-size precondition (Section 5.3.2.1) being
- violated. In the absence of this property, the client can assume
- that the server will allow storing a resource of any reasonable
- size.
-
- Definition:
-
-
- PCDATA value: a numeric value (positive integer)
-
-
-
-
-Daboo, et al. Standards Track [Page 16]
-
-RFC 4791 CalDAV March 2007
-
-
- Example:
-
- 102400
-
-5.2.6. CALDAV:min-date-time Property
-
- Name: min-date-time
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a DATE-TIME value indicating the earliest date and
- time (in UTC) that the server is willing to accept for any DATE or
- DATE-TIME value in a calendar object resource stored in a calendar
- collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:min-date-time is used to specify an
- iCalendar DATE-TIME value in UTC that indicates the earliest
- inclusive date that the server is willing to accept for any
- explicit DATE or DATE-TIME value in a calendar object resource
- stored in a calendar collection. Any attempt to store a calendar
- object resource using a DATE or DATE-TIME value earlier than this
- value MUST result in an error, with the CALDAV:min-date-time
- precondition (Section 5.3.2.1) being violated. Note that servers
- MUST accept recurring components that specify instances beyond
- this limit, provided none of those instances have been overridden.
- In that case, the server MAY simply ignore those instances outside
- of the acceptable range when processing reports on the calendar
- object resource. In the absence of this property, the client can
- assume any valid iCalendar date may be used at least up to the
- CALDAV:max-date-time value, if that is defined.
-
- Definition:
-
-
- PCDATA value: an iCalendar format DATE-TIME value in UTC
-
- Example:
-
- 19000101T000000Z
-
-
-
-
-
-Daboo, et al. Standards Track [Page 17]
-
-RFC 4791 CalDAV March 2007
-
-
-5.2.7. CALDAV:max-date-time Property
-
- Name: max-date-time
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a DATE-TIME value indicating the latest date and
- time (in UTC) that the server is willing to accept for any DATE or
- DATE-TIME value in a calendar object resource stored in a calendar
- collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:max-date-time is used to specify an
- iCalendar DATE-TIME value in UTC that indicates the inclusive
- latest date that the server is willing to accept for any date or
- time value in a calendar object resource stored in a calendar
- collection. Any attempt to store a calendar object resource using
- a DATE or DATE-TIME value later than this value MUST result in an
- error, with the CALDAV:max-date-time precondition
- (Section 5.3.2.1) being violated. Note that servers MUST accept
- recurring components that specify instances beyond this limit,
- provided none of those instances have been overridden. In that
- case, the server MAY simply ignore those instances outside of the
- acceptable range when processing reports on the calendar object
- resource. In the absence of this property, the client can assume
- any valid iCalendar date may be used at least down to the CALDAV:
- min-date-time value, if that is defined.
-
- Definition:
-
-
- PCDATA value: an iCalendar format DATE-TIME value in UTC
-
- Example:
-
- 20491231T235959Z
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 18]
-
-RFC 4791 CalDAV March 2007
-
-
-5.2.8. CALDAV:max-instances Property
-
- Name: max-instances
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a numeric value indicating the maximum number of
- recurrence instances that a calendar object resource stored in a
- calendar collection can generate.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:max-instances is used to specify a numeric
- value that indicates the maximum number of recurrence instances
- that a calendar object resource stored in a calendar collection
- can generate. Any attempt to store a calendar object resource
- with a recurrence pattern that generates more instances than this
- value MUST result in an error, with the CALDAV:max-instances
- precondition (Section 5.3.2.1) being violated. In the absence of
- this property, the client can assume that the server has no limits
- on the number of recurrence instances it can handle or expand.
-
- Definition:
-
-
- PCDATA value: a numeric value (integer greater than zero)
-
- Example:
-
- 100
-
-5.2.9. CALDAV:max-attendees-per-instance Property
-
- Name: max-attendees-per-instance
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Provides a numeric value indicating the maximum number of
- ATTENDEE properties in any instance of a calendar object resource
- stored in a calendar collection.
-
- Conformance: This property MAY be defined on any calendar
- collection. If defined, it MUST be protected and SHOULD NOT be
-
-
-
-
-Daboo, et al. Standards Track [Page 19]
-
-RFC 4791 CalDAV March 2007
-
-
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:max-attendees-per-instance is used to
- specify a numeric value that indicates the maximum number of
- iCalendar ATTENDEE properties on any one instance of a calendar
- object resource stored in a calendar collection. Any attempt to
- store a calendar object resource with more ATTENDEE properties per
- instance than this value MUST result in an error, with the CALDAV:
- max-attendees-per-instance precondition (Section 5.3.2.1) being
- violated. In the absence of this property, the client can assume
- that the server can handle any number of ATTENDEE properties in a
- calendar component.
-
- Definition:
-
-
- PCDATA value: a numeric value (integer greater than zero)
-
- Example:
-
- 25
-
-5.2.10. Additional Precondition for PROPPATCH
-
- This specification requires an additional Precondition for the
- PROPPATCH method. The precondition is:
-
- (CALDAV:valid-calendar-data): The time zone specified in CALDAV:
- calendar-timezone property MUST be a valid iCalendar object
- containing a single valid VTIMEZONE component.
-
-5.3. Creating Resources
-
- Calendar collections and calendar object resources may be created by
- either a CalDAV client or by the CalDAV server. This specification
- defines restrictions and a data model that both clients and servers
- MUST adhere to when manipulating such calendar data.
-
-5.3.1. MKCALENDAR Method
-
- An HTTP request using the MKCALENDAR method creates a new calendar
- collection resource. A server MAY restrict calendar collection
- creation to particular collections.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 20]
-
-RFC 4791 CalDAV March 2007
-
-
- Support for MKCALENDAR on the server is only RECOMMENDED and not
- REQUIRED because some calendar stores only support one calendar per
- user (or principal), and those are typically pre-created for each
- account. However, servers and clients are strongly encouraged to
- support MKCALENDAR whenever possible to allow users to create
- multiple calendar collections to help organize their data better.
-
- Clients SHOULD use the DAV:displayname property for a human-readable
- name of the calendar. Clients can either specify the value of the
- DAV:displayname property in the request body of the MKCALENDAR
- request, or alternatively issue a PROPPATCH request to change the
- DAV:displayname property to the appropriate value immediately after
- issuing the MKCALENDAR request. Clients SHOULD NOT set the DAV:
- displayname property to be the same as any other calendar collection
- at the same URI "level". When displaying calendar collections to
- users, clients SHOULD check the DAV:displayname property and use that
- value as the name of the calendar. In the event that the DAV:
- displayname property is empty, the client MAY use the last part of
- the calendar collection URI as the name; however, that path segment
- may be "opaque" and not represent any meaningful human-readable text.
-
- If a MKCALENDAR request fails, the server state preceding the request
- MUST be restored.
-
- Marshalling:
- If a request body is included, it MUST be a CALDAV:mkcalendar XML
- element. Instruction processing MUST occur in the order
- instructions are received (i.e., from top to bottom).
- Instructions MUST either all be executed or none executed. Thus,
- if any error occurs during processing, all executed instructions
- MUST be undone and a proper error result returned. Instruction
- processing details can be found in the definition of the DAV:set
- instruction in Section 12.13.2 of [RFC2518].
-
-
-
- If a response body for a successful request is included, it MUST
- be a CALDAV:mkcalendar-response XML element.
-
-
-
- The response MUST include a Cache-Control:no-cache header.
-
- Preconditions:
-
- (DAV:resource-must-be-null): A resource MUST NOT exist at the
- Request-URI;
-
-
-
-
-Daboo, et al. Standards Track [Page 21]
-
-RFC 4791 CalDAV March 2007
-
-
- (CALDAV:calendar-collection-location-ok): The Request-URI MUST
- identify a location where a calendar collection can be created;
-
- (CALDAV:valid-calendar-data): The time zone specified in the
- CALDAV:calendar-timezone property MUST be a valid iCalendar object
- containing a single valid VTIMEZONE component;
-
- (DAV:needs-privilege): The DAV:bind privilege MUST be granted to
- the current user on the parent collection of the Request-URI.
-
- Postconditions:
-
- (CALDAV:initialize-calendar-collection): A new calendar collection
- exists at the Request-URI. The DAV:resourcetype of the calendar
- collection MUST contain both DAV:collection and CALDAV:calendar
- XML elements.
-
-5.3.1.1. Status Codes
-
- The following are examples of response codes one would expect to get
- in a response to a MKCALENDAR request. Note that this list is by no
- means exhaustive.
-
- 201 (Created) - The calendar collection resource was created in
- its entirety;
-
- 207 (Multi-Status) - The calendar collection resource was not
- created since one or more DAV:set instructions specified in the
- request body could not be processed successfully. The following
- are examples of response codes one would expect to be used in a
- 207 (Multi-Status) response in this situation:
-
- 403 (Forbidden) - The client, for reasons the server chooses
- not to specify, cannot alter one of the properties;
-
- 409 (Conflict) - The client has provided a value whose
- semantics are not appropriate for the property. This includes
- trying to set read-only properties;
-
- 424 (Failed Dependency) - The DAV:set instruction on the
- specified resource would have succeeded if it were not for the
- failure of another DAV:set instruction specified in the request
- body;
-
- 423 (Locked) - The specified resource is locked and the client
- either is not a lock owner or the lock type requires a lock
- token to be submitted and the client did not submit it; and
-
-
-
-
-Daboo, et al. Standards Track [Page 22]
-
-RFC 4791 CalDAV March 2007
-
-
- 507 (Insufficient Storage) - The server did not have sufficient
- space to record the property;
-
- 403 (Forbidden) - This indicates at least one of two conditions:
- 1) the server does not allow the creation of calendar collections
- at the given location in its namespace, or 2) the parent
- collection of the Request-URI exists but cannot accept members;
-
- 409 (Conflict) - A collection cannot be made at the Request-URI
- until one or more intermediate collections have been created;
-
- 415 (Unsupported Media Type) - The server does not support the
- request type of the body; and
-
- 507 (Insufficient Storage) - The resource does not have sufficient
- space to record the state of the resource after the execution of
- this method.
-
-5.3.1.2. Example: Successful MKCALENDAR Request
-
- This example creates a calendar collection called /home/lisa/
- calendars/events/ on the server cal.example.com with specific values
- for the properties DAV:displayname, CALDAV:calendar-description,
- CALDAV:supported-calendar-component-set, and CALDAV:calendar-
- timezone.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 23]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- MKCALENDAR /home/lisa/calendars/events/ HTTP/1.1
- Host: cal.example.com
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
- Lisa's Events
- Calendar restricted to events.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 24]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Response <<
-
- HTTP/1.1 201 Created
- Cache-Control: no-cache
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Length: 0
-
-5.3.2. Creating Calendar Object Resources
-
- Clients populate calendar collections with calendar object resources.
- The URL for each calendar object resource is entirely arbitrary and
- does not need to bear a specific relationship to the calendar object
- resource's iCalendar properties or other metadata. New calendar
- object resources MUST be created with a PUT request targeted at an
- unmapped URI. A PUT request targeted at a mapped URI updates an
- existing calendar object resource.
-
- When servers create new resources, it's not hard for the server to
- choose an unmapped URI. It's slightly tougher for clients, because a
- client might not want to examine all resources in the collection and
- might not want to lock the entire collection to ensure that a new
- resource isn't created with a name collision. However, there is an
- HTTP feature to mitigate this. If the client intends to create a new
- non-collection resource, such as a new VEVENT, the client SHOULD use
- the HTTP request header "If-None-Match: *" on the PUT request. The
- Request-URI on the PUT request MUST include the target collection,
- where the resource is to be created, plus the name of the resource in
- the last path segment. The "If-None-Match: *" request header ensures
- that the client will not inadvertently overwrite an existing resource
- if the last path segment turned out to already be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 25]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- PUT /home/lisa/calendars/events/qwue23489.ics HTTP/1.1
- If-None-Match: *
- Host: cal.example.com
- Content-Type: text/calendar
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- UID:20010712T182145Z-123401@example.com
- DTSTAMP:20060712T182145Z
- DTSTART:20060714T170000Z
- DTEND:20060715T040000Z
- SUMMARY:Bastille Day Party
- END:VEVENT
- END:VCALENDAR
-
- >> Response <<
-
- HTTP/1.1 201 Created
- Content-Length: 0
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- ETag: "123456789-000-111"
-
- The request to change an existing event is the same, but with a
- specific ETag in the "If-Match" header, rather than the "If-None-
- Match" header.
-
- As indicated in Section 3.10 of [RFC2445], the URL of calendar object
- resources containing (an arbitrary set of) calendaring and scheduling
- information may be suffixed by ".ics", and the URL of calendar object
- resources containing free or busy time information may be suffixed by
- ".ifb".
-
-5.3.2.1. Additional Preconditions for PUT, COPY, and MOVE
-
- This specification creates additional Preconditions for PUT, COPY,
- and MOVE methods. These preconditions apply when a PUT operation of
- a calendar object resource into a calendar collection occurs, or when
- a COPY or MOVE operation of a calendar object resource into a
- calendar collection occurs, or when a COPY or MOVE operation occurs
- on a calendar collection.
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 26]
-
-RFC 4791 CalDAV March 2007
-
-
- The new preconditions are:
-
- (CALDAV:supported-calendar-data): The resource submitted in the
- PUT request, or targeted by a COPY or MOVE request, MUST be a
- supported media type (i.e., iCalendar) for calendar object
- resources;
-
- (CALDAV:valid-calendar-data): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST be valid data
- for the media type being specified (i.e., MUST contain valid
- iCalendar data);
-
- (CALDAV:valid-calendar-object-resource): The resource submitted in
- the PUT request, or targeted by a COPY or MOVE request, MUST obey
- all restrictions specified in Section 4.1 (e.g., calendar object
- resources MUST NOT contain more than one type of calendar
- component, calendar object resources MUST NOT specify the
- iCalendar METHOD property, etc.);
-
- (CALDAV:supported-calendar-component): The resource submitted in
- the PUT request, or targeted by a COPY or MOVE request, MUST
- contain a type of calendar component that is supported in the
- targeted calendar collection;
-
- (CALDAV:no-uid-conflict): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST NOT specify
- an iCalendar UID property value already in use in the targeted
- calendar collection or overwrite an existing calendar object
- resource with one that has a different UID property value.
- Servers SHOULD report the URL of the resource that is already
- making use of the same UID property value in the DAV:href element;
-
-
-
- (CALDAV:calendar-collection-location-ok): In a COPY or MOVE
- request, when the Request-URI is a calendar collection, the
- Destination-URI MUST identify a location where a calendar
- collection can be created;
-
- (CALDAV:max-resource-size): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST have an octet
- size less than or equal to the value of the CALDAV:max-resource-
- size property value (Section 5.2.5) on the calendar collection
- where the resource will be stored;
-
- (CALDAV:min-date-time): The resource submitted in the PUT request,
- or targeted by a COPY or MOVE request, MUST have all of its
- iCalendar DATE or DATE-TIME property values (for each recurring
-
-
-
-Daboo, et al. Standards Track [Page 27]
-
-RFC 4791 CalDAV March 2007
-
-
- instance) greater than or equal to the value of the CALDAV:min-
- date-time property value (Section 5.2.6) on the calendar
- collection where the resource will be stored;
-
- (CALDAV:max-date-time): The resource submitted in the PUT request,
- or targeted by a COPY or MOVE request, MUST have all of its
- iCalendar DATE or DATE-TIME property values (for each recurring
- instance) less than the value of the CALDAV:max-date-time property
- value (Section 5.2.7) on the calendar collection where the
- resource will be stored;
-
- (CALDAV:max-instances): The resource submitted in the PUT request,
- or targeted by a COPY or MOVE request, MUST generate a number of
- recurring instances less than or equal to the value of the CALDAV:
- max-instances property value (Section 5.2.8) on the calendar
- collection where the resource will be stored;
-
- (CALDAV:max-attendees-per-instance): The resource submitted in the
- PUT request, or targeted by a COPY or MOVE request, MUST have a
- number of ATTENDEE properties on any one instance less than or
- equal to the value of the CALDAV:max-attendees-per-instance
- property value (Section 5.2.9) on the calendar collection where
- the resource will be stored;
-
-5.3.3. Non-Standard Components, Properties, and Parameters
-
- iCalendar provides a "standard mechanism for doing non-standard
- things". This extension support allows implementers to make use of
- non-standard components, properties, and parameters whose names are
- prefixed with the text "X-".
-
- Servers MUST support the use of non-standard components, properties,
- and parameters in calendar object resources stored via the PUT
- method.
-
- Servers may need to enforce rules for their own "private" components,
- properties, or parameters, so servers MAY reject any attempt by the
- client to change those or use values for those outside of any
- restrictions the server may have. Servers SHOULD ensure that any
- "private" components, properties, or parameters it uses follow the
- convention of including a vendor id in the "X-" name, as described in
- Section 4.2 of [RFC2445], e.g., "X-ABC-PRIVATE".
-
-5.3.4. Calendar Object Resource Entity Tag
-
- The DAV:getetag property MUST be defined and set to a strong entity
- tag on all calendar object resources.
-
-
-
-
-Daboo, et al. Standards Track [Page 28]
-
-RFC 4791 CalDAV March 2007
-
-
- A response to a GET request targeted at a calendar object resource
- MUST contain an ETag response header field indicating the current
- value of the strong entity tag of the calendar object resource.
-
- Servers SHOULD return a strong entity tag (ETag header) in a PUT
- response when the stored calendar object resource is equivalent by
- octet equality to the calendar object resource submitted in the body
- of the PUT request. This allows clients to reliably use the returned
- strong entity tag for data synchronization purposes. For instance,
- the client can do a PROPFIND request on the stored calendar object
- resource and have the DAV:getetag property returned, and compare that
- value with the strong entity tag it received on the PUT response, and
- know that if they are equal, then the calendar object resource on the
- server has not been changed.
-
- In the case where the data stored by a server as a result of a PUT
- request is not equivalent by octet equality to the submitted calendar
- object resource, the behavior of the ETag response header is not
- specified here, with the exception that a strong entity tag MUST NOT
- be returned in the response. As a result, clients may need to
- retrieve the modified calendar object resource (and ETag) as a basis
- for further changes, rather than use the calendar object resource it
- had sent with the PUT request.
-
-6. Calendaring Access Control
-
-6.1. Calendaring Privilege
-
- CalDAV servers MUST support and adhere to the requirements of WebDAV
- ACL [RFC3744]. WebDAV ACL provides a framework for an extensible set
- of privileges that can be applied to WebDAV collections and ordinary
- resources. CalDAV servers MUST also support the calendaring
- privilege defined in this section.
-
-6.1.1. CALDAV:read-free-busy Privilege
-
- Calendar users often wish to allow other users to see their busy time
- information, without viewing the other details of the calendar
- components (e.g., location, summary, attendees). This allows a
- significant amount of privacy while still allowing other users to
- schedule meetings at times when the user is likely to be free.
-
- The CALDAV:read-free-busy privilege controls which calendar
- collections, regular collections, and calendar object resources are
- examined when a CALDAV:free-busy-query REPORT request is processed
- (see Section 7.10). This privilege can be granted on calendar
- collections, regular collections, or calendar object resources.
-
-
-
-
-Daboo, et al. Standards Track [Page 29]
-
-RFC 4791 CalDAV March 2007
-
-
- Servers MUST support this privilege on all calendar collections,
- regular collections, and calendar object resources.
-
-
-
-
- The CALDAV:read-free-busy privilege MUST be aggregated in the DAV:
- read privilege. Servers MUST allow the CALDAV:read-free-busy to be
- granted without the DAV:read privilege being granted.
-
- Clients should note that when only the CALDAV:read-free-busy
- privilege has been granted on a resource, access to GET, HEAD,
- OPTIONS, and PROPFIND on the resource is not implied (those
- operations are governed by the DAV:read privilege).
-
-6.2. Additional Principal Property
-
- This section defines an additional property for WebDAV principal
- resources, as defined in [RFC3744].
-
-6.2.1. CALDAV:calendar-home-set Property
-
- Name: calendar-home-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identifies the URL of any WebDAV collections that contain
- calendar collections owned by the associated principal resource.
-
- Conformance: This property SHOULD be defined on a principal
- resource. If defined, it MAY be protected and SHOULD NOT be
- returned by a PROPFIND DAV:allprop request (as defined in Section
- 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:calendar-home-set property is meant to allow
- users to easily find the calendar collections owned by the
- principal. Typically, users will group all the calendar
- collections that they own under a common collection. This
- property specifies the URL of collections that are either calendar
- collections or ordinary collections that have child or descendant
- calendar collections owned by the principal.
-
- Definition:
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 30]
-
-RFC 4791 CalDAV March 2007
-
-
- Example:
-
-
- http://cal.example.com/home/bernard/calendars/
-
-
-7. Calendaring Reports
-
- This section defines the reports that CalDAV servers MUST support on
- calendar collections and calendar object resources.
-
- CalDAV servers MUST advertise support for these reports on all
- calendar collections and calendar object resources with the DAV:
- supported-report-set property, defined in Section 3.1.5 of [RFC3253].
- CalDAV servers MAY also advertise support for these reports on
- ordinary collections.
-
- Some of these reports allow calendar data (from possibly multiple
- resources) to be returned.
-
-7.1. REPORT Method
-
- The REPORT method (defined in Section 3.6 of [RFC3253]) provides an
- extensible mechanism for obtaining information about one or more
- resources. Unlike the PROPFIND method, which returns the value of
- one or more named properties, the REPORT method can involve more
- complex processing. REPORT is valuable in cases where the server has
- access to all of the information needed to perform the complex
- request (such as a query), and where it would require multiple
- requests for the client to retrieve the information needed to perform
- the same request.
-
- CalDAV servers MUST support the DAV:expand-property REPORT defined in
- Section 3.8 of [RFC3253].
-
-7.2. Ordinary Collections
-
- Servers MAY support the reports defined in this document on ordinary
- collections (collections that are not calendar collections), in
- addition to calendar collections or calendar object resources. In
- computing responses to the reports on ordinary collections, servers
- MUST only consider calendar object resources contained in calendar
- collections that are targeted by the REPORT request, based on the
- value of the Depth request header.
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 31]
-
-RFC 4791 CalDAV March 2007
-
-
-7.3. Date and Floating Time
-
- iCalendar provides a way to specify DATE and DATE-TIME values that
- are not bound to any time zone in particular, hereafter called
- "floating date" and "floating time", respectively. These values are
- used to represent the same day, hour, minute, and second value,
- regardless of which time zone is being observed. For instance, the
- DATE value "20051111", represents November 11, 2005 in no specific
- time zone, while the DATE-TIME value "20051111T111100" represents
- November 11, 2005, at 11:11 A.M. in no specific time zone.
-
- CalDAV servers may need to convert "floating date" and "floating
- time" values in date with UTC time values in the processing of
- calendaring REPORT requests.
-
- For the CALDAV:calendar-query REPORT, CalDAV servers MUST rely on the
- value of the CALDAV:timezone XML element, if specified as part of the
- request body, to perform the proper conversion of "floating date" and
- "floating time" values to date with UTC time values. If the CALDAV:
- timezone XML element is not specified in the request body, CalDAV
- servers MUST rely on the value of the CALDAV:calendar-timezone
- property, if defined, or else the CalDAV servers MAY rely on the time
- zone of their choice.
-
- For the CALDAV:free-busy-query REPORT, CalDAV servers MUST rely on
- the value of the CALDAV:calendar-timezone property, if defined, to
- compute the proper FREEBUSY time period value as date with UTC time
- for calendar components scheduled with "floating date" or "floating
- time". If the CALDAV:calendar-timezone property is not defined,
- CalDAV servers MAY rely on the time zone of their choice.
-
-7.4. Time Range Filtering
-
- Some of the reports defined in this section can include a time range
- filter that is used to restrict the set of calendar object resources
- returned to just those that overlap the specified time range. The
- time range filter can be applied to a calendar component as a whole,
- or to specific calendar component properties with DATE or DATE-TIME
- value types.
-
- To determine whether a calendar object resource matches the time
- range filter element, the start and end times for the targeted
- component or property are determined and then compared to the
- requested time range. If there is an overlap with the requested time
- range, then the calendar object resource matches the filter element.
- The rules defined in [RFC2445] for determining the actual start and
- end times of calendar components MUST be used, and these are fully
- enumerated in Section 9.9 of this document.
-
-
-
-Daboo, et al. Standards Track [Page 32]
-
-RFC 4791 CalDAV March 2007
-
-
- When such time range filtering is used, special consideration must be
- given to recurring calendar components, such as VEVENT and VTODO.
- The server MUST expand recurring components to determine whether any
- recurrence instances overlap the specified time range. If one or
- more recurrence instances overlap the time range, then the calendar
- object resource matches the filter element.
-
-7.5. Searching Text: Collations
-
- Some of the reports defined in this section do text matches of
- character strings provided by the client and are compared to stored
- calendar data. Since iCalendar data is, by default, encoded in the
- UTF-8 charset and may include characters outside the US-ASCII charset
- range in some property and parameter values, there is a need to
- ensure that text matching follows well-defined rules.
-
- To deal with this, this specification makes use of the IANA Collation
- Registry defined in [RFC4790] to specify collations that may be used
- to carry out the text comparison operations with a well-defined rule.
-
- The comparisons used in CalDAV are all "substring" matches, as per
- [RFC4790], Section 4.2. Collations supported by the server MUST
- support "substring" match operations.
-
- CalDAV servers are REQUIRED to support the "i;ascii-casemap" and
- "i;octet" collations, as described in [RFC4790], and MAY support
- other collations.
-
- Servers MUST advertise the set of collations that they support via
- the CALDAV:supported-collation-set property defined on any resource
- that supports reports that use collations.
-
- Clients MUST only use collations from the list advertised by the
- server.
-
- In the absence of a collation explicitly specified by the client, or
- if the client specifies the "default" collation identifier (as
- defined in [RFC4790], Section 3.1), the server MUST default to using
- "i;ascii-casemap" as the collation.
-
- Wildcards (as defined in [RFC4790], Section 3.2) MUST NOT be used in
- the collation identifier.
-
- If the client chooses a collation not supported by the server, the
- server MUST respond with a CALDAV:supported-collation precondition
- error response.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 33]
-
-RFC 4791 CalDAV March 2007
-
-
-7.5.1. CALDAV:supported-collation-set Property
-
- Name: supported-collation-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identifies the set of collations supported by the server
- for text matching operations.
-
- Conformance: This property MUST be defined on any resource that
- supports a report that does text matching. If defined, it MUST be
- protected and SHOULD NOT be returned by a PROPFIND DAV:allprop
- request (as defined in Section 12.14.1 of [RFC2518]).
-
- Description: The CALDAV:supported-collation-set property contains
- zero or more CALDAV:supported-collation elements, which specify
- the collection identifiers of the collations supported by the
- server.
-
- Definition:
-
-
-
-
-
- Example:
-
-
- i;ascii-casemap
- i;octet
-
-
-7.6. Partial Retrieval
-
- Some calendaring reports defined in this document allow partial
- retrieval of calendar object resources. A CalDAV client can specify
- what information to return in the body of a calendaring REPORT
- request.
-
- A CalDAV client can request particular WebDAV property values, all
- WebDAV property values, or a list of the names of the resource's
- WebDAV properties. A CalDAV client can also request calendar data to
- be returned and specify whether all calendar components and
- properties should be returned, or only particular ones. See CALDAV:
- calendar-data in Section 9.6.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 34]
-
-RFC 4791 CalDAV March 2007
-
-
- By default, the returned calendar data will include the component
- that defines the recurrence set, referred to as the "master
- component", as well as the components that define exceptions to the
- recurrence set, referred to as the "overridden components".
-
- A CalDAV client that is only interested in the recurrence instances
- that overlap a specified time range can request to receive only the
- "master component", along with the "overridden components" that
- impact the specified time range, and thus, limit the data returned by
- the server (see CALDAV:limit-recurrence-set in Section 9.6.6). An
- overridden component impacts a time range if its current start and
- end times overlap the time range, or if the original start and end
- times -- the ones that would have been used if the instance were not
- overridden -- overlap the time range, or if it affects other
- instances that overlap the time range.
-
- A CalDAV client with no support for recurrence properties (i.e.,
- EXDATE, EXRULE, RDATE, and RRULE) and possibly VTIMEZONE components,
- or a client unwilling to perform recurrence expansion because of
- limited processing capability, can request to receive only the
- recurrence instances that overlap a specified time range as separate
- calendar components that each define exactly one recurrence instance
- (see CALDAV:expand in Section 9.6.5.)
-
- Finally, in the case of VFREEBUSY components, a CalDAV client can
- request to receive only the FREEBUSY property values that overlap a
- specified time range (see CALDAV:limit-freebusy-set in
- Section 9.6.7.)
-
-7.7. Non-Standard Components, Properties, and Parameters
-
- Servers MUST support the use of non-standard component, property, or
- parameter names in the CALDAV:calendar-data XML element in
- calendaring REPORT requests to allow clients to request that non-
- standard components, properties, and parameters be returned in the
- calendar data provided in the response.
-
- Servers MAY support the use of non-standard component, property, or
- parameter names in the CALDAV:comp-filter, CALDAV:prop-filter, and
- CALDAV:param-filter XML elements specified in the CALDAV:filter XML
- element of calendaring REPORT requests.
-
- Servers MUST fail with the CALDAV:supported-filter precondition if a
- calendaring REPORT request uses a CALDAV:comp-filter, CALDAV:prop-
- filter, or CALDAV:param-filter XML element that makes reference to a
- non-standard component, property, or parameter name on which the
- server does not support queries.
-
-
-
-
-Daboo, et al. Standards Track [Page 35]
-
-RFC 4791 CalDAV March 2007
-
-
-7.8. CALDAV:calendar-query REPORT
-
- The CALDAV:calendar-query REPORT performs a search for all calendar
- object resources that match a specified filter. The response of this
- report will contain all the WebDAV properties and calendar object
- resource data specified in the request. In the case of the CALDAV:
- calendar-data XML element, one can explicitly specify the calendar
- components and properties that should be returned in the calendar
- object resource data that matches the filter.
-
- The format of this report is modeled on the PROPFIND method. The
- request and response bodies of the CALDAV:calendar-query REPORT use
- XML elements that are also used by PROPFIND. In particular, the
- request can include XML elements to request WebDAV properties to be
- returned. When that occurs, the response should follow the same
- behavior as PROPFIND with respect to the DAV:multistatus response
- elements used to return specific property results. For instance, a
- request to retrieve the value of a property that does not exist is an
- error and MUST be noted with a response XML element that contains a
- 404 (Not Found) status value.
-
- Support for the CALDAV:calendar-query REPORT is REQUIRED.
-
- Marshalling:
-
- The request body MUST be a CALDAV:calendar-query XML element, as
- defined in Section 9.5.
-
- The request MAY include a Depth header. If no Depth header is
- included, Depth:0 is assumed.
-
- The response body for a successful request MUST be a DAV:
- multistatus XML element (i.e., the response uses the same format
- as the response for PROPFIND). In the case where there are no
- response elements, the returned DAV:multistatus XML element is
- empty.
-
- The response body for a successful CALDAV:calendar-query REPORT
- request MUST contain a DAV:response element for each iCalendar
- object that matched the search filter. Calendar data is being
- returned in the CALDAV:calendar-data XML element inside the DAV:
- propstat XML element.
-
- Preconditions:
-
- (CALDAV:supported-calendar-data): The attributes "content-type"
- and "version" of the CALDAV:calendar-data XML element (see
-
-
-
-
-Daboo, et al. Standards Track [Page 36]
-
-RFC 4791 CalDAV March 2007
-
-
- Section 9.6) specify a media type supported by the server for
- calendar object resources.
-
- (CALDAV:valid-filter): The CALDAV:filter XML element (see
- Section 9.7) specified in the REPORT request MUST be valid. For
- instance, a CALDAV:filter cannot nest a
- element in a element, and a CALDAV:filter
- cannot nest a element in a
- element.
-
- (CALDAV:supported-filter): The CALDAV:comp-filter (see
- Section 9.7.1), CALDAV:prop-filter (see Section 9.7.2), and
- CALDAV:param-filter (see Section 9.7.3) XML elements used in the
- CALDAV:filter XML element (see Section 9.7) in the REPORT request
- only make reference to components, properties, and parameters for
- which queries are supported by the server, i.e., if the CALDAV:
- filter element attempts to reference an unsupported component,
- property, or parameter, this precondition is violated. Servers
- SHOULD report the CALDAV:comp-filter, CALDAV:prop-filter, or
- CALDAV:param-filter for which it does not provide support.
-
-
-
- (CALDAV:valid-calendar-data): The time zone specified in the
- REPORT request MUST be a valid iCalendar object containing a
- single valid VTIMEZONE component.
-
- (CALDAV:min-date-time): Any XML element specifying a range of time
- MUST have its start or end DATE or DATE-TIME values greater than
- or equal to the value of the CALDAV:min-date-time property value
- (Section 5.2.6) on the calendar collections being targeted by the
- REPORT request;
-
- (CALDAV:max-date-time): Any XML element specifying a range of time
- MUST have its start or end DATE or DATE-TIME values less than or
- equal to the value of the CALDAV:max-date-time property value
- (Section 5.2.7) on the calendar collections being targeted by the
- REPORT request;
-
- (CALDAV:supported-collation): Any XML attribute specifying a
- collation MUST specify a collation supported by the server as
- described in Section 7.5.
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 37]
-
-RFC 4791 CalDAV March 2007
-
-
- Postconditions:
-
- (DAV:number-of-matches-within-limits): The number of matching
- calendar object resources must fall within server-specific,
- predefined limits. For example, this condition might be triggered
- if a search specification would cause the return of an extremely
- large number of responses.
-
-7.8.1. Example: Partial Retrieval of Events by Time Range
-
- In this example, the client requests the server to return specific
- components and properties of the VEVENT components that overlap the
- time range from January 4, 2006, at 00:00:00 A.M. UTC to January 5,
- 2006, at 00:00:00 A.M. UTC. In addition, the DAV:getetag property is
- also requested and returned as part of the response. Note that the
- first calendar object returned is a recurring event whose first
- instance lies outside the requested time range, but whose third
- instance does overlap the time range. Note that due to the CALDAV:
- calendar-data element restrictions, the DTSTAMP property in VEVENT
- components has not been returned, and the only property returned in
- the VCALENDAR object is VERSION.
-
- See Appendix B for the calendar data being targeted by this example.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 38]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >> 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
-
-
-
-Daboo, et al. Standards Track [Page 39]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd2.ics
-
-
- "fffff-abcd2"
- BEGIN:VCALENDAR
- VERSION:2.0
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTART;TZID=US/Eastern:20060102T120000
- DURATION:PT1H
- RRULE:FREQ=DAILY;COUNT=5
- SUMMARY:Event #2
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTART;TZID=US/Eastern:20060104T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060104T120000
- SUMMARY:Event #2 bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTART;TZID=US/Eastern:20060106T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060106T120000
- SUMMARY:Event #2 bis bis
- UID:00959BC664CA650E933C892C@example.com
-
-
-
-Daboo, et al. Standards Track [Page 40]
-
-RFC 4791 CalDAV March 2007
-
-
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 41]
-
-RFC 4791 CalDAV March 2007
-
-
-7.8.2. Example: Partial Retrieval of Recurring Events
-
- In this example, the client requests the server to return VEVENT
- components that overlap the time range from January 3, 2006, at 00:
- 00:00 A.M. UTC to January 5, 2006, at 00:00:00 A.M. UTC. Use of the
- CALDAV:limit-recurrence-set element causes the server to only return
- overridden recurrence components that overlap the time range
- specified in that element or that affect other instances that overlap
- the time range (e.g., in the case of a THISANDFUTURE behavior). In
- this example, the first overridden component in the matching resource
- is returned, but the second one is not.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >> 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
-
-
-
-
-Daboo, et al. Standards Track [Page 42]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd2.ics
-
-
- "fffff-abcd2"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060102T120000
- DURATION:PT1H
- RRULE:FREQ=DAILY;COUNT=5
- SUMMARY:Event #2
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060104T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060104T120000
- SUMMARY:Event #2 bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- END:VCALENDAR
-
-
-
-
-
-Daboo, et al. Standards Track [Page 43]
-
-RFC 4791 CalDAV March 2007
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-Daboo, et al. Standards Track [Page 44]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
-7.8.3. Example: Expanded Retrieval of Recurring Events
-
- In this example, the client requests the server to return VEVENT
- components that overlap the time range from January 2, 2006, at 00:
- 00:00 A.M. UTC to January 5, 2006, at 00:00:00 A.M. UTC and to return
- recurring calendar components expanded into individual recurrence
- instance calendar components. Use of the CALDAV:expand element
- causes the server to only return overridden recurrence instances that
- overlap the time range specified in that element.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >> 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
-
-
-
-Daboo, et al. Standards Track [Page 45]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd2.ics
-
-
- "fffff-abcd2"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART:20060103T170000
- DURATION:PT1H
- RECURRENCE-ID:20060103T170000
- SUMMARY:Event #2
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART:20060104T190000
- DURATION:PT1H
- RECURRENCE-ID:20060104T170000
- SUMMARY:Event #2 bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART:20060104T150000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
-
-
-
-Daboo, et al. Standards Track [Page 46]
-
-RFC 4791 CalDAV March 2007
-
-
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 47]
-
-RFC 4791 CalDAV March 2007
-
-
-7.8.4. Example: Partial Retrieval of Stored Free Busy Components
-
- In this example, the client requests the server to return the
- VFREEBUSY components that have free busy information that overlap the
- time range from January 2, 2006, at 00:00:00 A.M. UTC (inclusively)
- to January 3, 2006, at 00:00:00 A.M. UTC (exclusively). Use of the
- CALDAV:limit-freebusy-set element causes the server to only return
- the FREEBUSY property values that overlap the time range specified in
- that element. Note that this is not an example of discovering when
- the calendar owner is busy.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 48]
-
-RFC 4791 CalDAV March 2007
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd8.ics
-
-
- "fffff-abcd8"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VFREEBUSY
- ORGANIZER;CN="Bernard Desruisseaux":mailto:bernard@example.com
- UID:76ef34-54a3d2@example.com
- DTSTAMP:20050530T123421Z
- DTSTART:20060101T100000Z
- DTEND:20060108T100000Z
- FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
- END:VFREEBUSY
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 49]
-
-RFC 4791 CalDAV March 2007
-
-
-7.8.5. Example: Retrieval of To-Dos by Alarm Time Range
-
- In this example, the client requests the server to return the VTODO
- components that have an alarm trigger scheduled in the specified time
- range.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 50]
-
-RFC 4791 CalDAV March 2007
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd4.ics
-
-
- "fffff-abcd4"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- DTSTAMP:20060205T235300Z
- DUE;TZID=US/Eastern:20060106T120000
- LAST-MODIFIED:20060205T235308Z
- SEQUENCE:1
- STATUS:NEEDS-ACTION
- SUMMARY:Task #2
- UID:E10BA47467C5C69BB74E8720@example.com
- BEGIN:VALARM
- ACTION:AUDIO
- TRIGGER;RELATED=START:-PT10M
- END:VALARM
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-7.8.6. Example: Retrieval of Event by UID
-
- In this example, the client requests the server to return the VEVENT
- component that has the UID property set to
- "DC6C50A017428C5216A2F1CD@example.com".
-
- See Appendix B for the calendar data being targeted by this example.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 51]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
- DC6C50A017428C5216A2F1CD@example.com
-
-
-
-
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
-
-
-
-Daboo, et al. Standards Track [Page 52]
-
-RFC 4791 CalDAV March 2007
-
-
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-7.8.7. Example: Retrieval of Events by PARTSTAT
-
- In this example, the client requests the server to return the VEVENT
- components that have the ATTENDEE property with the value
- "mailto:lisa@example.com" and for which the PARTSTAT parameter is set
- to NEEDS-ACTION.
-
- See Appendix B for the calendar data being targeted by this example.
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 53]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
- mailto:lisa@example.com
-
- NEEDS-ACTION
-
-
-
-
-
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
-
-
-
-Daboo, et al. Standards Track [Page 54]
-
-RFC 4791 CalDAV March 2007
-
-
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-7.8.8. Example: Retrieval of Events Only
-
- In this example, the client requests the server to return all VEVENT
- components.
-
- See Appendix B for the calendar data being targeted by this example.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 55]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd1.ics
-
-
- "fffff-abcd1"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
-
-
-
-Daboo, et al. Standards Track [Page 56]
-
-RFC 4791 CalDAV March 2007
-
-
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001102Z
- DTSTART;TZID=US/Eastern:20060102T100000
- DURATION:PT1H
- SUMMARY:Event #1
- Description:Go Steelers!
- UID:74855313FA803DA593CD579A@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/abcd2.ics
-
-
- "fffff-abcd2"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
-
-
-
-Daboo, et al. Standards Track [Page 57]
-
-RFC 4791 CalDAV March 2007
-
-
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060102T120000
- DURATION:PT1H
- RRULE:FREQ=DAILY;COUNT=5
- SUMMARY:Event #2
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060104T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060104T120000
- SUMMARY:Event #2 bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060106T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060106T120000
- SUMMARY:Event #2 bis bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
-
-
-
-Daboo, et al. Standards Track [Page 58]
-
-RFC 4791 CalDAV March 2007
-
-
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-7.8.9. Example: Retrieval of All Pending To-Dos
-
- In this example, the client requests the server to return all VTODO
- components that do not include a COMPLETED property and do not have a
- STATUS property value matching CANCELLED, i.e., VTODOs that still
- need to be worked on.
-
- See Appendix B for the calendar data being targeted by this example.
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 59]
-
-RFC 4791 CalDAV March 2007
-
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CANCELLED
-
-
-
-
-
-
- >> 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
-
-
-
-
- http://cal.example.com/bernard/work/abcd4.ics
-
-
- "fffff-abcd4"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
-
-
-
-Daboo, et al. Standards Track [Page 60]
-
-RFC 4791 CalDAV March 2007
-
-
- DTSTAMP:20060205T235335Z
- DUE;VALUE=DATE:20060104
- STATUS:NEEDS-ACTION
- SUMMARY:Task #1
- UID:DDDEEB7915FA61233B861457@example.com
- BEGIN:VALARM
- ACTION:AUDIO
- TRIGGER;RELATED=START:-PT10M
- END:VALARM
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd5.ics
-
-
- "fffff-abcd5"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- DTSTAMP:20060205T235300Z
- DUE;VALUE=DATE:20060106
- LAST-MODIFIED:20060205T235308Z
- SEQUENCE:1
- STATUS:NEEDS-ACTION
- SUMMARY:Task #2
- UID:E10BA47467C5C69BB74E8720@example.com
- BEGIN:VALARM
- ACTION:AUDIO
- TRIGGER;RELATED=START:-PT10M
- END:VALARM
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 61]
-
-RFC 4791 CalDAV March 2007
-
-
-7.8.10. Example: Attempt to Query Unsupported Property
-
- In this example, the client requests the server to return all VEVENT
- components that include an X-ABC-GUID property with a value matching
- "ABC". However, the server does not support querying that non-
- standard property, and instead returns an error response.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
- ABC
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 403 Forbidden
- Date: Sat, 11 Nov 2005 09:32:12 GMT
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 62]
-
-RFC 4791 CalDAV March 2007
-
-
-7.9. CALDAV:calendar-multiget REPORT
-
- The CALDAV:calendar-multiget REPORT is used to retrieve specific
- calendar object resources from within a collection, if the Request-
- URI is a collection, or to retrieve a specific calendar object
- resource, if the Request-URI is a calendar object resource. This
- report is similar to the CALDAV:calendar-query REPORT (see
- Section 7.8), except that it takes a list of DAV:href elements,
- instead of a CALDAV:filter element, to determine which calendar
- object resources to return.
-
- Support for the CALDAV:calendar-multiget REPORT is REQUIRED.
-
- Marshalling:
-
- The request body MUST be a CALDAV:calendar-multiget XML element
- (see Section 9.10). If the Request-URI is a collection resource,
- then the DAV:href elements MUST refer to calendar object resources
- within that collection, and they MAY refer to calendar object
- resources at any depth within the collection. As a result, the
- "Depth" header MUST be ignored by the server and SHOULD NOT be
- sent by the client. If the Request-URI refers to a non-collection
- resource, then there MUST be a single DAV:href element that is
- equivalent to the Request-URI.
-
- The response body for a successful request MUST be a DAV:
- multistatus XML element.
-
- The response body for a successful CALDAV:calendar-multiget REPORT
- request MUST contain a DAV:response element for each calendar
- object resource referenced by the provided set of DAV:href
- elements. Calendar data is being returned in the CALDAV:calendar-
- data element inside the DAV:prop element.
-
- In the case of an error accessing any of the provided DAV:href
- resources, the server MUST return the appropriate error status
- code in the DAV:status element of the corresponding DAV:response
- element.
-
- Preconditions:
-
- (CALDAV:supported-calendar-data): The attributes "content-type"
- and "version" of the CALDAV:calendar-data XML elements (see
- Section 9.6) specify a media type supported by the server for
- calendar object resources.
-
- (CALDAV:min-date-time): Any XML element specifying a range of time
- MUST have its start or end DATE or DATE-TIME values greater than
-
-
-
-Daboo, et al. Standards Track [Page 63]
-
-RFC 4791 CalDAV March 2007
-
-
- or equal to the value of the CALDAV:min-date-time property value
- (Section 5.2.6) on the calendar collections being targeted by the
- REPORT request;
-
- (CALDAV:max-date-time): Any XML element specifying a range of time
- MUST have its start or end DATE or DATE-TIME values less than or
- equal to the value of the CALDAV:max-date-time property value
- (Section 5.2.7) on the calendar collections being targeted by the
- REPORT request;
-
- Postconditions:
-
- None.
-
-7.9.1. Example: Successful CALDAV:calendar-multiget REPORT
-
- In this example, the client requests the server to return specific
- properties of the VEVENT components referenced by specific URIs. In
- addition, the DAV:getetag property is also requested and returned as
- part of the response. Note that in this example, the resource at
- http://cal.example.com/bernard/work/mtg1.ics does not exist,
- resulting in an error status response.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- /bernard/work/abcd1.ics
- /bernard/work/mtg1.ics
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: application/xml; charset="utf-8"
-
-
-
-Daboo, et al. Standards Track [Page 64]
-
-RFC 4791 CalDAV March 2007
-
-
- Content-Length: xxxx
-
-
-
-
- http://cal.example.com/bernard/work/abcd1.ics
-
-
- "fffff-abcd1"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001102Z
- DTSTART;TZID=US/Eastern:20060102T100000
- DURATION:PT1H
- SUMMARY:Event #1
- Description:Go Steelers!
- UID:74855313FA803DA593CD579A@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
- http://cal.example.com/bernard/work/mtg1.ics
- HTTP/1.1 404 Not Found
-
-
-
-Daboo, et al. Standards Track [Page 65]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
-7.10. CALDAV:free-busy-query REPORT
-
- The CALDAV:free-busy-query REPORT generates a VFREEBUSY component
- containing free busy information for all the calendar object
- resources targeted by the request and that have the CALDAV:read-free-
- busy or DAV:read privilege granted to the current user.
-
- Only VEVENT components without a TRANSP property or with the TRANSP
- property set to OPAQUE, and VFREEBUSY components SHOULD be considered
- in generating the free busy time information.
-
- In the case of VEVENT components, the free or busy time type (FBTYPE)
- of the FREEBUSY properties in the returned VFREEBUSY component SHOULD
- be derived from the value of the TRANSP and STATUS properties, as
- outlined in the table below:
-
- +---------------------------++------------------+
- | VEVENT || VFREEBUSY |
- +-------------+-------------++------------------+
- | TRANSP | STATUS || FBTYPE |
- +=============+=============++==================+
- | | CONFIRMED || BUSY |
- | | (default) || |
- | OPAQUE +-------------++------------------+
- | (default) | CANCELLED || FREE |
- | +-------------++------------------+
- | | TENTATIVE || BUSY-TENTATIVE |
- | +-------------++------------------+
- | | x-name || BUSY or |
- | | || x-name |
- +-------------+-------------++------------------+
- | | CONFIRMED || |
- | TRANSPARENT | CANCELLED || FREE |
- | | TENTATIVE || |
- | | x-name || |
- +-------------+-------------++------------------+
-
- Duplicate busy time periods with the same FBTYPE parameter value
- SHOULD NOT be specified in the returned VFREEBUSY component. Servers
- SHOULD coalesce consecutive or overlapping busy time periods of the
- same type. Busy time periods with different FBTYPE parameter values
- MAY overlap.
-
- Support for the CALDAV:free-busy-query REPORT is REQUIRED.
-
-
-
-
-Daboo, et al. Standards Track [Page 66]
-
-RFC 4791 CalDAV March 2007
-
-
- Marshalling:
-
- The request body MUST be a CALDAV:free-busy-query XML element (see
- Section 9.11), which MUST contain exactly one CALDAV:time-range
- XML element, as defined in Section 9.9.
-
- The request MAY include a Depth header. If no Depth header is
- included, Depth:0 is assumed.
-
- The response body for a successful request MUST be an iCalendar
- object that contains exactly one VFREEBUSY component that
- describes the busy time intervals for the calendar object
- resources containing VEVENT, or VFREEBUSY components that satisfy
- the Depth value and for which the current user is at least granted
- the CALDAV:read-free-busy privilege. If no calendar object
- resources are found to satisfy these conditions, a VFREEBUSY
- component with no FREEBUSY property MUST be returned. This report
- only returns busy time information. Free time information can be
- inferred from the returned busy time information.
-
- If the current user is not granted the CALDAV:read-free-busy or
- DAV:read privileges on the Request-URI, the CALDAV:free-busy-query
- REPORT request MUST fail and return a 404 (Not Found) status
- value. This restriction will prevent users from discovering URLs
- of resources for which they are only granted the CALDAV:read-free-
- busy privilege.
-
- The CALDAV:free-busy-query REPORT request can only be run against
- a collection (either a regular collection or a calendar
- collection). An attempt to run the report on a calendar object
- resource MUST fail and return a 403 (Forbidden) status value.
-
- Preconditions:
-
- None.
-
- Postconditions:
-
- (DAV:number-of-matches-within-limits): The number of matching
- calendar object resources must fall within server-specific,
- predefined limits. For example, this postcondition might fail if
- the specified CALDAV:time-range would cause an extremely large
- number of calendar object resources to be considered in computing
- the response.
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 67]
-
-RFC 4791 CalDAV March 2007
-
-
-7.10.1. Example: Successful CALDAV:free-busy-query REPORT
-
- In this example, the client requests the server to return free busy
- information on the calendar collection /bernard/work/, between 9:00
- A.M. and 5:00 P.M. EST (2:00 P.M. and 10:00 P.M. UTC) on the January
- 4, 2006. The server responds, indicating two busy time intervals of
- one hour, one of which is tentative.
-
- See Appendix B for the calendar data being targeted by this example.
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/calendar
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- BEGIN:VFREEBUSY
- DTSTAMP:20050125T090000Z
- DTSTART:20060104T140000Z
- DTEND:20060105T220000Z
- FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060104T150000Z/PT1H
- FREEBUSY:20060104T190000Z/PT1H
- END:VFREEBUSY
- END:VCALENDAR
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 68]
-
-RFC 4791 CalDAV March 2007
-
-
-8. Guidelines
-
-8.1. Client-to-Client Interoperability
-
- There are a number of actions clients can take that will be legal
- (the server will not return errors), but that can degrade
- interoperability with other client implementations accessing the same
- data. For example, a recurrence rule could be replaced with a set of
- recurrence dates, a single recurring event could be replaced with a
- set of independent resources to represent each recurrence, or the
- start/end time values can be translated from the original time zone
- to another time zone. Although this advice amounts to iCalendar
- interoperability best practices and is not limited only to CalDAV
- usage, interoperability problems are likely to be more evident in
- CalDAV use cases.
-
-8.2. Synchronization Operations
-
- WebDAV already provides functionality required to synchronize a
- collection or set of collections, to make changes offline, and
- provides a simple way to resolve conflicts when reconnected. ETags
- are the key to making this work, but these are not required of all
- WebDAV servers. Since offline functionality is more important to
- calendar applications than to some other WebDAV applications, CalDAV
- servers MUST support ETags, as specified in Section 5.3.4.
-
-8.2.1. Use of Reports
-
-8.2.1.1. Restrict the Time Range
-
- The reports provided in CalDAV can be used by clients to optimize
- their performance in terms of network bandwidth usage and resource
- consumption on the local client machine. Both are certainly major
- considerations for mobile or handheld devices with limited capacity,
- but they are also relevant to desktop client applications in cases
- where the calendar collections contain large amounts of data.
-
- Typically, clients present calendar data to users in views that span
- a finite time interval, so whenever possible, clients should only
- retrieve calendar components from the server using CALDAV:calendar-
- query REPORT, combined with a CALDAV:time-range element, to limit the
- set of returned components to just those needed to populate the
- current view.
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 69]
-
-RFC 4791 CalDAV March 2007
-
-
-8.2.1.2. Synchronize by Time Range
-
- Typically in a calendar, historical data (events, to-dos, etc. that
- have completed prior to the current date) do not change, though they
- may be deleted. As a result, a client can speed up the
- synchronization process by only considering data for the present time
- and the future up to a reasonable limit (e.g., one week, one month).
- If the user then tries to examine a portion of the calendar outside
- the range that has been synchronized, the client can perform another
- synchronization operation on the new time interval being examined.
- This "just-in-time" synchronization can minimize bandwidth for common
- user interaction behaviors.
-
-8.2.1.3. Synchronization Process
-
- If a client wants to support calendar data synchronization, as
- opposed to downloading calendar data each time it is needed, the
- client needs to cache the calendar object resource's URI and ETag,
- along with the actual calendar data. While the URI remains static
- for the lifetime of the calendar object resource, the ETag will
- change with each successive change to the calendar object resource.
- Thus, to synchronize a local data cache with the server, the client
- can first fetch the URI/ETag pairs for the time interval being
- considered, and compare those results with the cached data. Any
- cached component whose ETag differs from that on the server needs to
- be refreshed.
-
- In order to properly detect the changes between the server and client
- data, the client will need to keep a record of which calendar object
- resources have been created, changed, or deleted since the last
- synchronization operation so that it can reconcile those changes with
- the data on the server.
-
- Here's an example of how to do that:
-
- The client issues a CALDAV:calendar-query REPORT request for a
- specific time range and asks for only the DAV:getetag property to be
- returned:
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 70]
-
-RFC 4791 CalDAV March 2007
-
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The client then uses the results to determine which calendar object
- resources have changed, been created, or deleted on the server, and
- how those relate to locally cached calendar object resources that may
- have changed, been created, or deleted. If the client determines
- that there are calendar object resources on the server that need to
- be fetched, the client issues a CALDAV:calendar-multiget REPORT
- request to fetch its calendar data:
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- /bernard/work/abcd1.ics
- /bernard/work/mtg1.ics
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 71]
-
-RFC 4791 CalDAV March 2007
-
-
-8.2.2. Restrict the Properties Returned
-
- A client may not need all the calendar properties of a calendar
- object resource when presenting information to the user. Since some
- calendar property values can be large (e.g., ATTACH or ATTENDEE), a
- client can choose to restrict the calendar properties to be returned
- in a calendaring REPORT request to those it knows it will use.
-
- However, if a client needs to make a change to a calendar object
- resource, it can only change the entire calendar object resource via
- a PUT request. There is currently no way to incrementally make a
- change to a set of calendar properties of a calendar object resource.
- As a result, the client will have to get the entire calendar object
- resource that is being changed.
-
-8.3. Use of Locking
-
- WebDAV locks can be used to prevent two clients that are modifying
- the same resource from either overwriting each others' changes
- (though that problem can also be solved by using ETags) or wasting
- time making changes that will conflict with another set of changes.
- In a multi-user calendar system, an interactive calendar client could
- lock an event while the user is editing the event, and unlock the
- event when the user finishes or cancels. Locks can also be used to
- prevent changes while data is being reorganized. For example, a
- calendar client might lock two calendar collections prior to moving a
- bunch of calendar resources from one to another.
-
- Clients are responsible for requesting a lock timeout period that is
- appropriate to the use case. When the user explicitly decides to
- reserve a resource and prevent other changes, a long timeout might be
- appropriate, but in cases where the client automatically decides to
- lock the resource, the timeout should be short (and the client can
- always refresh the lock should it need to). A short lock timeout
- means that if the client is unable to remove the lock, the other
- calendar users aren't prevented from making changes.
-
-8.4. Finding Calendars
-
- Much of the time, a calendar client (or agent) will discover a new
- calendar's location by being provided directly with the URL. For
- example, a user will type his or her own calendar location into
- client configuration information or copy and paste a URL from email
- into the calendar application. The client need only confirm that the
- URL points to a resource that is a calendar collection. The client
- may also be able to browse WebDAV collections to find calendar
- collections.
-
-
-
-
-Daboo, et al. Standards Track [Page 72]
-
-RFC 4791 CalDAV March 2007
-
-
- The choice of HTTP URLs means that calendar object resources are
- backward compatible with existing software, but does have the
- disadvantage that existing software does not usually know to look at
- the OPTIONS response to that URL to determine what can be done with
- it. This is somewhat of a barrier for WebDAV usage as well as with
- CalDAV usage. This specification does not offer a way through this
- other than making the information available in the OPTIONS response
- should this be requested.
-
- For calendar sharing and scheduling use cases, one might wish to find
- the calendar belonging to another user. If the other user has a
- calendar in the same repository, that calendar can be found by using
- the principal namespace required by WebDAV ACL support. For other
- cases, the authors have no universal solution, but implementers can
- consider whether to use vCard [RFC2426] or LDAP [RFC4511] standards
- together with calendar attributes [RFC2739].
-
- Because CalDAV requires servers to support WebDAV ACL [RFC3744],
- including principal namespaces, and with the addition of the CALDAV:
- calendar-home-set property, there are a couple options for CalDAV
- clients to find one's own calendar or another user's calendar.
-
- In this case, a DAV:principal-match REPORT is used to find a named
- property (the CALDAV:calendar-home-set) on the Principal-URL of the
- current user. Using this, a WebDAV client can learn "who am I" and
- "where are my calendars". The REPORT request body looks like this:
-
-
-
-
-
-
-
-
-
- To find other users' calendars, the DAV:principal-property-search
- REPORT can be used to filter on some properties and return others.
- To search for a calendar owned by a user named "Laurie", the REPORT
- request body would look like this:
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 73]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
-
-
-
- Laurie
-
-
-
-
-
-
-
- The server performs a case-sensitive or caseless search for a
- matching string subset of "Laurie" within the DAV:displayname
- property. Thus, the server might return "Laurie Dusseault", "Laurier
- Desruisseaux", or "Wilfrid Laurier" as matching DAV:displayname
- values, and return the calendars for each of these.
-
-8.5. Storing and Using Attachments
-
- CalDAV clients MAY create attachments in calendar components either
- as inline or external. This section contains some guidelines for
- creating and managing attachments.
-
-8.5.1. Inline Attachments
-
- CalDAV clients MUST support inline attachments as specified in
- iCalendar [RFC2445]. CalDAV servers MUST support inline attachments,
- so clients can rely on being able to create attachments this way. On
- the other hand, inline attachments have some drawbacks:
-
- o Servers MAY impose limitations on the size of calendar object
- resources (i.e., refusing PUT requests of very large iCalendar
- objects). Servers that impose such limitations MUST use the
- CALDAV:max-resource-size property on a calendar collection to
- inform the client as to what the limitation is (see
- Section 5.2.5).
-
- o Servers MAY impose storage quota limitations on calendar
- collections (See [RFC4331]).
-
- o Any change to a calendar object resource containing an inline
- attachment requires the entire inline attachment to be re-
- uploaded.
-
-
-
-
-Daboo, et al. Standards Track [Page 74]
-
-RFC 4791 CalDAV March 2007
-
-
- o Clients synchronizing a changed calendar object resource have to
- download the entire calendar object resource, even if the
- attachment is unchanged.
-
-8.5.2. External Attachments
-
- CalDAV clients SHOULD support downloading of external attachments
- referenced by arbitrary URI schemes, by either processing them
- directly, or by passing the attachment URI to a suitable "helper
- application" for processing, if such an application exists. CalDAV
- clients MUST support downloading of external attachments referenced
- by the "http" or "https" URI schemes. An external attachment could
- be:
-
- o In a collection in the calendar collection containing the calendar
- object resource;
-
- o Somewhere else in the same repository that hosts the calendar
- collection; or
-
- o On an HTTP or FTP server elsewhere.
-
- CalDAV servers MAY provide support for child collections in calendar
- collections. CalDAV servers MAY allow the MKCOL method to create
- child collections in calendar collections. Child collections of
- calendar collections MAY contain any type of resource except calendar
- collections that they MUST NOT contain. Some CalDAV servers won't
- allow child collections in calendar collections, and it may be
- possible on such a server to discover other locations where
- attachments can be stored.
-
- Clients are entirely responsible for maintaining reference
- consistency with calendar components that link to external
- attachments. A client deleting a calendar component with an external
- attachment might therefore also delete the attachment if that's
- appropriate; however, appropriateness can be very hard to determine.
- A new component might easily reference some pre-existing Web resource
- that is intended to have independent existence from the calendar
- component (the "attachment" could be a major proposal to be discussed
- in a meeting, for instance). Best practices will probably emerge and
- should probably be documented, but for now, clients should be wary of
- engaging in aggressive "cleanup" of external attachments. A client
- could involve the user in making decisions about removing
- unreferenced documents, or a client could be conservative in only
- deleting attachments it had created.
-
- Also, clients are responsible for consistency of permissions when
- using external attachments. One reason for servers to support the
-
-
-
-Daboo, et al. Standards Track [Page 75]
-
-RFC 4791 CalDAV March 2007
-
-
- storage of attachments within child collections of calendar
- collections is that ACL inheritance might make it easier to grant the
- same permissions to attachments that are granted on the calendar
- collection. Otherwise, it can be very difficult to keep permissions
- synchronized. With attachments stored on separate repositories, it
- can be impossible to keep permissions consistent -- the two
- repositories may not support the same permissions or have the same
- set of principals. Some systems have used tickets or other anonymous
- access control mechanisms to provide partially satisfactory solutions
- to these kinds of problems.
-
-8.6. Storing and Using Alarms
-
- Note that all CalDAV calendar collections (including those the user
- might treat as public or group calendars) can contain alarm
- information on events and to-dos. Users can synchronize a calendar
- between multiple devices and decide to have alarms execute on a
- different device than the device that created the alarm. Not all
- alarm action types are completely interoperable (e.g., those that
- name a sound file to play).
-
- When the action is AUDIO and the client is configured to execute
- the alarm, the client SHOULD play the suggested sound if it's
- available or play another sound, but SHOULD NOT rewrite the alarm
- just to replace the suggested sound with a sound that's locally
- available.
-
- When the action is DISPLAY and the client is configured to execute
- the alarm, the client SHOULD execute a display alarm by displaying
- according to the suggested description or some reasonable
- replacement, but SHOULD NOT rewrite the alarm for its own
- convenience.
-
- When the action is EMAIL and the client is incapable of sending
- email, it SHOULD ignore the alarm, but it MUST continue to
- synchronize the alarm itself.
-
- This specification makes no recommendations about executing alarms
- of type PROCEDURE, except to note that clients are advised to take
- care to avoid creating security holes by executing these.
-
- Non-interoperable alarm information (e.g., should somebody define a
- color to be used in a display alarm) should be put in non-standard
- properties inside the VALARM component in order to keep the basic
- alarm usable on all devices.
-
- Clients that allow changes to calendar object resources MUST
- synchronize the alarm data that already exists in the resources.
-
-
-
-Daboo, et al. Standards Track [Page 76]
-
-RFC 4791 CalDAV March 2007
-
-
- Clients MAY execute alarms that are downloaded in this fashion,
- possibly based on user preference. If a client is only doing read
- operations on a calendar and there is no risk of losing alarm
- information, then the client MAY discard alarm information.
-
- This specification makes no attempt to provide multi-user alarms on
- group calendars or to find out for whom an alarm is intended.
- Addressing those issues might require extensions to iCalendar; for
- example, to store alarms per-user, or to indicate for which user a
- VALARM was intended. In the meantime, clients might maximize
- interoperability by generally not uploading alarm information to
- public, group, or resource calendars.
-
-9. XML Element Definitions
-
-9.1. CALDAV:calendar XML Element
-
- Name: calendar
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies the resource type of a calendar collection.
-
- Description: See Section 4.2.
-
- Definition:
-
-
-
-9.2. CALDAV:mkcalendar XML Element
-
- Name: mkcalendar
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a request that includes the WebDAV property
- values to be set for a calendar collection resource when it is
- created.
-
- Description: See Section 5.3.1.
-
- Definition:
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 77]
-
-RFC 4791 CalDAV March 2007
-
-
-9.3. CALDAV:mkcalendar-response XML Element
-
- Name: mkcalendar-response
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a response body for a successful MKCALENDAR
- request.
-
- Description: See Section 5.3.1.
-
- Definition:
-
-
-
-9.4. CALDAV:supported-collation XML Element
-
- Name: supported-collation
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identifies a single collation via its collation identifier,
- as defined by [RFC4790].
-
- Description: The CALDAV:supported-collation contains the text of a
- collation identifier, as described in Section 7.5.1.
-
- Definition:
-
-
- PCDATA value: collation identifier
-
-9.5. CALDAV:calendar-query XML Element
-
- Name: calendar-query
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Defines a report for querying calendar object resources.
-
- Description: See Section 7.8.
-
- Definition:
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 78]
-
-RFC 4791 CalDAV March 2007
-
-
-9.6. CALDAV:calendar-data XML Element
-
- Name: calendar-data
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specified one of the following:
-
- 1. A supported media type for calendar object resources when
- nested in the CALDAV:supported-calendar-data property;
-
- 2. The parts of a calendar object resource should be returned by
- a calendaring report;
-
- 3. The content of a calendar object resource in a response to a
- calendaring report.
-
- Description: When nested in the CALDAV:supported-calendar-data
- property, the CALDAV:calendar-data XML element specifies a media
- type supported by the CalDAV server for calendar object resources.
-
- When used in a calendaring REPORT request, the CALDAV:calendar-
- data XML element specifies which parts of calendar object
- resources need to be returned in the response. If the CALDAV:
- calendar-data XML element doesn't contain any CALDAV:comp element,
- calendar object resources will be returned in their entirety.
-
- Finally, when used in a calendaring REPORT response, the CALDAV:
- calendar-data XML element specifies the content of a calendar
- object resource. Given that XML parsers normalize the two-
- character sequence CRLF (US-ASCII decimal 13 and US-ASCII decimal
- 10) to a single LF character (US-ASCII decimal 10), the CR
- character (US-ASCII decimal 13) MAY be omitted in calendar object
- resources specified in the CALDAV:calendar-data XML element.
- Furthermore, calendar object resources specified in the CALDAV:
- calendar-data XML element MAY be invalid per their media type
- specification if the CALDAV:calendar-data XML element part of the
- calendaring REPORT request did not specify required properties
- (e.g., UID, DTSTAMP, etc.), or specified a CALDAV:prop XML element
- with the "novalue" attribute set to "yes".
-
- Note: The CALDAV:calendar-data XML element is specified in requests
- and responses inside the DAV:prop XML element as if it were a
- WebDAV property. However, the CALDAV:calendar-data XML element is
- not a WebDAV property and, as such, is not returned in PROPFIND
- responses, nor used in PROPPATCH requests.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 79]
-
-RFC 4791 CalDAV March 2007
-
-
- Note: The iCalendar data embedded within the CALDAV:calendar-data
- XML element MUST follow the standard XML character data encoding
- rules, including use of <, >, & etc. entity encoding or
- the use of a construct. In the later case, the
- iCalendar data cannot contain the character sequence "]]>", which
- is the end delimiter for the CDATA section.
-
- Definition:
-
-
-
- when nested in the CALDAV:supported-calendar-data property
- to specify a supported media type for calendar object
- resources;
-
-
-
- when nested in the DAV:prop XML element in a calendaring
- REPORT request to specify which parts of calendar object
- resources should be returned in the response;
-
-
- PCDATA value: iCalendar object
-
- when nested in the DAV:prop XML element in a calendaring
- REPORT response to specify the content of a returned
- calendar object resource.
-
-
- content-type value: a MIME media type
- version value: a version string
-
- attributes can be used on all three variants of the
- CALDAV:calendar-data XML element.
-
-9.6.1. CALDAV:comp XML Element
-
- Name: comp
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Defines which component types to return.
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 80]
-
-RFC 4791 CalDAV March 2007
-
-
- Description: The name value is a calendar component name (e.g.,
- VEVENT).
-
- Definition:
-
-
-
-
- name value: a calendar component name
-
- Note: The CALDAV:prop and CALDAV:allprop elements have the same name
- as the DAV:prop and DAV:allprop elements defined in [RFC2518].
- However, the CALDAV:prop and CALDAV:allprop elements are defined
- in the "urn:ietf:params:xml:ns:caldav" namespace instead of the
- "DAV:" namespace.
-
-9.6.2. CALDAV:allcomp XML Element
-
- Name: allcomp
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies that all components shall be returned.
-
- Description: The CALDAV:allcomp XML element can be used when the
- client wants all types of components returned by a calendaring
- REPORT request.
-
- Definition:
-
-
-
-9.6.3. CALDAV:allprop XML Element
-
- Name: allprop
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies that all properties shall be returned.
-
- Description: The CALDAV:allprop XML element can be used when the
- client wants all properties of components returned by a
- calendaring REPORT request.
-
- Definition:
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 81]
-
-RFC 4791 CalDAV March 2007
-
-
- Note: The CALDAV:allprop element has the same name as the DAV:
- allprop element defined in [RFC2518]. However, the CALDAV:allprop
- element is defined in the "urn:ietf:params:xml:ns:caldav"
- namespace instead of the "DAV:" namespace.
-
-9.6.4. CALDAV:prop XML Element
-
- Name: prop
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Defines which properties to return in the response.
-
- Description: The "name" attribute specifies the name of the calendar
- property to return (e.g., ATTENDEE). The "novalue" attribute can
- be used by clients to request that the actual value of the
- property not be returned (if the "novalue" attribute is set to
- "yes"). In that case, the server will return just the iCalendar
- property name and any iCalendar parameters and a trailing ":"
- without the subsequent value data.
-
- Definition:
-
-
-
-
- name value: a calendar property name
- novalue value: "yes" or "no"
-
- Note: The CALDAV:prop element has the same name as the DAV:prop
- element defined in [RFC2518]. However, the CALDAV:prop element is
- defined in the "urn:ietf:params:xml:ns:caldav" namespace instead
- of the "DAV:" namespace.
-
-9.6.5. CALDAV:expand XML Element
-
- Name: expand
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Forces the server to expand recurring components into
- individual recurrence instances.
-
- Description: The CALDAV:expand XML element specifies that for a
- given calendaring REPORT request, the server MUST expand the
- recurrence set into calendar components that define exactly one
-
-
-
-
-Daboo, et al. Standards Track [Page 82]
-
-RFC 4791 CalDAV March 2007
-
-
- recurrence instance, and MUST return only those whose scheduled
- time intersect a specified time range.
-
- The "start" attribute specifies the inclusive start of the time
- range, and the "end" attribute specifies the non-inclusive end of
- the time range. Both attributes are specified as date with UTC
- time value. The value of the "end" attribute MUST be greater than
- the value of the "start" attribute.
-
- The server MUST use the same logic as defined for CALDAV:time-
- range to determine if a recurrence instance intersects the
- specified time range.
-
- Recurring components, other than the initial instance, MUST
- include a RECURRENCE-ID property indicating which instance they
- refer to.
-
- The returned calendar components MUST NOT use recurrence
- properties (i.e., EXDATE, EXRULE, RDATE, and RRULE) and MUST NOT
- have reference to or include VTIMEZONE components. Date and local
- time with reference to time zone information MUST be converted
- into date with UTC time.
-
- Definition:
-
-
-
-
- start value: an iCalendar "date with UTC time"
- end value: an iCalendar "date with UTC time"
-
-9.6.6. CALDAV:limit-recurrence-set XML Element
-
- Name: limit-recurrence-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a time range to limit the set of "overridden
- components" returned by the server.
-
- Description: The CALDAV:limit-recurrence-set XML element specifies
- that for a given calendaring REPORT request, the server MUST
- return, in addition to the "master component", only the
- "overridden components" that impact a specified time range. An
- overridden component impacts a time range if its current start and
- end times overlap the time range, or if the original start and end
-
-
-
-
-Daboo, et al. Standards Track [Page 83]
-
-RFC 4791 CalDAV March 2007
-
-
- times -- the ones that would have been used if the instance were
- not overridden -- overlap the time range.
-
- The "start" attribute specifies the inclusive start of the time
- range, and the "end" attribute specifies the non-inclusive end of
- the time range. Both attributes are specified as date with UTC
- time value. The value of the "end" attribute MUST be greater than
- the value of the "start" attribute.
-
- The server MUST use the same logic as defined for CALDAV:time-
- range to determine if the current or original scheduled time of an
- "overridden" recurrence instance intersects the specified time
- range.
-
- Overridden components that have a RANGE parameter on their
- RECURRENCE-ID property may specify one or more instances in the
- recurrence set, and some of those instances may fall within the
- specified time range or may have originally fallen within the
- specified time range prior to being overridden. If that is the
- case, the overridden component MUST be included in the results, as
- it has a direct impact on the interpretation of instances within
- the specified time range.
-
- Definition:
-
-
-
-
- start value: an iCalendar "date with UTC time"
- end value: an iCalendar "date with UTC time"
-
-9.6.7. CALDAV:limit-freebusy-set XML Element
-
- Name: limit-freebusy-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a time range to limit the set of FREEBUSY values
- returned by the server.
-
- Description: The CALDAV:limit-freebusy-set XML element specifies
- that for a given calendaring REPORT request, the server MUST only
- return the FREEBUSY property values of a VFREEBUSY component that
- intersects a specified time range.
-
- The "start" attribute specifies the inclusive start of the time
- range, and the "end" attribute specifies the non-inclusive end of
-
-
-
-Daboo, et al. Standards Track [Page 84]
-
-RFC 4791 CalDAV March 2007
-
-
- the time range. Both attributes are specified as "date with UTC
- time" value. The value of the "end" attribute MUST be greater
- than the value of the "start" attribute.
-
- The server MUST use the same logic as defined for CALDAV:time-
- range to determine if a FREEBUSY property value intersects the
- specified time range.
-
- Definition:
-
-
-
-
- start value: an iCalendar "date with UTC time"
- end value: an iCalendar "date with UTC time"
-
-9.7. CALDAV:filter XML Element
-
- Name: filter
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a filter to limit the set of calendar components
- returned by the server.
-
- Description: The CALDAV:filter XML element specifies the search
- filter used to limit the calendar components returned by a
- calendaring REPORT request.
-
- Definition:
-
-
-
-9.7.1. CALDAV:comp-filter XML Element
-
- Name: comp-filter
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies search criteria on calendar components.
-
- Description: The CALDAV:comp-filter XML element specifies a query
- targeted at the calendar object (i.e., VCALENDAR) or at a specific
- calendar component type (e.g., VEVENT). The scope of the
- CALDAV:comp-filter XML element is the calendar object when used as
- a child of the CALDAV:filter XML element. The scope of the
- CALDAV:comp-filter XML element is the enclosing calendar component
-
-
-
-Daboo, et al. Standards Track [Page 85]
-
-RFC 4791 CalDAV March 2007
-
-
- when used as a child of another CALDAV:comp-filter XML element. A
- CALDAV:comp-filter is said to match if:
-
- * The CALDAV:comp-filter XML element is empty and the calendar
- object or calendar component type specified by the "name"
- attribute exists in the current scope;
-
- or:
-
- * The CALDAV:comp-filter XML element contains a CALDAV:is-not-
- defined XML element and the calendar object or calendar
- component type specified by the "name" attribute does not exist
- in the current scope;
-
- or:
-
- * The CALDAV:comp-filter XML element contains a CALDAV:time-range
- XML element and at least one recurrence instance in the
- targeted calendar component is scheduled to overlap the
- specified time range, and all specified CALDAV:prop-filter and
- CALDAV:comp-filter child XML elements also match the targeted
- calendar component;
-
- or:
-
- * The CALDAV:comp-filter XML element only contains CALDAV:prop-
- filter and CALDAV:comp-filter child XML elements that all match
- the targeted calendar component.
-
- Definition:
-
-
-
-
- name value: a calendar object or calendar component
- type (e.g., VEVENT)
-
-9.7.2. CALDAV:prop-filter XML Element
-
- Name: prop-filter
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies search criteria on calendar properties.
-
- Description: The CALDAV:prop-filter XML element specifies a query
- targeted at a specific calendar property (e.g., CATEGORIES) in the
-
-
-
-Daboo, et al. Standards Track [Page 86]
-
-RFC 4791 CalDAV March 2007
-
-
- scope of the enclosing calendar component. A calendar property is
- said to match a CALDAV:prop-filter if:
-
- * The CALDAV:prop-filter XML element is empty and a property of
- the type specified by the "name" attribute exists in the
- enclosing calendar component;
-
- or:
-
- * The CALDAV:prop-filter XML element contains a CALDAV:is-not-
- defined XML element and no property of the type specified by
- the "name" attribute exists in the enclosing calendar
- component;
-
- or:
-
- * The CALDAV:prop-filter XML element contains a CALDAV:time-range
- XML element and the property value overlaps the specified time
- range, and all specified CALDAV:param-filter child XML elements
- also match the targeted property;
-
- or:
-
- * The CALDAV:prop-filter XML element contains a CALDAV:text-match
- XML element and the property value matches it, and all
- specified CALDAV:param-filter child XML elements also match the
- targeted property;
-
- Definition:
-
-
-
-
- name value: a calendar property name (e.g., ATTENDEE)
-
-9.7.3. CALDAV:param-filter XML Element
-
- Name: param-filter
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Limits the search to specific parameter values.
-
- Description: The CALDAV:param-filter XML element specifies a query
- targeted at a specific calendar property parameter (e.g.,
- PARTSTAT) in the scope of the calendar property on which it is
-
-
-
-Daboo, et al. Standards Track [Page 87]
-
-RFC 4791 CalDAV March 2007
-
-
- defined. A calendar property parameter is said to match a CALDAV:
- param-filter if:
-
- * The CALDAV:param-filter XML element is empty and a parameter of
- the type specified by the "name" attribute exists on the
- calendar property being examined;
-
- or:
-
- * The CALDAV:param-filter XML element contains a CALDAV:is-not-
- defined XML element and no parameter of the type specified by
- the "name" attribute exists on the calendar property being
- examined;
-
- Definition:
-
-
-
-
- name value: a property parameter name (e.g., PARTSTAT)
-
-9.7.4. CALDAV:is-not-defined XML Element
-
- Name: is-not-defined
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies that a match should occur if the enclosing
- component, property, or parameter does not exist.
-
- Description: The CALDAV:is-not-defined XML element specifies that a
- match occurs if the enclosing component, property, or parameter
- value specified in a calendaring REPORT request does not exist in
- the calendar data being tested.
-
- Definition:
-
-
-
-9.7.5. CALDAV:text-match XML Element
-
- Name: text-match
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a substring match on a property or parameter
- value.
-
-
-
-
-Daboo, et al. Standards Track [Page 88]
-
-RFC 4791 CalDAV March 2007
-
-
- Description: The CALDAV:text-match XML element specifies text used
- for a substring match against the property or parameter value
- specified in a calendaring REPORT request.
-
- The "collation" attribute is used to select the collation that the
- server MUST use for character string matching. In the absence of
- this attribute, the server MUST use the "i;ascii-casemap"
- collation.
-
- The "negate-condition" attribute is used to indicate that this
- test returns a match if the text matches when the attribute value
- is set to "no", or return a match if the text does not match, if
- the attribute value is set to "yes". For example, this can be
- used to match components with a STATUS property not set to
- CANCELLED.
-
- Definition:
-
-
- PCDATA value: string
-
-
-
-9.8. CALDAV:timezone XML Element
-
- Name: timezone
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies the time zone component to use when determining
- the results of a report.
-
- Description: The CALDAV:timezone XML element specifies that for a
- given calendaring REPORT request, the server MUST rely on the
- specified VTIMEZONE component instead of the CALDAV:calendar-
- timezone property of the calendar collection, in which the
- calendar object resource is contained to resolve "date" values and
- "date with local time" values (i.e., floating time) to "date with
- UTC time" values. The server will require this information to
- determine if a calendar component scheduled with "date" values or
- "date with local time" values intersects a CALDAV:time-range
- specified in a CALDAV:calendar-query REPORT.
-
- Note: The iCalendar data embedded within the CALDAV:timezone XML
- element MUST follow the standard XML character data encoding
- rules, including use of <, >, & etc. entity encoding or
- the use of a construct. In the later case, the
-
-
-
-Daboo, et al. Standards Track [Page 89]
-
-RFC 4791 CalDAV March 2007
-
-
- iCalendar data cannot contain the character sequence "]]>", which
- is the end delimiter for the CDATA section.
-
- Definition:
-
-
- PCDATA value: an iCalendar object with exactly one VTIMEZONE
-
-9.9. CALDAV:time-range XML Element
-
- Name: time-range
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a time range to limit the set of calendar
- components returned by the server.
-
- Description: The CALDAV:time-range XML element specifies that for a
- given calendaring REPORT request, the server MUST only return the
- calendar object resources that, depending on the context, have a
- component or property whose value intersects a specified time
- range.
-
- The "start" attribute specifies the inclusive start of the time
- range, and the "end" attribute specifies the non-inclusive end of
- the time range. Both attributes MUST be specified as "date with
- UTC time" value. Time ranges open at one end can be specified by
- including only one attribute; however, at least one attribute MUST
- always be present in the CALDAV:time-range element. If either the
- "start" or "end" attribute is not specified in the CALDAV:time-
- range XML element, assume "-infinity" and "+infinity" as their
- value, respectively. If both "start" and "end" are present, the
- value of the "end" attribute MUST be greater than the value of the
- "start" attribute.
-
- Time range tests MUST consider every recurrence instance when
- testing the time range condition; if any one instance matches,
- then the test returns true. Testing recurrence instances requires
- the server to infer an effective value for DTSTART, DTEND,
- DURATION, and DUE properties for an instance based on the
- recurrence patterns and any overrides.
-
- A VEVENT component overlaps a given time range if the condition
- for the corresponding component state specified in the table below
- is satisfied. Note that, as specified in [RFC2445], the DTSTART
- property is REQUIRED in the VEVENT component. The conditions
- depend on the presence of the DTEND and DURATION properties in the
- VEVENT component. Furthermore, the value of the DTEND property
-
-
-
-Daboo, et al. Standards Track [Page 90]
-
-RFC 4791 CalDAV March 2007
-
-
- MUST be later in time than the value of the DTSTART property. The
- duration of a VEVENT component with no DTEND and DURATION
- properties is 1 day (+P1D) when the DTSTART is a DATE value, and 0
- seconds when the DTSTART is a DATE-TIME value.
-
- +---------------------------------------------------------------+
- | VEVENT has the DTEND property? |
- | +-----------------------------------------------------------+
- | | VEVENT has the DURATION property? |
- | | +-------------------------------------------------------+
- | | | DURATION property value is greater than 0 seconds? |
- | | | +---------------------------------------------------+
- | | | | DTSTART property is a DATE-TIME value? |
- | | | | +-----------------------------------------------+
- | | | | | Condition to evaluate |
- +---+---+---+---+-----------------------------------------------+
- | Y | N | N | * | (start < DTEND AND end > DTSTART) |
- +---+---+---+---+-----------------------------------------------+
- | N | Y | Y | * | (start < DTSTART+DURATION AND end > DTSTART) |
- | | +---+---+-----------------------------------------------+
- | | | N | * | (start <= DTSTART AND end > DTSTART) |
- +---+---+---+---+-----------------------------------------------+
- | N | N | N | Y | (start <= DTSTART AND end > DTSTART) |
- +---+---+---+---+-----------------------------------------------+
- | N | N | N | N | (start < DTSTART+P1D AND end > DTSTART) |
- +---+---+---+---+-----------------------------------------------+
-
- A VTODO component is said to overlap a given time range if the
- condition for the corresponding component state specified in the
- table below is satisfied. The conditions depend on the presence
- of the DTSTART, DURATION, DUE, COMPLETED, and CREATED properties
- in the VTODO component. Note that, as specified in [RFC2445], the
- DUE value MUST be a DATE-TIME value equal to or after the DTSTART
- value if specified.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 91]
-
-RFC 4791 CalDAV March 2007
-
-
- +-------------------------------------------------------------------+
- | VTODO has the DTSTART property? |
- | +---------------------------------------------------------------+
- | | VTODO has the DURATION property? |
- | | +-----------------------------------------------------------+
- | | | VTODO has the DUE property? |
- | | | +-------------------------------------------------------+
- | | | | VTODO has the COMPLETED property? |
- | | | | +---------------------------------------------------+
- | | | | | VTODO has the CREATED property? |
- | | | | | +-----------------------------------------------+
- | | | | | | Condition to evaluate |
- +---+---+---+---+---+-----------------------------------------------+
- | Y | Y | N | * | * | (start <= DTSTART+DURATION) AND |
- | | | | | | ((end > DTSTART) OR |
- | | | | | | (end >= DTSTART+DURATION)) |
- +---+---+---+---+---+-----------------------------------------------+
- | Y | N | Y | * | * | ((start < DUE) OR (start <= DTSTART)) |
- | | | | | | AND |
- | | | | | | ((end > DTSTART) OR (end >= DUE)) |
- +---+---+---+---+---+-----------------------------------------------+
- | Y | N | N | * | * | (start <= DTSTART) AND (end > DTSTART) |
- +---+---+---+---+---+-----------------------------------------------+
- | N | N | Y | * | * | (start < DUE) AND (end >= DUE) |
- +---+---+---+---+---+-----------------------------------------------+
- | N | N | N | Y | Y | ((start <= CREATED) OR (start <= COMPLETED))|
- | | | | | | AND |
- | | | | | | ((end >= CREATED) OR (end >= COMPLETED))|
- +---+---+---+---+---+-----------------------------------------------+
- | N | N | N | Y | N | (start <= COMPLETED) AND (end >= COMPLETED) |
- +---+---+---+---+---+-----------------------------------------------+
- | N | N | N | N | Y | (end > CREATED) |
- +---+---+---+---+---+-----------------------------------------------+
- | N | N | N | N | N | TRUE |
- +---+---+---+---+---+-----------------------------------------------+
-
- A VJOURNAL component overlaps a given time range if the condition
- for the corresponding component state specified in the table below
- is satisfied. The conditions depend on the presence of the
- DTSTART property in the VJOURNAL component and on whether the
- DTSTART is a DATE-TIME or DATE value. The effective "duration" of
- a VJOURNAL component is 1 day (+P1D) when the DTSTART is a DATE
- value, and 0 seconds when the DTSTART is a DATE-TIME value.
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 92]
-
-RFC 4791 CalDAV March 2007
-
-
- +----------------------------------------------------+
- | VJOURNAL has the DTSTART property? |
- | +------------------------------------------------+
- | | DTSTART property is a DATE-TIME value? |
- | | +--------------------------------------------+
- | | | Condition to evaluate |
- +---+---+--------------------------------------------+
- | Y | Y | (start <= DTSTART) AND (end > DTSTART) |
- +---+---+--------------------------------------------+
- | Y | N | (start < DTSTART+P1D) AND (end > DTSTART) |
- +---+---+--------------------------------------------+
- | N | * | FALSE |
- +---+---+--------------------------------------------+
-
- A VFREEBUSY component overlaps a given time range if the condition
- for the corresponding component state specified in the table below
- is satisfied. The conditions depend on the presence in the
- VFREEBUSY component of the DTSTART and DTEND properties, and any
- FREEBUSY properties in the absence of DTSTART and DTEND. Any
- DURATION property is ignored, as it has a special meaning when
- used in a VFREEBUSY component.
-
- When only FREEBUSY properties are used, each period in each
- FREEBUSY property is compared against the time range, irrespective
- of the type of free busy information (free, busy, busy-tentative,
- busy-unavailable) represented by the property.
-
-
- +------------------------------------------------------+
- | VFREEBUSY has both the DTSTART and DTEND properties? |
- | +--------------------------------------------------+
- | | VFREEBUSY has the FREEBUSY property? |
- | | +----------------------------------------------+
- | | | Condition to evaluate |
- +---+---+----------------------------------------------+
- | Y | * | (start <= DTEND) AND (end > DTSTART) |
- +---+---+----------------------------------------------+
- | N | Y | (start < freebusy-period-end) AND |
- | | | (end > freebusy-period-start) |
- +---+---+----------------------------------------------+
- | N | N | FALSE |
- +---+---+----------------------------------------------+
-
- A VALARM component is said to overlap a given time range if the
- following condition holds:
-
- (start <= trigger-time) AND (end > trigger-time)
-
-
-
-
-Daboo, et al. Standards Track [Page 93]
-
-RFC 4791 CalDAV March 2007
-
-
- A VALARM component can be defined such that it triggers repeatedly.
- Such a VALARM component is said to overlap a given time range if at
- least one of its triggers overlaps the time range.
-
- The calendar properties COMPLETED, CREATED, DTEND, DTSTAMP,
- DTSTART, DUE, and LAST-MODIFIED overlap a given time range if the
- following condition holds:
-
- (start <= date-time) AND (end > date-time)
-
- Note that if DTEND is not present in a VEVENT, but DURATION is, then
- the test should instead operate on the 'effective' DTEND, i.e.,
- DTSTART+DURATION. Similarly, if DUE is not present in a VTODO, but
- DTSTART and DURATION are, then the test should instead operate on the
- 'effective' DUE, i.e., DTSTART+DURATION.
-
- The semantic of CALDAV:time-range is not defined for any other
- calendar components and properties.
-
- Definition:
-
-
-
-
- start value: an iCalendar "date with UTC time"
- end value: an iCalendar "date with UTC time"
-
-9.10. CALDAV:calendar-multiget XML Element
-
- Name: calendar-multiget
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: CalDAV report used to retrieve specific calendar object
- resources.
-
- Description: See Section 7.9.
-
- Definition:
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 94]
-
-RFC 4791 CalDAV March 2007
-
-
-9.11. CALDAV:free-busy-query XML Element
-
- Name: free-busy-query
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: CalDAV report used to generate a VFREEBUSY to determine
- busy time over a specific time range.
-
- Description: See Section 7.10.
-
- Definition:
-
-
-
-10. Internationalization Considerations
-
- CalDAV allows internationalized strings to be stored and retrieved
- for the description of calendar collections (see Section 5.2.1).
-
- The CALDAV:calendar-query REPORT (Section 7.8) includes a text
- searching option controlled by the CALDAV:text-match element, and
- details of character handling are covered in the description of that
- element (see Section 9.7.5).
-
-11. Security Considerations
-
- HTTP protocol transactions are sent in the clear over the network
- unless protection from snooping is negotiated. This can be
- accomplished by use of TLS, as defined in [RFC2818]. In particular,
- HTTP Basic authentication MUST NOT be used unless TLS is in effect.
-
- Servers MUST take adequate precautions to ensure that malicious
- clients cannot consume excessive server resources (CPU, memory, disk,
- etc.) through carefully crafted reports. For example, a client could
- upload an event with a recurrence rule that specifies a recurring
- event occurring every second for the next 100 years, which would
- result in approximately 3 x 10^9 instances! A report that asks for
- recurrences to be expanded over that range would likely constitute a
- denial-of-service attack on the server.
-
- When creating new resources (including calendar collections), clients
- MUST ensure that the resource name (the last path segment of the
- resource URI) assigned to the new resource does not expose any data
- from within the iCalendar resource itself or information about the
- nature of a calendar collection. This is required to ensure that the
- presence of a specific iCalendar component or nature of components in
- a collection cannot be inferred based on the name of a resource.
-
-
-
-Daboo, et al. Standards Track [Page 95]
-
-RFC 4791 CalDAV March 2007
-
-
- When rolling up free-busy information, more information about a
- user's events is exposed if busy periods overlap or are adjacent
- (this tells the client requesting the free-busy information that the
- calendar owner has at least two events, rather than knowing only that
- the calendar owner has one or more events during the busy period).
- Thus, a conservative approach to calendar data privacy would have
- servers always coalesce such busy periods when they are the same
- type.
-
- Procedure alarms are a known security risk for either clients or
- servers to handle, particularly when the alarm was created by another
- agent. Clients and servers are not required to execute such
- procedure alarms.
-
- Security considerations described in iCalendar [RFC2445] and iTIP
- [RFC2446] are also applicable to CalDAV.
-
- Beyond these, CalDAV does not raise any security considerations that
- are not present in HTTP [RFC2616] and WebDAV [RFC2518], [RFC3253],
- [RFC3744].
-
-12. IANA Considerations
-
- This document uses one new URN to identify a new XML namespace. The
- URN conforms to a registry mechanism described in [RFC3688].
-
-12.1. Namespace Registration
-
- Registration request for the CalDAV namespace:
-
- URI: urn:ietf:params:xml:ns:caldav
-
- Registrant Contact: See the "Authors' Addresses" section of this
- document.
-
- XML: None. Namespace URIs do not represent an XML specification.
-
-13. Acknowledgements
-
- The authors would like to thank the following individuals for
- contributing their ideas and support for writing this specification:
- Michael Arick, Mario Bonin, Chris Bryant, Scott Carr, Andre
- Courtemanche, Mike Douglass, Ted Hardie, Marten den Haring, Jeffrey
- Harris, Sam Hartman, Helge Hess, Jeff McCullough, Alexey Melnikov,
- Dan Mosedale, Brian Moseley, Francois Perrault, Kervin L. Pierre,
- Julian F. Reschke, Wilfredo Sanchez Vega, Mike Shaver, Jari
- Urpalainen, Simon Vaillancourt, and Jim Whitehead.
-
-
-
-
-Daboo, et al. Standards Track [Page 96]
-
-RFC 4791 CalDAV March 2007
-
-
- The authors would also like to thank the Calendaring and Scheduling
- Consortium for advice with this specification, and for organizing
- interoperability testing events to help refine it.
-
-14. References
-
-14.1. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to
- Indicate Requirement Levels", BCP 14,
- RFC 2119, March 1997.
-
- [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol
- Version 1.0", RFC 2246, January 1999.
-
- [RFC2445] Dawson, F. and Stenerson, D., "Internet
- Calendaring and Scheduling Core Object
- Specification (iCalendar)", RFC 2445,
- November 1998.
-
- [RFC2446] Silverberg, S., Mansour, S., Dawson, F., and
- R. Hopson, "iCalendar Transport-Independent
- Interoperability Protocol (iTIP) Scheduling
- Events, BusyTime, To-dos and Journal
- Entries", RFC 2446, November 1998.
-
- [RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter,
- S., and D. Jensen, "HTTP Extensions for
- Distributed Authoring -- WEBDAV", RFC 2518,
- February 1999.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk,
- H., Masinter, L., Leach, P., and T. Berners-
- Lee, "Hypertext Transfer Protocol --
- HTTP/1.1", RFC 2616, June 1999.
-
- [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818,
- May 2000.
-
- [RFC3253] Clemm, G., Amsden, J., Ellison, T., Kaler,
- C., and J. Whitehead, "Versioning Extensions
- to WebDAV (Web Distributed Authoring and
- Versioning)", RFC 3253, March 2002.
-
- [RFC3688] Mealling, M., "The IETF XML Registry",
- BCP 81, RFC 3688, January 2004.
-
-
-
-
-
-Daboo, et al. Standards Track [Page 97]
-
-RFC 4791 CalDAV March 2007
-
-
- [RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J.
- Whitehead, "Web Distributed Authoring and
- Versioning (WebDAV) Access Control Protocol",
- RFC 3744, May 2004.
-
- [RFC4346] Dierks, T. and E. Rescorla, "The Transport
- Layer Security (TLS) Protocol Version 1.1",
- RFC 4346, April 2006.
-
- [RFC4790] Newman, C., Duerst, M., and A. Gulbrandsen,
- "Internet Application Protocol Collation
- Registry", RFC 4790, March 2007.
-
- [W3C.REC-xml-20060816] Paoli, J., Maler, E., Yergeau, F., Sperberg-
- McQueen, C., and T. Bray, "Extensible Markup
- Language (XML) 1.0 (Fourth Edition)", World
- Wide Web Consortium Recommendation REC-xml-
- 20060816, August 2006,
- .
-
-14.2. Informative References
-
- [RFC2426] Dawson, F. and T. Howes, "vCard MIME
- Directory Profile", RFC 2426, September 1998.
-
- [RFC2739] Small, T., Hennessy, D., and F. Dawson,
- "Calendar Attributes for vCard and LDAP",
- RFC 2739, January 2000.
-
- [RFC4331] Korver, B. and L. Dusseault, "Quota and Size
- Properties for Distributed Authoring and
- Versioning (DAV) Collections", RFC 4331,
- February 2006.
-
- [RFC4511] Sermersheim, J., "Lightweight Directory
- Access Protocol (LDAP): The Protocol",
- RFC 4511, June 2006.
-
- [rfc2518bis] Dusseault, L., "HTTP Extensions for
- Distributed Authoring - WebDAV", Work
- in Progress, December 2006.
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 98]
-
-RFC 4791 CalDAV March 2007
-
-
-Appendix A. CalDAV Method Privilege Table (Normative)
-
- The following table extends the WebDAV Method Privilege Table
- specified in Appendix B of [RFC3744].
-
- +------------+------------------------------------------------------+
- | METHOD | PRIVILEGES |
- +------------+------------------------------------------------------+
- | MKCALENDAR | DAV:bind |
- | REPORT | DAV:read or CALDAV:read-free-busy (on all referenced |
- | | resources) |
- +------------+------------------------------------------------------+
-
-Appendix B. Calendar Collections Used in the Examples
-
- This appendix shows the calendar object resources contained in the
- calendar collection queried in the examples throughout this document.
-
- The content of the calendar collection is being shown as if it were
- returned by a CALDAV:calendar-query REPORT request designed to return
- all the calendar data in the collection:
-
- >> Request <<
-
- REPORT /bernard/work/ HTTP/1.1
- Host: cal.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-Daboo, et al. Standards Track [Page 99]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd1.ics
-
-
- "fffff-abcd1"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001102Z
- DTSTART;TZID=US/Eastern:20060102T100000
- DURATION:PT1H
- SUMMARY:Event #1
- Description:Go Steelers!
- UID:74855313FA803DA593CD579A@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd2.ics
-
-
-
-
-Daboo, et al. Standards Track [Page 100]
-
-RFC 4791 CalDAV March 2007
-
-
-
- "fffff-abcd2"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060102T120000
- DURATION:PT1H
- RRULE:FREQ=DAILY;COUNT=5
- SUMMARY:Event #2
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- BEGIN:VEVENT
- DTSTAMP:20060206T001121Z
- DTSTART;TZID=US/Eastern:20060104T140000
- DURATION:PT1H
- RECURRENCE-ID;TZID=US/Eastern:20060104T120000
- SUMMARY:Event #2 bis
- UID:00959BC664CA650E933C892C@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd3.ics
-
-
-
-Daboo, et al. Standards Track [Page 101]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
- "fffff-abcd3"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- LAST-MODIFIED:20040110T032845Z
- TZID:US/Eastern
- BEGIN:DAYLIGHT
- DTSTART:20000404T020000
- RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- BEGIN:STANDARD
- DTSTART:20001026T020000
- RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
- ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
- DTSTAMP:20060206T001220Z
- DTSTART;TZID=US/Eastern:20060104T100000
- DURATION:PT1H
- LAST-MODIFIED:20060206T001330Z
- ORGANIZER:mailto:cyrus@example.com
- SEQUENCE:1
- STATUS:TENTATIVE
- SUMMARY:Event #3
- UID:DC6C50A017428C5216A2F1CD@example.com
- END:VEVENT
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd4.ics
-
-
-
-
-
-Daboo, et al. Standards Track [Page 102]
-
-RFC 4791 CalDAV March 2007
-
-
- "fffff-abcd4"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- DTSTAMP:20060205T235335Z
- DUE;VALUE=DATE:20060104
- STATUS:NEEDS-ACTION
- SUMMARY:Task #1
- UID:DDDEEB7915FA61233B861457@example.com
- BEGIN:VALARM
- ACTION:AUDIO
- TRIGGER;RELATED=START:-PT10M
- END:VALARM
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd5.ics
-
-
- "fffff-abcd5"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- DTSTAMP:20060205T235300Z
- DUE;VALUE=DATE:20060106
- LAST-MODIFIED:20060205T235308Z
- SEQUENCE:1
- STATUS:NEEDS-ACTION
- SUMMARY:Task #2
- UID:E10BA47467C5C69BB74E8720@example.com
- BEGIN:VALARM
- ACTION:AUDIO
- TRIGGER;RELATED=START:-PT10M
- END:VALARM
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-Daboo, et al. Standards Track [Page 103]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd6.ics
-
-
- "fffff-abcd6"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- COMPLETED:20051223T122322Z
- DTSTAMP:20060205T235400Z
- DUE;VALUE=DATE:20051225
- LAST-MODIFIED:20060205T235308Z
- SEQUENCE:1
- STATUS:COMPLETED
- SUMMARY:Task #3
- UID:E10BA47467C5C69BB74E8722@example.com
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
- http://cal.example.com/bernard/work/abcd7.ics
-
-
- "fffff-abcd7"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTODO
- DTSTAMP:20060205T235600Z
- DUE;VALUE=DATE:20060101
- LAST-MODIFIED:20060205T235308Z
- SEQUENCE:1
- STATUS:CANCELLED
- SUMMARY:Task #4
- UID:E10BA47467C5C69BB74E8725@example.com
- END:VTODO
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-Daboo, et al. Standards Track [Page 104]
-
-RFC 4791 CalDAV March 2007
-
-
-
-
-
-
- http://cal.example.com/bernard/work/abcd8.ics
-
-
- "fffff-abcd8"
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VFREEBUSY
- ORGANIZER;CN="Bernard Desruisseaux":mailto:bernard@example.com
- UID:76ef34-54a3d2@example.com
- DTSTAMP:20050530T123421Z
- DTSTART:20060101T000000Z
- DTEND:20060108T000000Z
- FREEBUSY:20050531T230000Z/20050601T010000Z
- FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
- FREEBUSY:20060103T100000Z/20060103T120000Z
- FREEBUSY:20060104T100000Z/20060104T120000Z
- FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20060105T100000Z/20060105T120000Z
- FREEBUSY:20060106T100000Z/20060106T120000Z
- END:VFREEBUSY
- END:VCALENDAR
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 105]
-
-RFC 4791 CalDAV March 2007
-
-
-Authors' Addresses
-
- Cyrus Daboo
- Apple Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
- Bernard Desruisseaux
- Oracle Corporation
- 600 Blvd. de Maisonneuve West
- Suite 1900
- Montreal, QC H3A 3J2
- CANADA
-
- EMail: bernard.desruisseaux@oracle.com
- URI: http://www.oracle.com/
-
-
- Lisa Dusseault
- CommerceNet
- 169 University Ave.
- Palo Alto, CA 94301
- USA
-
- EMail: ldusseault@commerce.net
- URI: http://commerce.net/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 106]
-
-RFC 4791 CalDAV March 2007
-
-
-Full Copyright Statement
-
- Copyright (C) The IETF Trust (2007).
-
- This document is subject to the rights, licenses and restrictions
- contained in BCP 78, and except as set forth therein, the authors
- retain all their rights.
-
- This document and the information contained herein are provided on an
- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
- THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
- THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- Intellectual Property Rights or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; nor does it represent that it has
- made any independent effort to identify any such rights. Information
- on the procedures with respect to rights in RFC documents can be
- found in BCP 78 and BCP 79.
-
- Copies of IPR disclosures made to the IETF Secretariat and any
- assurances of licenses to be made available, or the result of an
- attempt made to obtain a general license or permission for the use of
- such proprietary rights by implementers or users of this
- specification can be obtained from the IETF on-line IPR repository at
- http://www.ietf.org/ipr.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights that may cover technology that may be required to implement
- this standard. Please address the information to the IETF at
- ietf-ipr@ietf.org.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-Daboo, et al. Standards Track [Page 107]
-
diff --git a/doc/rfc4918-webdav.txt b/doc/rfc4918-webdav.txt
deleted file mode 100644
index 4ef181bb..00000000
--- a/doc/rfc4918-webdav.txt
+++ /dev/null
@@ -1,7115 +0,0 @@
-
-
-
-
-
-
-Network Working Group L. Dusseault, Ed.
-Request for Comments: 4918 CommerceNet
-Obsoletes: 2518 June 2007
-Category: Standards Track
-
-
- HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)
-
-Status of This Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (C) The IETF Trust (2007).
-
-Abstract
-
- Web Distributed Authoring and Versioning (WebDAV) consists of a set
- of methods, headers, and content-types ancillary to HTTP/1.1 for the
- management of resource properties, creation and management of
- resource collections, URL namespace manipulation, and resource
- locking (collision avoidance).
-
- RFC 2518 was published in February 1999, and this specification
- obsoletes RFC 2518 with minor revisions mostly due to
- interoperability experience.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 1]
-
-RFC 4918 WebDAV June 2007
-
-
-Table of Contents
-
- 1. Introduction ....................................................7
- 2. Notational Conventions ..........................................8
- 3. Terminology .....................................................8
- 4. Data Model for Resource Properties .............................10
- 4.1. The Resource Property Model ...............................10
- 4.2. Properties and HTTP Headers ...............................10
- 4.3. Property Values ...........................................10
- 4.3.1. Example - Property with Mixed Content ..............12
- 4.4. Property Names ............................................14
- 4.5. Source Resources and Output Resources .....................14
- 5. Collections of Web Resources ...................................14
- 5.1. HTTP URL Namespace Model ..................................15
- 5.2. Collection Resources ......................................15
- 6. Locking ........................................................17
- 6.1. Lock Model ................................................18
- 6.2. Exclusive vs. Shared Locks ................................19
- 6.3. Required Support ..........................................20
- 6.4. Lock Creator and Privileges ...............................20
- 6.5. Lock Tokens ...............................................21
- 6.6. Lock Timeout ..............................................21
- 6.7. Lock Capability Discovery .................................22
- 6.8. Active Lock Discovery .....................................22
- 7. Write Lock .....................................................23
- 7.1. Write Locks and Properties ................................24
- 7.2. Avoiding Lost Updates .....................................24
- 7.3. Write Locks and Unmapped URLs .............................25
- 7.4. Write Locks and Collections ...............................26
- 7.5. Write Locks and the If Request Header .....................28
- 7.5.1. Example - Write Lock and COPY ......................28
- 7.5.2. Example - Deleting a Member of a Locked
- Collection .........................................29
- 7.6. Write Locks and COPY/MOVE .................................30
- 7.7. Refreshing Write Locks ....................................30
- 8. General Request and Response Handling ..........................31
- 8.1. Precedence in Error Handling ..............................31
- 8.2. Use of XML ................................................31
- 8.3. URL Handling ..............................................32
- 8.3.1. Example - Correct URL Handling .....................32
- 8.4. Required Bodies in Requests ...............................33
- 8.5. HTTP Headers for Use in WebDAV ............................33
- 8.6. ETag ......................................................33
- 8.7. Including Error Response Bodies ...........................34
- 8.8. Impact of Namespace Operations on Cache Validators ........34
- 9. HTTP Methods for Distributed Authoring .........................35
- 9.1. PROPFIND Method ...........................................35
- 9.1.1. PROPFIND Status Codes ..............................37
-
-
-
-Dusseault Standards Track [Page 2]
-
-RFC 4918 WebDAV June 2007
-
-
- 9.1.2. Status Codes for Use in 'propstat' Element .........37
- 9.1.3. Example - Retrieving Named Properties ..............38
- 9.1.4. Example - Using 'propname' to Retrieve All
- Property Names .....................................39
- 9.1.5. Example - Using So-called 'allprop' ................41
- 9.1.6. Example - Using 'allprop' with 'include' ...........43
- 9.2. PROPPATCH Method ..........................................44
- 9.2.1. Status Codes for Use in 'propstat' Element .........44
- 9.2.2. Example - PROPPATCH ................................45
- 9.3. MKCOL Method ..............................................46
- 9.3.1. MKCOL Status Codes .................................47
- 9.3.2. Example - MKCOL ....................................47
- 9.4. GET, HEAD for Collections .................................48
- 9.5. POST for Collections ......................................48
- 9.6. DELETE Requirements .......................................48
- 9.6.1. DELETE for Collections .............................49
- 9.6.2. Example - DELETE ...................................49
- 9.7. PUT Requirements ..........................................50
- 9.7.1. PUT for Non-Collection Resources ...................50
- 9.7.2. PUT for Collections ................................51
- 9.8. COPY Method ...............................................51
- 9.8.1. COPY for Non-collection Resources ..................51
- 9.8.2. COPY for Properties ................................52
- 9.8.3. COPY for Collections ...............................52
- 9.8.4. COPY and Overwriting Destination Resources .........53
- 9.8.5. Status Codes .......................................54
- 9.8.6. Example - COPY with Overwrite ......................55
- 9.8.7. Example - COPY with No Overwrite ...................55
- 9.8.8. Example - COPY of a Collection .....................56
- 9.9. MOVE Method ...............................................56
- 9.9.1. MOVE for Properties ................................57
- 9.9.2. MOVE for Collections ...............................57
- 9.9.3. MOVE and the Overwrite Header ......................58
- 9.9.4. Status Codes .......................................59
- 9.9.5. Example - MOVE of a Non-Collection .................60
- 9.9.6. Example - MOVE of a Collection .....................60
- 9.10. LOCK Method ..............................................61
- 9.10.1. Creating a Lock on an Existing Resource ...........61
- 9.10.2. Refreshing Locks ..................................62
- 9.10.3. Depth and Locking .................................62
- 9.10.4. Locking Unmapped URLs .............................63
- 9.10.5. Lock Compatibility Table ..........................63
- 9.10.6. LOCK Responses ....................................63
- 9.10.7. Example - Simple Lock Request .....................64
- 9.10.8. Example - Refreshing a Write Lock .................65
- 9.10.9. Example - Multi-Resource Lock Request .............66
- 9.11. UNLOCK Method ............................................68
- 9.11.1. Status Codes ......................................68
-
-
-
-Dusseault Standards Track [Page 3]
-
-RFC 4918 WebDAV June 2007
-
-
- 9.11.2. Example - UNLOCK ..................................69
- 10. HTTP Headers for Distributed Authoring ........................69
- 10.1. DAV Header ...............................................69
- 10.2. Depth Header .............................................70
- 10.3. Destination Header .......................................71
- 10.4. If Header ................................................72
- 10.4.1. Purpose ...........................................72
- 10.4.2. Syntax ............................................72
- 10.4.3. List Evaluation ...................................73
- 10.4.4. Matching State Tokens and ETags ...................74
- 10.4.5. If Header and Non-DAV-Aware Proxies ...............74
- 10.4.6. Example - No-tag Production .......................75
- 10.4.7. Example - Using "Not" with No-tag Production ......75
- 10.4.8. Example - Causing a Condition to Always
- Evaluate to True ..................................75
- 10.4.9. Example - Tagged List If Header in COPY ...........76
- 10.4.10. Example - Matching Lock Tokens with
- Collection Locks .................................76
- 10.4.11. Example - Matching ETags on Unmapped URLs ........76
- 10.5. Lock-Token Header ........................................77
- 10.6. Overwrite Header .........................................77
- 10.7. Timeout Request Header ...................................78
- 11. Status Code Extensions to HTTP/1.1 ............................78
- 11.1. 207 Multi-Status .........................................78
- 11.2. 422 Unprocessable Entity .................................78
- 11.3. 423 Locked ...............................................78
- 11.4. 424 Failed Dependency ....................................79
- 11.5. 507 Insufficient Storage .................................79
- 12. Use of HTTP Status Codes ......................................79
- 12.1. 412 Precondition Failed ..................................79
- 12.2. 414 Request-URI Too Long .................................79
- 13. Multi-Status Response .........................................80
- 13.1. Response Headers .........................................80
- 13.2. Handling Redirected Child Resources ......................81
- 13.3. Internal Status Codes ....................................81
- 14. XML Element Definitions .......................................81
- 14.1. activelock XML Element ...................................81
- 14.2. allprop XML Element ......................................82
- 14.3. collection XML Element ...................................82
- 14.4. depth XML Element ........................................82
- 14.5. error XML Element ........................................82
- 14.6. exclusive XML Element ....................................83
- 14.7. href XML Element .........................................83
- 14.8. include XML Element ......................................83
- 14.9. location XML Element .....................................83
- 14.10. lockentry XML Element ...................................84
- 14.11. lockinfo XML Element ....................................84
- 14.12. lockroot XML Element ....................................84
-
-
-
-Dusseault Standards Track [Page 4]
-
-RFC 4918 WebDAV June 2007
-
-
- 14.13. lockscope XML Element ...................................84
- 14.14. locktoken XML Element ...................................85
- 14.15. locktype XML Element ....................................85
- 14.16. multistatus XML Element .................................85
- 14.17. owner XML Element .......................................85
- 14.18. prop XML Element ........................................86
- 14.19. propertyupdate XML Element ..............................86
- 14.20. propfind XML Element ....................................86
- 14.21. propname XML Element ....................................87
- 14.22. propstat XML Element ....................................87
- 14.23. remove XML Element ......................................87
- 14.24. response XML Element ....................................88
- 14.25. responsedescription XML Element .........................88
- 14.26. set XML Element .........................................88
- 14.27. shared XML Element ......................................89
- 14.28. status XML Element ......................................89
- 14.29. timeout XML Element .....................................89
- 14.30. write XML Element .......................................89
- 15. DAV Properties ................................................90
- 16. Precondition/Postcondition XML Elements .......................98
- 17. XML Extensibility in DAV .....................................101
- 18. DAV Compliance Classes .......................................103
- 18.1. Class 1 .................................................103
- 18.2. Class 2 .................................................103
- 18.3. Class 3 .................................................103
- 19. Internationalization Considerations ..........................104
- 20. Security Considerations ......................................105
- 20.1. Authentication of Clients ...............................105
- 20.2. Denial of Service .......................................106
- 20.3. Security through Obscurity ..............................106
- 20.4. Privacy Issues Connected to Locks .......................106
- 20.5. Privacy Issues Connected to Properties ..................107
- 20.6. Implications of XML Entities ............................107
- 20.7. Risks Connected with Lock Tokens ........................108
- 20.8. Hosting Malicious Content ...............................108
- 21. IANA Considerations ..........................................109
- 21.1. New URI Schemes .........................................109
- 21.2. XML Namespaces ..........................................109
- 21.3. Message Header Fields ...................................109
- 21.3.1. DAV ..............................................109
- 21.3.2. Depth ............................................110
- 21.3.3. Destination ......................................110
- 21.3.4. If ...............................................110
- 21.3.5. Lock-Token .......................................110
- 21.3.6. Overwrite ........................................111
- 21.3.7. Timeout ..........................................111
- 21.4. HTTP Status Codes .......................................111
- 22. Acknowledgements .............................................112
-
-
-
-Dusseault Standards Track [Page 5]
-
-RFC 4918 WebDAV June 2007
-
-
- 23. Contributors to This Specification ...........................113
- 24. Authors of RFC 2518 ..........................................113
- 25. References ...................................................114
- 25.1. Normative References.....................................114
- 25.2. Informative References ..................................115
- Appendix A. Notes on Processing XML Elements ....................117
- A.1. Notes on Empty XML Elements ..............................117
- A.2. Notes on Illegal XML Processing ..........................117
- A.3. Example - XML Syntax Error ...............................117
- A.4. Example - Unexpected XML Element .........................118
- Appendix B. Notes on HTTP Client Compatibility ...................119
- Appendix C. The 'opaquelocktoken' Scheme and URIs ................120
- Appendix D. Lock-null Resources ..................................120
- D.1. Guidance for Clients Using LOCK to Create Resources ......121
- Appendix E. Guidance for Clients Desiring to Authenticate ........121
- Appendix F. Summary of Changes from RFC 2518 .....................123
- F.1. Changes for Both Client and Server Implementations .......123
- F.2. Changes for Server Implementations .......................125
- F.3. Other Changes ............................................126
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 6]
-
-RFC 4918 WebDAV June 2007
-
-
-1. Introduction
-
- This document describes an extension to the HTTP/1.1 protocol that
- allows clients to perform remote Web content authoring operations.
- This extension provides a coherent set of methods, headers, request
- entity body formats, and response entity body formats that provide
- operations for:
-
- Properties: The ability to create, remove, and query information
- about Web pages, such as their authors, creation dates, etc.
-
- Collections: The ability to create sets of documents and to retrieve
- a hierarchical membership listing (like a directory listing in a file
- system).
-
- Locking: The ability to keep more than one person from working on a
- document at the same time. This prevents the "lost update problem",
- in which modifications are lost as first one author, then another,
- writes changes without merging the other author's changes.
-
- Namespace Operations: The ability to instruct the server to copy and
- move Web resources, operations that change the mapping from URLs to
- resources.
-
- Requirements and rationale for these operations are described in a
- companion document, "Requirements for a Distributed Authoring and
- Versioning Protocol for the World Wide Web" [RFC2291].
-
- This document does not specify the versioning operations suggested by
- [RFC2291]. That work was done in a separate document, "Versioning
- Extensions to WebDAV" [RFC3253].
-
- The sections below provide a detailed introduction to various WebDAV
- abstractions: resource properties (Section 4), collections of
- resources (Section 5), locks (Section 6) in general, and write locks
- (Section 7) specifically.
-
- These abstractions are manipulated by the WebDAV-specific HTTP
- methods (Section 9) and the extra HTTP headers (Section 10) used with
- WebDAV methods. General considerations for handling HTTP requests
- and responses in WebDAV are found in Section 8.
-
- While the status codes provided by HTTP/1.1 are sufficient to
- describe most error conditions encountered by WebDAV methods, there
- are some errors that do not fall neatly into the existing categories.
- This specification defines extra status codes developed for WebDAV
- methods (Section 11) and describes existing HTTP status codes
- (Section 12) as used in WebDAV. Since some WebDAV methods may
-
-
-
-Dusseault Standards Track [Page 7]
-
-RFC 4918 WebDAV June 2007
-
-
- operate over many resources, the Multi-Status response (Section 13)
- has been introduced to return status information for multiple
- resources. Finally, this version of WebDAV introduces precondition
- and postcondition (Section 16) XML elements in error response bodies.
-
- WebDAV uses XML ([REC-XML]) for property names and some values, and
- also uses XML to marshal complicated requests and responses. This
- specification contains DTD and text definitions of all properties
- (Section 15) and all other XML elements (Section 14) used in
- marshalling. WebDAV includes a few special rules on extending WebDAV
- XML marshalling in backwards-compatible ways (Section 17).
-
- Finishing off the specification are sections on what it means for a
- resource to be compliant with this specification (Section 18), on
- internationalization support (Section 19), and on security
- (Section 20).
-
-2. Notational Conventions
-
- Since this document describes a set of extensions to the HTTP/1.1
- protocol, the augmented BNF used herein to describe protocol elements
- is exactly the same as described in Section 2.1 of [RFC2616],
- including the rules about implied linear whitespace. Since this
- augmented BNF uses the basic production rules provided in Section 2.2
- of [RFC2616], these rules apply to this document as well. Note this
- is not the standard BNF syntax used in other RFCs.
-
- 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].
-
- Note that in natural language, a property like the "creationdate"
- property in the "DAV:" XML namespace is sometimes referred to as
- "DAV:creationdate" for brevity.
-
-3. Terminology
-
- URI/URL - A Uniform Resource Identifier and Uniform Resource Locator,
- respectively. These terms (and the distinction between them) are
- defined in [RFC3986].
-
- URI/URL Mapping - A relation between an absolute URI and a resource.
- Since a resource can represent items that are not network
- retrievable, as well as those that are, it is possible for a resource
- to have zero, one, or many URI mappings. Mapping a resource to an
- "http" scheme URI makes it possible to submit HTTP protocol requests
- to the resource using the URI.
-
-
-
-
-Dusseault Standards Track [Page 8]
-
-RFC 4918 WebDAV June 2007
-
-
- Path Segment - Informally, the characters found between slashes ("/")
- in a URI. Formally, as defined in Section 3.3 of [RFC3986].
-
- Collection - Informally, a resource that also acts as a container of
- references to child resources. Formally, a resource that contains a
- set of mappings between path segments and resources and meets the
- requirements defined in Section 5.
-
- Internal Member (of a Collection) - Informally, a child resource of a
- collection. Formally, a resource referenced by a path segment
- mapping contained in the collection.
-
- Internal Member URL (of a Collection) - A URL of an internal member,
- consisting of the URL of the collection (including trailing slash)
- plus the path segment identifying the internal member.
-
- Member (of a Collection) - Informally, a "descendant" of a
- collection. Formally, an internal member of the collection, or,
- recursively, a member of an internal member.
-
- Member URL (of a Collection) - A URL that is either an internal
- member URL of the collection itself, or is an internal member URL of
- a member of that collection.
-
- Property - A name/value pair that contains descriptive information
- about a resource.
-
- Live Property - A property whose semantics and syntax are enforced by
- the server. For example, the live property DAV:getcontentlength has
- its value, the length of the entity returned by a GET request,
- automatically calculated by the server.
-
- Dead Property - A property whose semantics and syntax are not
- enforced by the server. The server only records the value of a dead
- property; the client is responsible for maintaining the consistency
- of the syntax and semantics of a dead property.
-
- Principal - A distinct human or computational actor that initiates
- access to network resources.
-
- State Token - A URI that represents a state of a resource. Lock
- tokens are the only state tokens defined in this specification.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 9]
-
-RFC 4918 WebDAV June 2007
-
-
-4. Data Model for Resource Properties
-
-4.1. The Resource Property Model
-
- Properties are pieces of data that describe the state of a resource.
- Properties are data about data.
-
- Properties are used in distributed authoring environments to provide
- for efficient discovery and management of resources. For example, a
- 'subject' property might allow for the indexing of all resources by
- their subject, and an 'author' property might allow for the discovery
- of what authors have written which documents.
-
- The DAV property model consists of name/value pairs. The name of a
- property identifies the property's syntax and semantics, and provides
- an address by which to refer to its syntax and semantics.
-
- There are two categories of properties: "live" and "dead". A live
- property has its syntax and semantics enforced by the server. Live
- properties include cases where a) the value of a property is
- protected and maintained by the server, and b) the value of the
- property is maintained by the client, but the server performs syntax
- checking on submitted values. All instances of a given live property
- MUST comply with the definition associated with that property name.
- A dead property has its syntax and semantics enforced by the client;
- the server merely records the value of the property verbatim.
-
-4.2. Properties and HTTP Headers
-
- Properties already exist, in a limited sense, in HTTP message
- headers. However, in distributed authoring environments, a
- relatively large number of properties are needed to describe the
- state of a resource, and setting/returning them all through HTTP
- headers is inefficient. Thus, a mechanism is needed that allows a
- principal to identify a set of properties in which the principal is
- interested and to set or retrieve just those properties.
-
-4.3. Property Values
-
- The value of a property is always a (well-formed) XML fragment.
-
- XML has been chosen because it is a flexible, self-describing,
- structured data format that supports rich schema definitions, and
- because of its support for multiple character sets. XML's self-
- describing nature allows any property's value to be extended by
- adding elements. Clients will not break when they encounter
- extensions because they will still have the data specified in the
- original schema and MUST ignore elements they do not understand.
-
-
-
-Dusseault Standards Track [Page 10]
-
-RFC 4918 WebDAV June 2007
-
-
- XML's support for multiple character sets allows any human-readable
- property to be encoded and read in a character set familiar to the
- user. XML's support for multiple human languages, using the "xml:
- lang" attribute, handles cases where the same character set is
- employed by multiple human languages. Note that xml:lang scope is
- recursive, so an xml:lang attribute on any element containing a
- property name element applies to the property value unless it has
- been overridden by a more locally scoped attribute. Note that a
- property only has one value, in one language (or language MAY be left
- undefined); a property does not have multiple values in different
- languages or a single value in multiple languages.
-
- A property is always represented with an XML element consisting of
- the property name, called the "property name element". The simplest
- example is an empty property, which is different from a property that
- does not exist:
-
-
-
- The value of the property appears inside the property name element.
- The value may be any kind of well-formed XML content, including both
- text-only and mixed content. Servers MUST preserve the following XML
- Information Items (using the terminology from [REC-XML-INFOSET]) in
- storage and transmission of dead properties:
-
- For the property name Element Information Item itself:
-
- [namespace name]
-
- [local name]
-
- [attributes] named "xml:lang" or any such attribute in scope
-
- [children] of type element or character
-
- On all Element Information Items in the property value:
-
- [namespace name]
-
- [local name]
-
- [attributes]
-
- [children] of type element or character
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 11]
-
-RFC 4918 WebDAV June 2007
-
-
- On Attribute Information Items in the property value:
-
- [namespace name]
-
- [local name]
-
- [normalized value]
-
- On Character Information Items in the property value:
-
- [character code]
-
- Since prefixes are used in some XML vocabularies (XPath and XML
- Schema, for example), servers SHOULD preserve, for any Information
- Item in the value:
-
- [prefix]
-
- XML Infoset attributes not listed above MAY be preserved by the
- server, but clients MUST NOT rely on them being preserved. The above
- rules would also apply by default to live properties, unless defined
- otherwise.
-
- Servers MUST ignore the XML attribute xml:space if present and never
- use it to change whitespace handling. Whitespace in property values
- is significant.
-
-4.3.1. Example - Property with Mixed Content
-
- Consider a dead property 'author' created by the client as follows:
-
-
-
- Jane Doe
-
- mailto:jane.doe@example.com
- http://www.example.com
-
- Jane has been working way too long on the
- long-awaited revision of ]]>.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 12]
-
-RFC 4918 WebDAV June 2007
-
-
- When this property is requested, a server might return:
-
-
- Jane Doe
- mailto:jane.doe@example.com
- http://www.example.com
-
- Jane has been working way too long on the
- long-awaited revision of <RFC2518>.
-
-
-
-
- Note in this example:
-
- o The [prefix] for the property name itself was not preserved, being
- non-significant, whereas all other [prefix] values have been
- preserved,
-
- o attribute values have been rewritten with double quotes instead of
- single quotes (quoting style is not significant), and attribute
- order has not been preserved,
-
- o the xml:lang attribute has been returned on the property name
- element itself (it was in scope when the property was set, but the
- exact position in the response is not considered significant as
- long as it is in scope),
-
- o whitespace between tags has been preserved everywhere (whitespace
- between attributes not so),
-
- o CDATA encapsulation was replaced with character escaping (the
- reverse would also be legal),
-
- o the comment item was stripped (as would have been a processing
- instruction item).
-
- Implementation note: there are cases such as editing scenarios where
- clients may require that XML content is preserved character by
- character (such as attribute ordering or quoting style). In this
- case, clients should consider using a text-only property value by
- escaping all characters that have a special meaning in XML parsing.
-
-
-
-Dusseault Standards Track [Page 13]
-
-RFC 4918 WebDAV June 2007
-
-
-4.4. Property Names
-
- A property name is a universally unique identifier that is associated
- with a schema that provides information about the syntax and
- semantics of the property.
-
- Because a property's name is universally unique, clients can depend
- upon consistent behavior for a particular property across multiple
- resources, on the same and across different servers, so long as that
- property is "live" on the resources in question, and the
- implementation of the live property is faithful to its definition.
-
- The XML namespace mechanism, which is based on URIs ([RFC3986]), is
- used to name properties because it prevents namespace collisions and
- provides for varying degrees of administrative control.
-
- The property namespace is flat; that is, no hierarchy of properties
- is explicitly recognized. Thus, if a property A and a property A/B
- exist on a resource, there is no recognition of any relationship
- between the two properties. It is expected that a separate
- specification will eventually be produced that will address issues
- relating to hierarchical properties.
-
- Finally, it is not possible to define the same property twice on a
- single resource, as this would cause a collision in the resource's
- property namespace.
-
-4.5. Source Resources and Output Resources
-
- Some HTTP resources are dynamically generated by the server. For
- these resources, there presumably exists source code somewhere
- governing how that resource is generated. The relationship of source
- files to output HTTP resources may be one to one, one to many, many
- to one, or many to many. There is no mechanism in HTTP to determine
- whether a resource is even dynamic, let alone where its source files
- exist or how to author them. Although this problem would usefully be
- solved, interoperable WebDAV implementations have been widely
- deployed without actually solving this problem, by dealing only with
- static resources. Thus, the source vs. output problem is not solved
- in this specification and has been deferred to a separate document.
-
-5. Collections of Web Resources
-
- This section provides a description of a type of Web resource, the
- collection, and discusses its interactions with the HTTP URL
- namespace and with HTTP methods. The purpose of a collection
- resource is to model collection-like objects (e.g., file system
- directories) within a server's namespace.
-
-
-
-Dusseault Standards Track [Page 14]
-
-RFC 4918 WebDAV June 2007
-
-
- All DAV-compliant resources MUST support the HTTP URL namespace model
- specified herein.
-
-5.1. HTTP URL Namespace Model
-
- The HTTP URL namespace is a hierarchical namespace where the
- hierarchy is delimited with the "/" character.
-
- An HTTP URL namespace is said to be consistent if it meets the
- following conditions: for every URL in the HTTP hierarchy there
- exists a collection that contains that URL as an internal member URL.
- The root, or top-level collection of the namespace under
- consideration, is exempt from the previous rule. The top-level
- collection of the namespace under consideration is not necessarily
- the collection identified by the absolute path '/' -- it may be
- identified by one or more path segments (e.g., /servlets/webdav/...)
-
- Neither HTTP/1.1 nor WebDAV requires that the entire HTTP URL
- namespace be consistent -- a WebDAV-compatible resource may not have
- a parent collection. However, certain WebDAV methods are prohibited
- from producing results that cause namespace inconsistencies.
-
- As is implicit in [RFC2616] and [RFC3986], any resource, including
- collection resources, MAY be identified by more than one URI. For
- example, a resource could be identified by multiple HTTP URLs.
-
-5.2. Collection Resources
-
- Collection resources differ from other resources in that they also
- act as containers. Some HTTP methods apply only to a collection, but
- some apply to some or all of the resources inside the container
- defined by the collection. When the scope of a method is not clear,
- the client can specify what depth to apply. Depth can be either zero
- levels (only the collection), one level (the collection and directly
- contained resources), or infinite levels (the collection and all
- contained resources recursively).
-
- A collection's state consists of at least a set of mappings between
- path segments and resources, and a set of properties on the
- collection itself. In this document, a resource B will be said to be
- contained in the collection resource A if there is a path segment
- mapping that maps to B and that is contained in A. A collection MUST
- contain at most one mapping for a given path segment, i.e., it is
- illegal to have the same path segment mapped to more than one
- resource.
-
-
-
-
-
-
-Dusseault Standards Track [Page 15]
-
-RFC 4918 WebDAV June 2007
-
-
- Properties defined on collections behave exactly as do properties on
- non-collection resources. A collection MAY have additional state
- such as entity bodies returned by GET.
-
- For all WebDAV-compliant resources A and B, identified by URLs "U"
- and "V", respectively, such that "V" is equal to "U/SEGMENT", A MUST
- be a collection that contains a mapping from "SEGMENT" to B. So, if
- resource B with URL "http://example.com/bar/blah" is WebDAV compliant
- and if resource A with URL "http://example.com/bar/" is WebDAV
- compliant, then resource A must be a collection and must contain
- exactly one mapping from "blah" to B.
-
- Although commonly a mapping consists of a single segment and a
- resource, in general, a mapping consists of a set of segments and a
- resource. This allows a server to treat a set of segments as
- equivalent (i.e., either all of the segments are mapped to the same
- resource, or none of the segments are mapped to a resource). For
- example, a server that performs case-folding on segments will treat
- the segments "ab", "Ab", "aB", and "AB" as equivalent. A client can
- then use any of these segments to identify the resource. Note that a
- PROPFIND result will select one of these equivalent segments to
- identify the mapping, so there will be one PROPFIND response element
- per mapping, not one per segment in the mapping.
-
- Collection resources MAY have mappings to non-WebDAV-compliant
- resources in the HTTP URL namespace hierarchy but are not required to
- do so. For example, if resource X with URL
- "http://example.com/bar/blah" is not WebDAV compliant and resource A
- with "URL http://example.com/bar/" identifies a WebDAV collection,
- then A may or may not have a mapping from "blah" to X.
-
- If a WebDAV-compliant resource has no WebDAV-compliant internal
- members in the HTTP URL namespace hierarchy, then the WebDAV-
- compliant resource is not required to be a collection.
-
- There is a standing convention that when a collection is referred to
- by its name without a trailing slash, the server MAY handle the
- request as if the trailing slash were present. In this case, it
- SHOULD return a Content-Location header in the response, pointing to
- the URL ending with the "/". For example, if a client invokes a
- method on http://example.com/blah (no trailing slash), the server may
- respond as if the operation were invoked on http://example.com/blah/
- (trailing slash), and should return a Content-Location header with
- the value http://example.com/blah/. Wherever a server produces a URL
- referring to a collection, the server SHOULD include the trailing
- slash. In general, clients SHOULD use the trailing slash form of
- collection names. If clients do not use the trailing slash form the
- client needs to be prepared to see a redirect response. Clients will
-
-
-
-Dusseault Standards Track [Page 16]
-
-RFC 4918 WebDAV June 2007
-
-
- find the DAV:resourcetype property more reliable than the URL to find
- out if a resource is a collection.
-
- Clients MUST be able to support the case where WebDAV resources are
- contained inside non-WebDAV resources. For example, if an OPTIONS
- response from "http://example.com/servlet/dav/collection" indicates
- WebDAV support, the client cannot assume that
- "http://example.com/servlet/dav/" or its parent necessarily are
- WebDAV collections.
-
- A typical scenario in which mapped URLs do not appear as members of
- their parent collection is the case where a server allows links or
- redirects to non-WebDAV resources. For instance, "/col/link" might
- not appear as a member of "/col/", although the server would respond
- with a 302 status to a GET request to "/col/link"; thus, the URL
- "/col/link" would indeed be mapped. Similarly, a dynamically-
- generated page might have a URL mapping from "/col/index.html", thus
- this resource might respond with a 200 OK to a GET request yet not
- appear as a member of "/col/".
-
- Some mappings to even WebDAV-compliant resources might not appear in
- the parent collection. An example for this case are servers that
- support multiple alias URLs for each WebDAV-compliant resource. A
- server may implement case-insensitive URLs, thus "/col/a" and
- "/col/A" identify the same resource, yet only either "a" or "A" is
- reported upon listing the members of "/col". In cases where a server
- treats a set of segments as equivalent, the server MUST expose only
- one preferred segment per mapping, consistently chosen, in PROPFIND
- responses.
-
-6. Locking
-
- The ability to lock a resource provides a mechanism for serializing
- access to that resource. Using a lock, an authoring client can
- provide a reasonable guarantee that another principal will not modify
- a resource while it is being edited. In this way, a client can
- prevent the "lost update" problem.
-
- This specification allows locks to vary over two client-specified
- parameters, the number of principals involved (exclusive vs. shared)
- and the type of access to be granted. This document defines locking
- for only one access type, write. However, the syntax is extensible,
- and permits the eventual specification of locking for other access
- types.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 17]
-
-RFC 4918 WebDAV June 2007
-
-
-6.1. Lock Model
-
- This section provides a concise model for how locking behaves. Later
- sections will provide more detail on some of the concepts and refer
- back to these model statements. Normative statements related to LOCK
- and UNLOCK method handling can be found in the sections on those
- methods, whereas normative statements that cover any method are
- gathered here.
-
- 1. A lock either directly or indirectly locks a resource.
-
- 2. A resource becomes directly locked when a LOCK request to a URL
- of that resource creates a new lock. The "lock-root" of the new
- lock is that URL. If at the time of the request, the URL is not
- mapped to a resource, a new empty resource is created and
- directly locked.
-
- 3. An exclusive lock (Section 6.2) conflicts with any other kind of
- lock on the same resource, whether either lock is direct or
- indirect. A server MUST NOT create conflicting locks on a
- resource.
-
- 4. For a collection that is locked with a depth-infinity lock L, all
- member resources are indirectly locked. Changes in membership of
- such a collection affect the set of indirectly locked resources:
-
- * If a member resource is added to the collection, the new
- member resource MUST NOT already have a conflicting lock,
- because the new resource MUST become indirectly locked by L.
-
- * If a member resource stops being a member of the collection,
- then the resource MUST no longer be indirectly locked by L.
-
- 5. Each lock is identified by a single globally unique lock token
- (Section 6.5).
-
- 6. An UNLOCK request deletes the lock with the specified lock token.
- After a lock is deleted, no resource is locked by that lock.
-
- 7. A lock token is "submitted" in a request when it appears in an
- "If" header (Section 7, "Write Lock", discusses when token
- submission is required for write locks).
-
- 8. If a request causes the lock-root of any lock to become an
- unmapped URL, then the lock MUST also be deleted by that request.
-
-
-
-
-
-
-Dusseault Standards Track [Page 18]
-
-RFC 4918 WebDAV June 2007
-
-
-6.2. Exclusive vs. Shared Locks
-
- The most basic form of lock is an exclusive lock. Exclusive locks
- avoid having to deal with content change conflicts, without requiring
- any coordination other than the methods described in this
- specification.
-
- However, there are times when the goal of a lock is not to exclude
- others from exercising an access right but rather to provide a
- mechanism for principals to indicate that they intend to exercise
- their access rights. Shared locks are provided for this case. A
- shared lock allows multiple principals to receive a lock. Hence any
- principal that has both access privileges and a valid lock can use
- the locked resource.
-
- With shared locks, there are two trust sets that affect a resource.
- The first trust set is created by access permissions. Principals who
- are trusted, for example, may have permission to write to the
- resource. Among those who have access permission to write to the
- resource, the set of principals who have taken out a shared lock also
- must trust each other, creating a (typically) smaller trust set
- within the access permission write set.
-
- Starting with every possible principal on the Internet, in most
- situations the vast majority of these principals will not have write
- access to a given resource. Of the small number who do have write
- access, some principals may decide to guarantee their edits are free
- from overwrite conflicts by using exclusive write locks. Others may
- decide they trust their collaborators will not overwrite their work
- (the potential set of collaborators being the set of principals who
- have write permission) and use a shared lock, which informs their
- collaborators that a principal may be working on the resource.
-
- The WebDAV extensions to HTTP do not need to provide all of the
- communications paths necessary for principals to coordinate their
- activities. When using shared locks, principals may use any out-of-
- band communication channel to coordinate their work (e.g., face-to-
- face interaction, written notes, post-it notes on the screen,
- telephone conversation, email, etc.) The intent of a shared lock is
- to let collaborators know who else may be working on a resource.
-
- Shared locks are included because experience from Web-distributed
- authoring systems has indicated that exclusive locks are often too
- rigid. An exclusive lock is used to enforce a particular editing
- process: take out an exclusive lock, read the resource, perform
- edits, write the resource, release the lock. This editing process
- has the problem that locks are not always properly released, for
- example, when a program crashes or when a lock creator leaves without
-
-
-
-Dusseault Standards Track [Page 19]
-
-RFC 4918 WebDAV June 2007
-
-
- unlocking a resource. While both timeouts (Section 6.6) and
- administrative action can be used to remove an offending lock,
- neither mechanism may be available when needed; the timeout may be
- long or the administrator may not be available.
-
- A successful request for a new shared lock MUST result in the
- generation of a unique lock associated with the requesting principal.
- Thus, if five principals have taken out shared write locks on the
- same resource, there will be five locks and five lock tokens, one for
- each principal.
-
-6.3. Required Support
-
- A WebDAV-compliant resource is not required to support locking in any
- form. If the resource does support locking, it may choose to support
- any combination of exclusive and shared locks for any access types.
-
- The reason for this flexibility is that locking policy strikes to the
- very heart of the resource management and versioning systems employed
- by various storage repositories. These repositories require control
- over what sort of locking will be made available. For example, some
- repositories only support shared write locks, while others only
- provide support for exclusive write locks, while yet others use no
- locking at all. As each system is sufficiently different to merit
- exclusion of certain locking features, this specification leaves
- locking as the sole axis of negotiation within WebDAV.
-
-6.4. Lock Creator and Privileges
-
- The creator of a lock has special privileges to use the lock to
- modify the resource. When a locked resource is modified, a server
- MUST check that the authenticated principal matches the lock creator
- (in addition to checking for valid lock token submission).
-
- The server MAY allow privileged users other than the lock creator to
- destroy a lock (for example, the resource owner or an administrator).
- The 'unlock' privilege in [RFC3744] was defined to provide that
- permission.
-
- There is no requirement for servers to accept LOCK requests from all
- users or from anonymous users.
-
- Note that having a lock does not confer full privilege to modify the
- locked resource. Write access and other privileges MUST be enforced
- through normal privilege or authentication mechanisms, not based on
- the possible obscurity of lock token values.
-
-
-
-
-
-Dusseault Standards Track [Page 20]
-
-RFC 4918 WebDAV June 2007
-
-
-6.5. Lock Tokens
-
- A lock token is a type of state token that identifies a particular
- lock. Each lock has exactly one unique lock token generated by the
- server. Clients MUST NOT attempt to interpret lock tokens in any
- way.
-
- Lock token URIs MUST be unique across all resources for all time.
- This uniqueness constraint allows lock tokens to be submitted across
- resources and servers without fear of confusion. Since lock tokens
- are unique, a client MAY submit a lock token in an If header on a
- resource other than the one that returned it.
-
- When a LOCK operation creates a new lock, the new lock token is
- returned in the Lock-Token response header defined in Section 10.5,
- and also in the body of the response.
-
- Servers MAY make lock tokens publicly readable (e.g., in the DAV:
- lockdiscovery property). One use case for making lock tokens
- readable is so that a long-lived lock can be removed by the resource
- owner (the client that obtained the lock might have crashed or
- disconnected before cleaning up the lock). Except for the case of
- using UNLOCK under user guidance, a client SHOULD NOT use a lock
- token created by another client instance.
-
- This specification encourages servers to create Universally Unique
- Identifiers (UUIDs) for lock tokens, and to use the URI form defined
- by "A Universally Unique Identifier (UUID) URN Namespace"
- ([RFC4122]). However, servers are free to use any URI (e.g., from
- another scheme) so long as it meets the uniqueness requirements. For
- example, a valid lock token might be constructed using the
- "opaquelocktoken" scheme defined in Appendix C.
-
- Example: "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
-
-6.6. Lock Timeout
-
- A lock MAY have a limited lifetime. The lifetime is suggested by the
- client when creating or refreshing the lock, but the server
- ultimately chooses the timeout value. Timeout is measured in seconds
- remaining until lock expiration.
-
- The timeout counter MUST be restarted if a refresh lock request is
- successful (see Section 9.10.2). The timeout counter SHOULD NOT be
- restarted at any other time.
-
- If the timeout expires, then the lock SHOULD be removed. In this
- case the server SHOULD act as if an UNLOCK method was executed by the
-
-
-
-Dusseault Standards Track [Page 21]
-
-RFC 4918 WebDAV June 2007
-
-
- server on the resource using the lock token of the timed-out lock,
- performed with its override authority.
-
- Servers are advised to pay close attention to the values submitted by
- clients, as they will be indicative of the type of activity the
- client intends to perform. For example, an applet running in a
- browser may need to lock a resource, but because of the instability
- of the environment within which the applet is running, the applet may
- be turned off without warning. As a result, the applet is likely to
- ask for a relatively small timeout value so that if the applet dies,
- the lock can be quickly harvested. However, a document management
- system is likely to ask for an extremely long timeout because its
- user may be planning on going offline.
-
- A client MUST NOT assume that just because the timeout has expired,
- the lock has immediately been removed.
-
- Likewise, a client MUST NOT assume that just because the timeout has
- not expired, the lock still exists. Clients MUST assume that locks
- can arbitrarily disappear at any time, regardless of the value given
- in the Timeout header. The Timeout header only indicates the
- behavior of the server if extraordinary circumstances do not occur.
- For example, a sufficiently privileged user may remove a lock at any
- time, or the system may crash in such a way that it loses the record
- of the lock's existence.
-
-6.7. Lock Capability Discovery
-
- Since server lock support is optional, a client trying to lock a
- resource on a server can either try the lock and hope for the best,
- or perform some form of discovery to determine what lock capabilities
- the server supports. This is known as lock capability discovery. A
- client can determine what lock types the server supports by
- retrieving the DAV:supportedlock property.
-
- Any DAV-compliant resource that supports the LOCK method MUST support
- the DAV:supportedlock property.
-
-6.8. Active Lock Discovery
-
- If another principal locks a resource that a principal wishes to
- access, it is useful for the second principal to be able to find out
- who the first principal is. For this purpose the DAV:lockdiscovery
- property is provided. This property lists all outstanding locks,
- describes their type, and MAY even provide the lock tokens.
-
- Any DAV-compliant resource that supports the LOCK method MUST support
- the DAV:lockdiscovery property.
-
-
-
-Dusseault Standards Track [Page 22]
-
-RFC 4918 WebDAV June 2007
-
-
-7. Write Lock
-
- This section describes the semantics specific to the write lock type.
- The write lock is a specific instance of a lock type, and is the only
- lock type described in this specification.
-
- An exclusive write lock protects a resource: it prevents changes by
- any principal other than the lock creator and in any case where the
- lock token is not submitted (e.g., by a client process other than the
- one holding the lock).
-
- Clients MUST submit a lock-token they are authorized to use in any
- request that modifies a write-locked resource. The list of
- modifications covered by a write-lock include:
-
- 1. A change to any of the following aspects of any write-locked
- resource:
-
- * any variant,
-
- * any dead property,
-
- * any live property that is lockable (a live property is
- lockable unless otherwise defined.)
-
- 2. For collections, any modification of an internal member URI. An
- internal member URI of a collection is considered to be modified
- if it is added, removed, or identifies a different resource.
- More discussion on write locks and collections is found in
- Section 7.4.
-
- 3. A modification of the mapping of the root of the write lock,
- either to another resource or to no resource (e.g., DELETE).
-
- Of the methods defined in HTTP and WebDAV, PUT, POST, PROPPATCH,
- LOCK, UNLOCK, MOVE, COPY (for the destination resource), DELETE, and
- MKCOL are affected by write locks. All other HTTP/WebDAV methods
- defined so far -- GET in particular -- function independently of a
- write lock.
-
- The next few sections describe in more specific terms how write locks
- interact with various operations.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 23]
-
-RFC 4918 WebDAV June 2007
-
-
-7.1. Write Locks and Properties
-
- While those without a write lock may not alter a property on a
- resource it is still possible for the values of live properties to
- change, even while locked, due to the requirements of their schemas.
- Only dead properties and live properties defined as lockable are
- guaranteed not to change while write locked.
-
-7.2. Avoiding Lost Updates
-
- Although the write locks provide some help in preventing lost
- updates, they cannot guarantee that updates will never be lost.
- Consider the following scenario:
-
- Two clients A and B are interested in editing the resource
- 'index.html'. Client A is an HTTP client rather than a WebDAV
- client, and so does not know how to perform locking.
-
- Client A doesn't lock the document, but does a GET, and begins
- editing.
-
- Client B does LOCK, performs a GET and begins editing.
-
- Client B finishes editing, performs a PUT, then an UNLOCK.
-
- Client A performs a PUT, overwriting and losing all of B's changes.
-
- There are several reasons why the WebDAV protocol itself cannot
- prevent this situation. First, it cannot force all clients to use
- locking because it must be compatible with HTTP clients that do not
- comprehend locking. Second, it cannot require servers to support
- locking because of the variety of repository implementations, some of
- which rely on reservations and merging rather than on locking.
- Finally, being stateless, it cannot enforce a sequence of operations
- like LOCK / GET / PUT / UNLOCK.
-
- WebDAV servers that support locking can reduce the likelihood that
- clients will accidentally overwrite each other's changes by requiring
- clients to lock resources before modifying them. Such servers would
- effectively prevent HTTP 1.0 and HTTP 1.1 clients from modifying
- resources.
-
- WebDAV clients can be good citizens by using a lock / retrieve /
- write /unlock sequence of operations (at least by default) whenever
- they interact with a WebDAV server that supports locking.
-
-
-
-
-
-
-Dusseault Standards Track [Page 24]
-
-RFC 4918 WebDAV June 2007
-
-
- HTTP 1.1 clients can be good citizens, avoiding overwriting other
- clients' changes, by using entity tags in If-Match headers with any
- requests that would modify resources.
-
- Information managers may attempt to prevent overwrites by
- implementing client-side procedures requiring locking before
- modifying WebDAV resources.
-
-7.3. Write Locks and Unmapped URLs
-
- WebDAV provides the ability to send a LOCK request to an unmapped URL
- in order to reserve the name for use. This is a simple way to avoid
- the lost-update problem on the creation of a new resource (another
- way is to use If-None-Match header specified in Section 14.26 of
- [RFC2616]). It has the side benefit of locking the new resource
- immediately for use of the creator.
-
- Note that the lost-update problem is not an issue for collections
- because MKCOL can only be used to create a collection, not to
- overwrite an existing collection. When trying to lock a collection
- upon creation, clients can attempt to increase the likelihood of
- getting the lock by pipelining the MKCOL and LOCK requests together
- (but because this doesn't convert two separate operations into one
- atomic operation, there's no guarantee this will work).
-
- A successful lock request to an unmapped URL MUST result in the
- creation of a locked (non-collection) resource with empty content.
- Subsequently, a successful PUT request (with the correct lock token)
- provides the content for the resource. Note that the LOCK request
- has no mechanism for the client to provide Content-Type or Content-
- Language, thus the server will use defaults or empty values and rely
- on the subsequent PUT request for correct values.
-
- A resource created with a LOCK is empty but otherwise behaves in
- every way as a normal resource. It behaves the same way as a
- resource created by a PUT request with an empty body (and where a
- Content-Type and Content-Language was not specified), followed by a
- LOCK request to the same resource. Following from this model, a
- locked empty resource:
-
- o Can be read, deleted, moved, and copied, and in all ways behaves
- as a regular non-collection resource.
-
- o Appears as a member of its parent collection.
-
- o SHOULD NOT disappear when its lock goes away (clients must
- therefore be responsible for cleaning up their own mess, as with
- any other operation or any non-empty resource).
-
-
-
-Dusseault Standards Track [Page 25]
-
-RFC 4918 WebDAV June 2007
-
-
- o MAY NOT have values for properties like DAV:getcontentlanguage
- that haven't been specified yet by the client.
-
- o Can be updated (have content added) with a PUT request.
-
- o MUST NOT be converted into a collection. The server MUST fail a
- MKCOL request (as it would with a MKCOL request to any existing
- non-collection resource).
-
- o MUST have defined values for DAV:lockdiscovery and DAV:
- supportedlock properties.
-
- o The response MUST indicate that a resource was created, by use of
- the "201 Created" response code (a LOCK request to an existing
- resource instead will result in 200 OK). The body must still
- include the DAV:lockdiscovery property, as with a LOCK request to
- an existing resource.
-
- The client is expected to update the locked empty resource shortly
- after locking it, using PUT and possibly PROPPATCH.
-
- Alternatively and for backwards compatibility to [RFC2518], servers
- MAY implement Lock-Null Resources (LNRs) instead (see definition in
- Appendix D). Clients can easily interoperate both with servers that
- support the old model LNRs and the recommended model of "locked empty
- resources" by only attempting PUT after a LOCK to an unmapped URL,
- not MKCOL or GET, and by not relying on specific properties of LNRs.
-
-7.4. Write Locks and Collections
-
- There are two kinds of collection write locks. A depth-0 write lock
- on a collection protects the collection properties plus the internal
- member URLs of that one collection, while not protecting the content
- or properties of member resources (if the collection itself has any
- entity bodies, those are also protected). A depth-infinity write
- lock on a collection provides the same protection on that collection
- and also provides write lock protection on every member resource.
-
- Expressed otherwise, a write lock of either kind protects any request
- that would create a new resource in a write locked collection, any
- request that would remove an internal member URL of a write locked
- collection, and any request that would change the segment name of any
- internal member.
-
- Thus, a collection write lock protects all the following actions:
-
- o DELETE a collection's direct internal member,
-
-
-
-
-Dusseault Standards Track [Page 26]
-
-RFC 4918 WebDAV June 2007
-
-
- o MOVE an internal member out of the collection,
-
- o MOVE an internal member into the collection,
-
- o MOVE to rename an internal member within a collection,
-
- o COPY an internal member into a collection, and
-
- o PUT or MKCOL request that would create a new internal member.
-
- The collection's lock token is required in addition to the lock token
- on the internal member itself, if it is locked separately.
-
- In addition, a depth-infinity lock affects all write operations to
- all members of the locked collection. With a depth-infinity lock,
- the resource identified by the root of the lock is directly locked,
- and all its members are indirectly locked.
-
- o Any new resource added as a descendant of a depth-infinity locked
- collection becomes indirectly locked.
-
- o Any indirectly locked resource moved out of the locked collection
- into an unlocked collection is thereafter unlocked.
-
- o Any indirectly locked resource moved out of a locked source
- collection into a depth-infinity locked target collection remains
- indirectly locked but is now protected by the lock on the target
- collection (the target collection's lock token will thereafter be
- required to make further changes).
-
- If a depth-infinity write LOCK request is issued to a collection
- containing member URLs identifying resources that are currently
- locked in a manner that conflicts with the new lock (see Section 6.1,
- point 3), the request MUST fail with a 423 (Locked) status code, and
- the response SHOULD contain the 'no-conflicting-lock' precondition.
-
- If a lock request causes the URL of a resource to be added as an
- internal member URL of a depth-infinity locked collection, then the
- new resource MUST be automatically protected by the lock. For
- example, if the collection /a/b/ is write locked and the resource /c
- is moved to /a/b/c, then resource /a/b/c will be added to the write
- lock.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 27]
-
-RFC 4918 WebDAV June 2007
-
-
-7.5. Write Locks and the If Request Header
-
- A user agent has to demonstrate knowledge of a lock when requesting
- an operation on a locked resource. Otherwise, the following scenario
- might occur. In the scenario, program A, run by User A, takes out a
- write lock on a resource. Program B, also run by User A, has no
- knowledge of the lock taken out by program A, yet performs a PUT to
- the locked resource. In this scenario, the PUT succeeds because
- locks are associated with a principal, not a program, and thus
- program B, because it is acting with principal A's credential, is
- allowed to perform the PUT. However, had program B known about the
- lock, it would not have overwritten the resource, preferring instead
- to present a dialog box describing the conflict to the user. Due to
- this scenario, a mechanism is needed to prevent different programs
- from accidentally ignoring locks taken out by other programs with the
- same authorization.
-
- In order to prevent these collisions, a lock token MUST be submitted
- by an authorized principal for all locked resources that a method may
- change or the method MUST fail. A lock token is submitted when it
- appears in an If header. For example, if a resource is to be moved
- and both the source and destination are locked, then two lock tokens
- must be submitted in the If header, one for the source and the other
- for the destination.
-
-7.5.1. Example - Write Lock and COPY
-
- >>Request
-
- COPY /~fielding/index.html HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/users/f/fielding/index.html
- If:
- ()
-
- >>Response
-
- HTTP/1.1 204 No Content
-
- In this example, even though both the source and destination are
- locked, only one lock token must be submitted (the one for the lock
- on the destination). This is because the source resource is not
- modified by a COPY, and hence unaffected by the write lock. In this
- example, user agent authentication has previously occurred via a
- mechanism outside the scope of the HTTP protocol, in the underlying
- transport layer.
-
-
-
-
-
-Dusseault Standards Track [Page 28]
-
-RFC 4918 WebDAV June 2007
-
-
-7.5.2. Example - Deleting a Member of a Locked Collection
-
- Consider a collection "/locked" with an exclusive, depth-infinity
- write lock, and an attempt to delete an internal member "/locked/
- member":
-
- >>Request
-
- DELETE /locked/member HTTP/1.1
- Host: example.com
-
- >>Response
-
- HTTP/1.1 423 Locked
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /locked/
-
-
-
- Thus, the client would need to submit the lock token with the request
- to make it succeed. To do that, various forms of the If header (see
- Section 10.4) could be used.
-
- "No-Tag-List" format:
-
- If: ()
-
- "Tagged-List" format, for "http://example.com/locked/":
-
- If:
- ()
-
- "Tagged-List" format, for "http://example.com/locked/member":
-
- If:
- ()
-
- Note that, for the purpose of submitting the lock token, the actual
- form doesn't matter; what's relevant is that the lock token appears
- in the If header, and that the If header itself evaluates to true.
-
-
-
-
-
-
-Dusseault Standards Track [Page 29]
-
-RFC 4918 WebDAV June 2007
-
-
-7.6. Write Locks and COPY/MOVE
-
- A COPY method invocation MUST NOT duplicate any write locks active on
- the source. However, as previously noted, if the COPY copies the
- resource into a collection that is locked with a depth-infinity lock,
- then the resource will be added to the lock.
-
- A successful MOVE request on a write locked resource MUST NOT move
- the write lock with the resource. However, if there is an existing
- lock at the destination, the server MUST add the moved resource to
- the destination lock scope. For example, if the MOVE makes the
- resource a child of a collection that has a depth-infinity lock, then
- the resource will be added to that collection's lock. Additionally,
- if a resource with a depth-infinity lock is moved to a destination
- that is within the scope of the same lock (e.g., within the URL
- namespace tree covered by the lock), the moved resource will again be
- added to the lock. In both these examples, as specified in
- Section 7.5, an If header must be submitted containing a lock token
- for both the source and destination.
-
-7.7. Refreshing Write Locks
-
- A client MUST NOT submit the same write lock request twice. Note
- that a client is always aware it is resubmitting the same lock
- request because it must include the lock token in the If header in
- order to make the request for a resource that is already locked.
-
- However, a client may submit a LOCK request with an If header but
- without a body. A server receiving a LOCK request with no body MUST
- NOT create a new lock -- this form of the LOCK request is only to be
- used to "refresh" an existing lock (meaning, at minimum, that any
- timers associated with the lock MUST be reset).
-
- Clients may submit Timeout headers of arbitrary value with their lock
- refresh requests. Servers, as always, may ignore Timeout headers
- submitted by the client, and a server MAY refresh a lock with a
- timeout period that is different than the previous timeout period
- used for the lock, provided it advertises the new value in the LOCK
- refresh response.
-
- If an error is received in response to a refresh LOCK request, the
- client MUST NOT assume that the lock was refreshed.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 30]
-
-RFC 4918 WebDAV June 2007
-
-
-8. General Request and Response Handling
-
-8.1. Precedence in Error Handling
-
- Servers MUST return authorization errors in preference to other
- errors. This avoids leaking information about protected resources
- (e.g., a client that finds that a hidden resource exists by seeing a
- 423 Locked response to an anonymous request to the resource).
-
-8.2. Use of XML
-
- In HTTP/1.1, method parameter information was exclusively encoded in
- HTTP headers. Unlike HTTP/1.1, WebDAV encodes method parameter
- information either in an XML ([REC-XML]) request entity body, or in
- an HTTP header. The use of XML to encode method parameters was
- motivated by the ability to add extra XML elements to existing
- structures, providing extensibility; and by XML's ability to encode
- information in ISO 10646 character sets, providing
- internationalization support.
-
- In addition to encoding method parameters, XML is used in WebDAV to
- encode the responses from methods, providing the extensibility and
- internationalization advantages of XML for method output, as well as
- input.
-
- When XML is used for a request or response body, the Content-Type
- type SHOULD be application/xml. Implementations MUST accept both
- text/xml and application/xml in request and response bodies. Use of
- text/xml is deprecated.
-
- All DAV-compliant clients and resources MUST use XML parsers that are
- compliant with [REC-XML] and [REC-XML-NAMES]. All XML used in either
- requests or responses MUST be, at minimum, well formed and use
- namespaces correctly. If a server receives XML that is not well-
- formed, then the server MUST reject the entire request with a 400
- (Bad Request). If a client receives XML that is not well-formed in a
- response, then the client MUST NOT assume anything about the outcome
- of the executed method and SHOULD treat the server as malfunctioning.
-
- Note that processing XML submitted by an untrusted source may cause
- risks connected to privacy, security, and service quality (see
- Section 20). Servers MAY reject questionable requests (even though
- they consist of well-formed XML), for instance, with a 400 (Bad
- Request) status code and an optional response body explaining the
- problem.
-
-
-
-
-
-
-Dusseault Standards Track [Page 31]
-
-RFC 4918 WebDAV June 2007
-
-
-8.3. URL Handling
-
- URLs appear in many places in requests and responses.
- Interoperability experience with [RFC2518] showed that many clients
- parsing Multi-Status responses did not fully implement the full
- Reference Resolution defined in Section 5 of [RFC3986]. Thus,
- servers in particular need to be careful in handling URLs in
- responses, to ensure that clients have enough context to be able to
- interpret all the URLs. The rules in this section apply not only to
- resource URLs in the 'href' element in Multi-Status responses, but
- also to the Destination and If header resource URLs.
-
- The sender has a choice between two approaches: using a relative
- reference, which is resolved against the Request-URI, or a full URI.
- A server MUST ensure that every 'href' value within a Multi-Status
- response uses the same format.
-
- WebDAV only uses one form of relative reference in its extensions,
- the absolute path.
-
- Simple-ref = absolute-URI | ( path-absolute [ "?" query ] )
-
- The absolute-URI, path-absolute and query productions are defined in
- Sections 4.3, 3.3, and 3.4 of [RFC3986].
-
- Within Simple-ref productions, senders MUST NOT:
-
- o use dot-segments ("." or ".."), or
-
- o have prefixes that do not match the Request-URI (using the
- comparison rules defined in Section 3.2.3 of [RFC2616]).
-
- Identifiers for collections SHOULD end in a '/' character.
-
-8.3.1. Example - Correct URL Handling
-
- Consider the collection http://example.com/sample/ with the internal
- member URL http://example.com/sample/a%20test and the PROPFIND
- request below:
-
- >>Request:
-
- PROPFIND /sample/ HTTP/1.1
- Host: example.com
- Depth: 1
-
-
-
-
-
-
-Dusseault Standards Track [Page 32]
-
-RFC 4918 WebDAV June 2007
-
-
- In this case, the server should return two 'href' elements containing
- either
-
- o 'http://example.com/sample/' and
- 'http://example.com/sample/a%20test', or
-
- o '/sample/' and '/sample/a%20test'
-
- Note that even though the server may be storing the member resource
- internally as 'a test', it has to be percent-encoded when used inside
- a URI reference (see Section 2.1 of [RFC3986]). Also note that a
- legal URI may still contain characters that need to be escaped within
- XML character data, such as the ampersand character.
-
-8.4. Required Bodies in Requests
-
- Some of these new methods do not define bodies. Servers MUST examine
- all requests for a body, even when a body was not expected. In cases
- where a request body is present but would be ignored by a server, the
- server MUST reject the request with 415 (Unsupported Media Type).
- This informs the client (which may have been attempting to use an
- extension) that the body could not be processed as the client
- intended.
-
-8.5. HTTP Headers for Use in WebDAV
-
- HTTP defines many headers that can be used in WebDAV requests and
- responses. Not all of these are appropriate in all situations and
- some interactions may be undefined. Note that HTTP 1.1 requires the
- Date header in all responses if possible (see Section 14.18,
- [RFC2616]).
-
- The server MUST do authorization checks before checking any HTTP
- conditional header.
-
-8.6. ETag
-
- HTTP 1.1 recommends the use of ETags rather than modification dates,
- for cache control, and there are even stronger reasons to prefer
- ETags for authoring. Correct use of ETags is even more important in
- a distributed authoring environment, because ETags are necessary
- along with locks to avoid the lost-update problem. A client might
- fail to renew a lock, for example, when the lock times out and the
- client is accidentally offline or in the middle of a long upload.
- When a client fails to renew the lock, it's quite possible the
- resource can still be relocked and the user can go on editing, as
- long as no changes were made in the meantime. ETags are required for
- the client to be able to distinguish this case. Otherwise, the
-
-
-
-Dusseault Standards Track [Page 33]
-
-RFC 4918 WebDAV June 2007
-
-
- client is forced to ask the user whether to overwrite the resource on
- the server without even being able to tell the user if it has
- changed. Timestamps do not solve this problem nearly as well as
- ETags.
-
- Strong ETags are much more useful for authoring use cases than weak
- ETags (see Section 13.3.3 of [RFC2616]). Semantic equivalence can be
- a useful concept but that depends on the document type and the
- application type, and interoperability might require some agreement
- or standard outside the scope of this specification and HTTP. Note
- also that weak ETags have certain restrictions in HTTP, e.g., these
- cannot be used in If-Match headers.
-
- Note that the meaning of an ETag in a PUT response is not clearly
- defined either in this document or in RFC 2616 (i.e., whether the
- ETag means that the resource is octet-for-octet equivalent to the
- body of the PUT request, or whether the server could have made minor
- changes in the formatting or content of the document upon storage).
- This is an HTTP issue, not purely a WebDAV issue.
-
- Because clients may be forced to prompt users or throw away changed
- content if the ETag changes, a WebDAV server SHOULD NOT change the
- ETag (or the Last-Modified time) for a resource that has an unchanged
- body and location. The ETag represents the state of the body or
- contents of the resource. There is no similar way to tell if
- properties have changed.
-
-8.7. Including Error Response Bodies
-
- HTTP and WebDAV did not use the bodies of most error responses for
- machine-parsable information until the specification for Versioning
- Extensions to WebDAV introduced a mechanism to include more specific
- information in the body of an error response (Section 1.6 of
- [RFC3253]). The error body mechanism is appropriate to use with any
- error response that may take a body but does not already have a body
- defined. The mechanism is particularly appropriate when a status
- code can mean many things (for example, 400 Bad Request can mean
- required headers are missing, headers are incorrectly formatted, or
- much more). This error body mechanism is covered in Section 16.
-
-8.8. Impact of Namespace Operations on Cache Validators
-
- Note that the HTTP response headers "Etag" and "Last-Modified" (see
- [RFC2616], Sections 14.19 and 14.29) are defined per URL (not per
- resource), and are used by clients for caching. Therefore servers
- must ensure that executing any operation that affects the URL
- namespace (such as COPY, MOVE, DELETE, PUT, or MKCOL) does preserve
- their semantics, in particular:
-
-
-
-Dusseault Standards Track [Page 34]
-
-RFC 4918 WebDAV June 2007
-
-
- o For any given URL, the "Last-Modified" value MUST increment every
- time the representation returned upon GET changes (within the
- limits of timestamp resolution).
-
- o For any given URL, an "ETag" value MUST NOT be reused for
- different representations returned by GET.
-
- In practice this means that servers
-
- o might have to increment "Last-Modified" timestamps for every
- resource inside the destination namespace of a namespace operation
- unless it can do so more selectively, and
-
- o similarly, might have to re-assign "ETag" values for these
- resources (unless the server allocates entity tags in a way so
- that they are unique across the whole URL namespace managed by the
- server).
-
- Note that these considerations also apply to specific use cases, such
- as using PUT to create a new resource at a URL that has been mapped
- before, but has been deleted since then.
-
- Finally, WebDAV properties (such as DAV:getetag and DAV:
- getlastmodified) that inherit their semantics from HTTP headers must
- behave accordingly.
-
-9. HTTP Methods for Distributed Authoring
-
-9.1. PROPFIND Method
-
- The PROPFIND method retrieves properties defined on the resource
- identified by the Request-URI, if the resource does not have any
- internal members, or on the resource identified by the Request-URI
- and potentially its member resources, if the resource is a collection
- that has internal member URLs. All DAV-compliant resources MUST
- support the PROPFIND method and the propfind XML element
- (Section 14.20) along with all XML elements defined for use with that
- element.
-
- A client MUST submit a Depth header with a value of "0", "1", or
- "infinity" with a PROPFIND request. Servers MUST support "0" and "1"
- depth requests on WebDAV-compliant resources and SHOULD support
- "infinity" requests. In practice, support for infinite-depth
- requests MAY be disabled, due to the performance and security
- concerns associated with this behavior. Servers SHOULD treat a
- request without a Depth header as if a "Depth: infinity" header was
- included.
-
-
-
-
-Dusseault Standards Track [Page 35]
-
-RFC 4918 WebDAV June 2007
-
-
- A client may submit a 'propfind' XML element in the body of the
- request method describing what information is being requested. It is
- possible to:
-
- o Request particular property values, by naming the properties
- desired within the 'prop' element (the ordering of properties in
- here MAY be ignored by the server),
-
- o Request property values for those properties defined in this
- specification (at a minimum) plus dead properties, by using the
- 'allprop' element (the 'include' element can be used with
- 'allprop' to instruct the server to also include additional live
- properties that may not have been returned otherwise),
-
- o Request a list of names of all the properties defined on the
- resource, by using the 'propname' element.
-
- A client may choose not to submit a request body. An empty PROPFIND
- request body MUST be treated as if it were an 'allprop' request.
-
- Note that 'allprop' does not return values for all live properties.
- WebDAV servers increasingly have expensively-calculated or lengthy
- properties (see [RFC3253] and [RFC3744]) and do not return all
- properties already. Instead, WebDAV clients can use propname
- requests to discover what live properties exist, and request named
- properties when retrieving values. For a live property defined
- elsewhere, that definition can specify whether or not that live
- property would be returned in 'allprop' requests.
-
- All servers MUST support returning a response of content type text/
- xml or application/xml that contains a multistatus XML element that
- describes the results of the attempts to retrieve the various
- properties.
-
- If there is an error retrieving a property, then a proper error
- result MUST be included in the response. A request to retrieve the
- value of a property that does not exist is an error and MUST be noted
- with a 'response' XML element that contains a 404 (Not Found) status
- value.
-
- Consequently, the 'multistatus' XML element for a collection resource
- MUST include a 'response' XML element for each member URL of the
- collection, to whatever depth was requested. It SHOULD NOT include
- any 'response' elements for resources that are not WebDAV-compliant.
- Each 'response' element MUST contain an 'href' element that contains
- the URL of the resource on which the properties in the prop XML
- element are defined. Results for a PROPFIND on a collection resource
- are returned as a flat list whose order of entries is not
-
-
-
-Dusseault Standards Track [Page 36]
-
-RFC 4918 WebDAV June 2007
-
-
- significant. Note that a resource may have only one value for a
- property of a given name, so the property may only show up once in
- PROPFIND responses.
-
- Properties may be subject to access control. In the case of
- 'allprop' and 'propname' requests, if a principal does not have the
- right to know whether a particular property exists, then the property
- MAY be silently excluded from the response.
-
- Some PROPFIND results MAY be cached, with care, as there is no cache
- validation mechanism for most properties. This method is both safe
- and idempotent (see Section 9.1 of [RFC2616]).
-
-9.1.1. PROPFIND Status Codes
-
- This section, as with similar sections for other methods, provides
- some guidance on error codes and preconditions or postconditions
- (defined in Section 16) that might be particularly useful with
- PROPFIND.
-
- 403 Forbidden - A server MAY reject PROPFIND requests on collections
- with depth header of "Infinity", in which case it SHOULD use this
- error with the precondition code 'propfind-finite-depth' inside the
- error body.
-
-9.1.2. Status Codes for Use in 'propstat' Element
-
- In PROPFIND responses, information about individual properties is
- returned inside 'propstat' elements (see Section 14.22), each
- containing an individual 'status' element containing information
- about the properties appearing in it. The list below summarizes the
- most common status codes used inside 'propstat'; however, clients
- should be prepared to handle other 2/3/4/5xx series status codes as
- well.
-
- 200 OK - A property exists and/or its value is successfully returned.
-
- 401 Unauthorized - The property cannot be viewed without appropriate
- authorization.
-
- 403 Forbidden - The property cannot be viewed regardless of
- authentication.
-
- 404 Not Found - The property does not exist.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 37]
-
-RFC 4918 WebDAV June 2007
-
-
-9.1.3. Example - Retrieving Named Properties
-
- >>Request
-
- PROPFIND /file HTTP/1.1
- Host: www.example.com
- Content-type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/file
-
-
-
- Box type A
-
-
- J.J. Johnson
-
-
- HTTP/1.1 200 OK
-
-
-
- HTTP/1.1 403 Forbidden
- The user does not have access to the
- DingALing property.
-
-
-
-
-
-Dusseault Standards Track [Page 38]
-
-RFC 4918 WebDAV June 2007
-
-
-
- There has been an access violation error.
-
-
-
-
- In this example, PROPFIND is executed on a non-collection resource
- http://www.example.com/file. The propfind XML element specifies the
- name of four properties whose values are being requested. In this
- case, only two properties were returned, since the principal issuing
- the request did not have sufficient access rights to see the third
- and fourth properties.
-
-9.1.4. Example - Using 'propname' to Retrieve All Property Names
-
- >>Request
-
- PROPFIND /container/ HTTP/1.1
- Host: www.example.com
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/container/
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-Dusseault Standards Track [Page 39]
-
-RFC 4918 WebDAV June 2007
-
-
-
-
-
- http://www.example.com/container/front.html
-
-
-
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
- In this example, PROPFIND is invoked on the collection resource
- http://www.example.com/container/, with a propfind XML element
- containing the propname XML element, meaning the name of all
- properties should be returned. Since no Depth header is present, it
- assumes its default value of "infinity", meaning the name of the
- properties on the collection and all its descendants should be
- returned.
-
- Consistent with the previous example, resource
- http://www.example.com/container/ has six properties defined on it:
- bigbox and author in the "http://ns.example.com/boxschema/"
- namespace, and creationdate, displayname, resourcetype, and
- supportedlock in the "DAV:" namespace.
-
- The resource http://www.example.com/container/index.html, a member of
- the "container" collection, has nine properties defined on it, bigbox
- in the "http://ns.example.com/boxschema/" namespace and creationdate,
- displayname, getcontentlength, getcontenttype, getetag,
- getlastmodified, resourcetype, and supportedlock in the "DAV:"
- namespace.
-
- This example also demonstrates the use of XML namespace scoping and
- the default namespace. Since the "xmlns" attribute does not contain
- a prefix, the namespace applies by default to all enclosed elements.
- Hence, all elements that do not explicitly state the namespace to
- which they belong are members of the "DAV:" namespace.
-
-
-
-
-Dusseault Standards Track [Page 40]
-
-RFC 4918 WebDAV June 2007
-
-
-9.1.5. Example - Using So-called 'allprop'
-
- Note that 'allprop', despite its name, which remains for backward-
- compatibility, does not return every property, but only dead
- properties and the live properties defined in this specification.
-
- >>Request
-
- PROPFIND /container/ HTTP/1.1
- Host: www.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /container/
-
-
- Box type A
- Hadrian
- 1997-12-01T17:42:21-08:00
- Example collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 41]
-
-RFC 4918 WebDAV June 2007
-
-
- HTTP/1.1 200 OK
-
-
-
- /container/front.html
-
-
- Box type B
-
- 1997-12-01T18:27:21-08:00
- Example HTML resource
- 4525
- text/html
- "zzyzx"
- Mon, 12 Jan 1998 09:25:56 GMT
-
-
-
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
- In this example, PROPFIND was invoked on the resource
- http://www.example.com/container/ with a Depth header of 1, meaning
- the request applies to the resource and its children, and a propfind
- XML element containing the allprop XML element, meaning the request
- should return the name and value of all the dead properties defined
- on the resources, plus the name and value of all the properties
- defined in this specification. This example illustrates the use of
- relative references in the 'href' elements of the response.
-
- The resource http://www.example.com/container/ has six properties
- defined on it: 'bigbox' and 'author in the
- "http://ns.example.com/boxschema/" namespace, DAV:creationdate, DAV:
- displayname, DAV:resourcetype, and DAV:supportedlock.
-
-
-
-
-
-Dusseault Standards Track [Page 42]
-
-RFC 4918 WebDAV June 2007
-
-
- The last four properties are WebDAV-specific, defined in Section 15.
- Since GET is not supported on this resource, the get* properties
- (e.g., DAV:getcontentlength) are not defined on this resource. The
- WebDAV-specific properties assert that "container" was created on
- December 1, 1997, at 5:42:21PM, in a time zone 8 hours west of GMT
- (DAV:creationdate), has a name of "Example collection" (DAV:
- displayname), a collection resource type (DAV:resourcetype), and
- supports exclusive write and shared write locks (DAV:supportedlock).
-
- The resource http://www.example.com/container/front.html has nine
- properties defined on it:
-
- 'bigbox' in the "http://ns.example.com/boxschema/" namespace (another
- instance of the "bigbox" property type), DAV:creationdate, DAV:
- displayname, DAV:getcontentlength, DAV:getcontenttype, DAV:getetag,
- DAV:getlastmodified, DAV:resourcetype, and DAV:supportedlock.
-
- The DAV-specific properties assert that "front.html" was created on
- December 1, 1997, at 6:27:21PM, in a time zone 8 hours west of GMT
- (DAV:creationdate), has a name of "Example HTML resource" (DAV:
- displayname), a content length of 4525 bytes (DAV:getcontentlength),
- a MIME type of "text/html" (DAV:getcontenttype), an entity tag of
- "zzyzx" (DAV:getetag), was last modified on Monday, January 12, 1998,
- at 09:25:56 GMT (DAV:getlastmodified), has an empty resource type,
- meaning that it is not a collection (DAV:resourcetype), and supports
- both exclusive write and shared write locks (DAV:supportedlock).
-
-9.1.6. Example - Using 'allprop' with 'include'
-
- >>Request
-
- PROPFIND /mycol/ HTTP/1.1
- Host: www.example.com
- Depth: 1
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 43]
-
-RFC 4918 WebDAV June 2007
-
-
- In this example, PROPFIND is executed on the resource
- http://www.example.com/mycol/ and its internal member resources. The
- client requests the values of all live properties defined in this
- specification, plus all dead properties, plus two more live
- properties defined in [RFC3253]. The response is not shown.
-
-9.2. PROPPATCH Method
-
- The PROPPATCH method processes instructions specified in the request
- body to set and/or remove properties defined on the resource
- identified by the Request-URI.
-
- All DAV-compliant resources MUST support the PROPPATCH method and
- MUST process instructions that are specified using the
- propertyupdate, set, and remove XML elements. Execution of the
- directives in this method is, of course, subject to access control
- constraints. DAV-compliant resources SHOULD support the setting of
- arbitrary dead properties.
-
- The request message body of a PROPPATCH method MUST contain the
- propertyupdate XML element.
-
- Servers MUST process PROPPATCH instructions in document order (an
- exception to the normal rule that ordering is irrelevant).
- Instructions MUST either all be executed or none executed. Thus, if
- any error occurs during processing, all executed instructions MUST be
- undone and a proper error result returned. Instruction processing
- details can be found in the definition of the set and remove
- instructions in Sections 14.23 and 14.26.
-
- If a server attempts to make any of the property changes in a
- PROPPATCH request (i.e., the request is not rejected for high-level
- errors before processing the body), the response MUST be a Multi-
- Status response as described in Section 9.2.1.
-
- This method is idempotent, but not safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.2.1. Status Codes for Use in 'propstat' Element
-
- In PROPPATCH responses, information about individual properties is
- returned inside 'propstat' elements (see Section 14.22), each
- containing an individual 'status' element containing information
- about the properties appearing in it. The list below summarizes the
- most common status codes used inside 'propstat'; however, clients
- should be prepared to handle other 2/3/4/5xx series status codes as
- well.
-
-
-
-
-Dusseault Standards Track [Page 44]
-
-RFC 4918 WebDAV June 2007
-
-
- 200 (OK) - The property set or change succeeded. Note that if this
- appears for one property, it appears for every property in the
- response, due to the atomicity of PROPPATCH.
-
- 403 (Forbidden) - The client, for reasons the server chooses not to
- specify, cannot alter one of the properties.
-
- 403 (Forbidden): The client has attempted to set a protected
- property, such as DAV:getetag. If returning this error, the server
- SHOULD use the precondition code 'cannot-modify-protected-property'
- inside the response body.
-
- 409 (Conflict) - The client has provided a value whose semantics are
- not appropriate for the property.
-
- 424 (Failed Dependency) - The property change could not be made
- because of another property change that failed.
-
- 507 (Insufficient Storage) - The server did not have sufficient space
- to record the property.
-
-9.2.2. Example - PROPPATCH
-
- >>Request
-
- PROPPATCH /bar.html HTTP/1.1
- Host: www.example.com
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
- Jim Whitehead
- Roy Fielding
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 45]
-
-RFC 4918 WebDAV June 2007
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/bar.html
-
-
- HTTP/1.1 424 Failed Dependency
-
-
-
- HTTP/1.1 409 Conflict
-
- Copyright Owner cannot be deleted or
- altered.
-
-
-
- In this example, the client requests the server to set the value of
- the "Authors" property in the
- "http://ns.example.com/standards/z39.50/" namespace, and to remove
- the property "Copyright-Owner" in the same namespace. Since the
- Copyright-Owner property could not be removed, no property
- modifications occur. The 424 (Failed Dependency) status code for the
- Authors property indicates this action would have succeeded if it
- were not for the conflict with removing the Copyright-Owner property.
-
-9.3. MKCOL Method
-
- MKCOL creates a new collection resource at the location specified by
- the Request-URI. If the Request-URI is already mapped to a resource,
- then the MKCOL MUST fail. During MKCOL processing, a server MUST
- make the Request-URI an internal member of its parent collection,
- unless the Request-URI is "/". If no such ancestor exists, the
- method MUST fail. When the MKCOL operation creates a new collection
- resource, all ancestors MUST already exist, or the method MUST fail
- with a 409 (Conflict) status code. For example, if a request to
- create collection /a/b/c/d/ is made, and /a/b/c/ does not exist, the
- request must fail.
-
- When MKCOL is invoked without a request body, the newly created
- collection SHOULD have no members.
-
-
-
-Dusseault Standards Track [Page 46]
-
-RFC 4918 WebDAV June 2007
-
-
- A MKCOL request message may contain a message body. The precise
- behavior of a MKCOL request when the body is present is undefined,
- but limited to creating collections, members of a collection, bodies
- of members, and properties on the collections or members. If the
- server receives a MKCOL request entity type it does not support or
- understand, it MUST respond with a 415 (Unsupported Media Type)
- status code. If the server decides to reject the request based on
- the presence of an entity or the type of an entity, it should use the
- 415 (Unsupported Media Type) status code.
-
- This method is idempotent, but not safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.3.1. MKCOL Status Codes
-
- In addition to the general status codes possible, the following
- status codes have specific applicability to MKCOL:
-
- 201 (Created) - The collection was created.
-
- 403 (Forbidden) - This indicates at least one of two conditions: 1)
- the server does not allow the creation of collections at the given
- location in its URL namespace, or 2) the parent collection of the
- Request-URI exists but cannot accept members.
-
- 405 (Method Not Allowed) - MKCOL can only be executed on an unmapped
- URL.
-
- 409 (Conflict) - A collection cannot be made at the Request-URI until
- one or more intermediate collections have been created. The server
- MUST NOT create those intermediate collections automatically.
-
- 415 (Unsupported Media Type) - The server does not support the
- request body type (although bodies are legal on MKCOL requests, since
- this specification doesn't define any, the server is likely not to
- support any given body type).
-
- 507 (Insufficient Storage) - The resource does not have sufficient
- space to record the state of the resource after the execution of this
- method.
-
-9.3.2. Example - MKCOL
-
- This example creates a collection called /webdisc/xfiles/ on the
- server www.example.com.
-
-
-
-
-
-
-Dusseault Standards Track [Page 47]
-
-RFC 4918 WebDAV June 2007
-
-
- >>Request
-
- MKCOL /webdisc/xfiles/ HTTP/1.1
- Host: www.example.com
-
-
- >>Response
-
- HTTP/1.1 201 Created
-
-9.4. GET, HEAD for Collections
-
- The semantics of GET are unchanged when applied to a collection,
- since GET is defined as, "retrieve whatever information (in the form
- of an entity) is identified by the Request-URI" [RFC2616]. GET, when
- applied to a collection, may return the contents of an "index.html"
- resource, a human-readable view of the contents of the collection, or
- something else altogether. Hence, it is possible that the result of
- a GET on a collection will bear no correlation to the membership of
- the collection.
-
- Similarly, since the definition of HEAD is a GET without a response
- message body, the semantics of HEAD are unmodified when applied to
- collection resources.
-
-9.5. POST for Collections
-
- Since by definition the actual function performed by POST is
- determined by the server and often depends on the particular
- resource, the behavior of POST when applied to collections cannot be
- meaningfully modified because it is largely undefined. Thus, the
- semantics of POST are unmodified when applied to a collection.
-
-9.6. DELETE Requirements
-
- DELETE is defined in [RFC2616], Section 9.7, to "delete the resource
- identified by the Request-URI". However, WebDAV changes some DELETE
- handling requirements.
-
- A server processing a successful DELETE request:
-
- MUST destroy locks rooted on the deleted resource
-
- MUST remove the mapping from the Request-URI to any resource.
-
- Thus, after a successful DELETE operation (and in the absence of
- other actions), a subsequent GET/HEAD/PROPFIND request to the target
- Request-URI MUST return 404 (Not Found).
-
-
-
-Dusseault Standards Track [Page 48]
-
-RFC 4918 WebDAV June 2007
-
-
-9.6.1. DELETE for Collections
-
- The DELETE method on a collection MUST act as if a "Depth: infinity"
- header was used on it. A client MUST NOT submit a Depth header with
- a DELETE on a collection with any value but infinity.
-
- DELETE instructs that the collection specified in the Request-URI and
- all resources identified by its internal member URLs are to be
- deleted.
-
- If any resource identified by a member URL cannot be deleted, then
- all of the member's ancestors MUST NOT be deleted, so as to maintain
- URL namespace consistency.
-
- Any headers included with DELETE MUST be applied in processing every
- resource to be deleted.
-
- When the DELETE method has completed processing, it MUST result in a
- consistent URL namespace.
-
- If an error occurs deleting a member resource (a resource other than
- the resource identified in the Request-URI), then the response can be
- a 207 (Multi-Status). Multi-Status is used here to indicate which
- internal resources could NOT be deleted, including an error code,
- which should help the client understand which resources caused the
- failure. For example, the Multi-Status body could include a response
- with status 423 (Locked) if an internal resource was locked.
-
- The server MAY return a 4xx status response, rather than a 207, if
- the request failed completely.
-
- 424 (Failed Dependency) status codes SHOULD NOT be in the 207 (Multi-
- Status) response for DELETE. They can be safely left out because the
- client will know that the ancestors of a resource could not be
- deleted when the client receives an error for the ancestor's progeny.
- Additionally, 204 (No Content) errors SHOULD NOT be returned in the
- 207 (Multi-Status). The reason for this prohibition is that 204 (No
- Content) is the default success code.
-
-9.6.2. Example - DELETE
-
- >>Request
-
- DELETE /container/ HTTP/1.1
- Host: www.example.com
-
-
-
-
-
-
-Dusseault Standards Track [Page 49]
-
-RFC 4918 WebDAV June 2007
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/container/resource3
- HTTP/1.1 423 Locked
-
-
-
-
- In this example, the attempt to delete
- http://www.example.com/container/resource3 failed because it is
- locked, and no lock token was submitted with the request.
- Consequently, the attempt to delete http://www.example.com/container/
- also failed. Thus, the client knows that the attempt to delete
- http://www.example.com/container/ must have also failed since the
- parent cannot be deleted unless its child has also been deleted.
- Even though a Depth header has not been included, a depth of infinity
- is assumed because the method is on a collection.
-
-9.7. PUT Requirements
-
-9.7.1. PUT for Non-Collection Resources
-
- A PUT performed on an existing resource replaces the GET response
- entity of the resource. Properties defined on the resource may be
- recomputed during PUT processing but are not otherwise affected. For
- example, if a server recognizes the content type of the request body,
- it may be able to automatically extract information that could be
- profitably exposed as properties.
-
- A PUT that would result in the creation of a resource without an
- appropriately scoped parent collection MUST fail with a 409
- (Conflict).
-
- A PUT request allows a client to indicate what media type an entity
- body has, and whether it should change if overwritten. Thus, a
- client SHOULD provide a Content-Type for a new resource if any is
- known. If the client does not provide a Content-Type for a new
- resource, the server MAY create a resource with no Content-Type
- assigned, or it MAY attempt to assign a Content-Type.
-
-
-
-
-
-Dusseault Standards Track [Page 50]
-
-RFC 4918 WebDAV June 2007
-
-
- Note that although a recipient ought generally to treat metadata
- supplied with an HTTP request as authoritative, in practice there's
- no guarantee that a server will accept client-supplied metadata
- (e.g., any request header beginning with "Content-"). Many servers
- do not allow configuring the Content-Type on a per-resource basis in
- the first place. Thus, clients can't always rely on the ability to
- directly influence the content type by including a Content-Type
- request header.
-
-9.7.2. PUT for Collections
-
- This specification does not define the behavior of the PUT method for
- existing collections. A PUT request to an existing collection MAY be
- treated as an error (405 Method Not Allowed).
-
- The MKCOL method is defined to create collections.
-
-9.8. COPY Method
-
- The COPY method creates a duplicate of the source resource identified
- by the Request-URI, in the destination resource identified by the URI
- in the Destination header. The Destination header MUST be present.
- The exact behavior of the COPY method depends on the type of the
- source resource.
-
- All WebDAV-compliant resources MUST support the COPY method.
- However, support for the COPY method does not guarantee the ability
- to copy a resource. For example, separate programs may control
- resources on the same server. As a result, it may not be possible to
- copy a resource to a location that appears to be on the same server.
-
- This method is idempotent, but not safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.8.1. COPY for Non-collection Resources
-
- When the source resource is not a collection, the result of the COPY
- method is the creation of a new resource at the destination whose
- state and behavior match that of the source resource as closely as
- possible. Since the environment at the destination may be different
- than at the source due to factors outside the scope of control of the
- server, such as the absence of resources required for correct
- operation, it may not be possible to completely duplicate the
- behavior of the resource at the destination. Subsequent alterations
- to the destination resource will not modify the source resource.
- Subsequent alterations to the source resource will not modify the
- destination resource.
-
-
-
-
-Dusseault Standards Track [Page 51]
-
-RFC 4918 WebDAV June 2007
-
-
-9.8.2. COPY for Properties
-
- After a successful COPY invocation, all dead properties on the source
- resource SHOULD be duplicated on the destination resource. Live
- properties described in this document SHOULD be duplicated as
- identically behaving live properties at the destination resource, but
- not necessarily with the same values. Servers SHOULD NOT convert
- live properties into dead properties on the destination resource,
- because clients may then draw incorrect conclusions about the state
- or functionality of a resource. Note that some live properties are
- defined such that the absence of the property has a specific meaning
- (e.g., a flag with one meaning if present, and the opposite if
- absent), and in these cases, a successful COPY might result in the
- property being reported as "Not Found" in subsequent requests.
-
- When the destination is an unmapped URL, a COPY operation creates a
- new resource much like a PUT operation does. Live properties that
- are related to resource creation (such as DAV:creationdate) should
- have their values set accordingly.
-
-9.8.3. COPY for Collections
-
- The COPY method on a collection without a Depth header MUST act as if
- a Depth header with value "infinity" was included. A client may
- submit a Depth header on a COPY on a collection with a value of "0"
- or "infinity". Servers MUST support the "0" and "infinity" Depth
- header behaviors on WebDAV-compliant resources.
-
- An infinite-depth COPY instructs that the collection resource
- identified by the Request-URI is to be copied to the location
- identified by the URI in the Destination header, and all its internal
- member resources are to be copied to a location relative to it,
- recursively through all levels of the collection hierarchy. Note
- that an infinite-depth COPY of /A/ into /A/B/ could lead to infinite
- recursion if not handled correctly.
-
- A COPY of "Depth: 0" only instructs that the collection and its
- properties, but not resources identified by its internal member URLs,
- are to be copied.
-
- Any headers included with a COPY MUST be applied in processing every
- resource to be copied with the exception of the Destination header.
-
- The Destination header only specifies the destination URI for the
- Request-URI. When applied to members of the collection identified by
- the Request-URI, the value of Destination is to be modified to
- reflect the current location in the hierarchy. So, if the Request-
- URI is /a/ with Host header value http://example.com/ and the
-
-
-
-Dusseault Standards Track [Page 52]
-
-RFC 4918 WebDAV June 2007
-
-
- Destination is http://example.com/b/, then when
- http://example.com/a/c/d is processed, it must use a Destination of
- http://example.com/b/c/d.
-
- When the COPY method has completed processing, it MUST have created a
- consistent URL namespace at the destination (see Section 5.1 for the
- definition of namespace consistency). However, if an error occurs
- while copying an internal collection, the server MUST NOT copy any
- resources identified by members of this collection (i.e., the server
- must skip this subtree), as this would create an inconsistent
- namespace. After detecting an error, the COPY operation SHOULD try
- to finish as much of the original copy operation as possible (i.e.,
- the server should still attempt to copy other subtrees and their
- members that are not descendants of an error-causing collection).
-
- So, for example, if an infinite-depth copy operation is performed on
- collection /a/, which contains collections /a/b/ and /a/c/, and an
- error occurs copying /a/b/, an attempt should still be made to copy
- /a/c/. Similarly, after encountering an error copying a non-
- collection resource as part of an infinite-depth copy, the server
- SHOULD try to finish as much of the original copy operation as
- possible.
-
- If an error in executing the COPY method occurs with a resource other
- than the resource identified in the Request-URI, then the response
- MUST be a 207 (Multi-Status), and the URL of the resource causing the
- failure MUST appear with the specific error.
-
- The 424 (Failed Dependency) status code SHOULD NOT be returned in the
- 207 (Multi-Status) response from a COPY method. These responses can
- be safely omitted because the client will know that the progeny of a
- resource could not be copied when the client receives an error for
- the parent. Additionally, 201 (Created)/204 (No Content) status
- codes SHOULD NOT be returned as values in 207 (Multi-Status)
- responses from COPY methods. They, too, can be safely omitted
- because they are the default success codes.
-
-9.8.4. COPY and Overwriting Destination Resources
-
- If a COPY request has an Overwrite header with a value of "F", and a
- resource exists at the Destination URL, the server MUST fail the
- request.
-
- When a server executes a COPY request and overwrites a destination
- resource, the exact behavior MAY depend on many factors, including
- WebDAV extension capabilities (see particularly [RFC3253]). For
-
-
-
-
-
-Dusseault Standards Track [Page 53]
-
-RFC 4918 WebDAV June 2007
-
-
- example, when an ordinary resource is overwritten, the server could
- delete the target resource before doing the copy, or could do an in-
- place overwrite to preserve live properties.
-
- When a collection is overwritten, the membership of the destination
- collection after the successful COPY request MUST be the same
- membership as the source collection immediately before the COPY.
- Thus, merging the membership of the source and destination
- collections together in the destination is not a compliant behavior.
-
- In general, if clients require the state of the destination URL to be
- wiped out prior to a COPY (e.g., to force live properties to be
- reset), then the client could send a DELETE to the destination before
- the COPY request to ensure this reset.
-
-9.8.5. Status Codes
-
- In addition to the general status codes possible, the following
- status codes have specific applicability to COPY:
-
- 201 (Created) - The source resource was successfully copied. The
- COPY operation resulted in the creation of a new resource.
-
- 204 (No Content) - The source resource was successfully copied to a
- preexisting destination resource.
-
- 207 (Multi-Status) - Multiple resources were to be affected by the
- COPY, but errors on some of them prevented the operation from taking
- place. Specific error messages, together with the most appropriate
- of the source and destination URLs, appear in the body of the multi-
- status response. For example, if a destination resource was locked
- and could not be overwritten, then the destination resource URL
- appears with the 423 (Locked) status.
-
- 403 (Forbidden) - The operation is forbidden. A special case for
- COPY could be that the source and destination resources are the same
- resource.
-
- 409 (Conflict) - A resource cannot be created at the destination
- until one or more intermediate collections have been created. The
- server MUST NOT create those intermediate collections automatically.
-
- 412 (Precondition Failed) - A precondition header check failed, e.g.,
- the Overwrite header is "F" and the destination URL is already mapped
- to a resource.
-
-
-
-
-
-
-Dusseault Standards Track [Page 54]
-
-RFC 4918 WebDAV June 2007
-
-
- 423 (Locked) - The destination resource, or resource within the
- destination collection, was locked. This response SHOULD contain the
- 'lock-token-submitted' precondition element.
-
- 502 (Bad Gateway) - This may occur when the destination is on another
- server, repository, or URL namespace. Either the source namespace
- does not support copying to the destination namespace, or the
- destination namespace refuses to accept the resource. The client may
- wish to try GET/PUT and PROPFIND/PROPPATCH instead.
-
- 507 (Insufficient Storage) - The destination resource does not have
- sufficient space to record the state of the resource after the
- execution of this method.
-
-9.8.6. Example - COPY with Overwrite
-
- This example shows resource
- http://www.example.com/~fielding/index.html being copied to the
- location http://www.example.com/users/f/fielding/index.html. The 204
- (No Content) status code indicates that the existing resource at the
- destination was overwritten.
-
- >>Request
-
- COPY /~fielding/index.html HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/users/f/fielding/index.html
-
- >>Response
-
- HTTP/1.1 204 No Content
-
-9.8.7. Example - COPY with No Overwrite
-
- The following example shows the same copy operation being performed,
- but with the Overwrite header set to "F." A response of 412
- (Precondition Failed) is returned because the destination URL is
- already mapped to a resource.
-
- >>Request
-
- COPY /~fielding/index.html HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/users/f/fielding/index.html
- Overwrite: F
-
-
-
-
-
-
-Dusseault Standards Track [Page 55]
-
-RFC 4918 WebDAV June 2007
-
-
- >>Response
-
- HTTP/1.1 412 Precondition Failed
-
-9.8.8. Example - COPY of a Collection
-
- >>Request
-
- COPY /container/ HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/othercontainer/
- Depth: infinity
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
- http://www.example.com/othercontainer/R2/
- HTTP/1.1 423 Locked
-
-
-
-
- The Depth header is unnecessary as the default behavior of COPY on a
- collection is to act as if a "Depth: infinity" header had been
- submitted. In this example, most of the resources, along with the
- collection, were copied successfully. However, the collection R2
- failed because the destination R2 is locked. Because there was an
- error copying R2, none of R2's members were copied. However, no
- errors were listed for those members due to the error minimization
- rules.
-
-9.9. MOVE Method
-
- The MOVE operation on a non-collection resource is the logical
- equivalent of a copy (COPY), followed by consistency maintenance
- processing, followed by a delete of the source, where all three
- actions are performed in a single operation. The consistency
- maintenance step allows the server to perform updates caused by the
- move, such as updating all URLs, other than the Request-URI that
- identifies the source resource, to point to the new destination
- resource.
-
-
-
-Dusseault Standards Track [Page 56]
-
-RFC 4918 WebDAV June 2007
-
-
- The Destination header MUST be present on all MOVE methods and MUST
- follow all COPY requirements for the COPY part of the MOVE method.
- All WebDAV-compliant resources MUST support the MOVE method.
-
- Support for the MOVE method does not guarantee the ability to move a
- resource to a particular destination. For example, separate programs
- may actually control different sets of resources on the same server.
- Therefore, it may not be possible to move a resource within a
- namespace that appears to belong to the same server.
-
- If a resource exists at the destination, the destination resource
- will be deleted as a side-effect of the MOVE operation, subject to
- the restrictions of the Overwrite header.
-
- This method is idempotent, but not safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.9.1. MOVE for Properties
-
- Live properties described in this document SHOULD be moved along with
- the resource, such that the resource has identically behaving live
- properties at the destination resource, but not necessarily with the
- same values. Note that some live properties are defined such that
- the absence of the property has a specific meaning (e.g., a flag with
- one meaning if present, and the opposite if absent), and in these
- cases, a successful MOVE might result in the property being reported
- as "Not Found" in subsequent requests. If the live properties will
- not work the same way at the destination, the server MAY fail the
- request.
-
- MOVE is frequently used by clients to rename a file without changing
- its parent collection, so it's not appropriate to reset all live
- properties that are set at resource creation. For example, the DAV:
- creationdate property value SHOULD remain the same after a MOVE.
-
- Dead properties MUST be moved along with the resource.
-
-9.9.2. MOVE for Collections
-
- A MOVE with "Depth: infinity" instructs that the collection
- identified by the Request-URI be moved to the address specified in
- the Destination header, and all resources identified by its internal
- member URLs are to be moved to locations relative to it, recursively
- through all levels of the collection hierarchy.
-
- The MOVE method on a collection MUST act as if a "Depth: infinity"
- header was used on it. A client MUST NOT submit a Depth header on a
- MOVE on a collection with any value but "infinity".
-
-
-
-Dusseault Standards Track [Page 57]
-
-RFC 4918 WebDAV June 2007
-
-
- Any headers included with MOVE MUST be applied in processing every
- resource to be moved with the exception of the Destination header.
- The behavior of the Destination header is the same as given for COPY
- on collections.
-
- When the MOVE method has completed processing, it MUST have created a
- consistent URL namespace at both the source and destination (see
- Section 5.1 for the definition of namespace consistency). However,
- if an error occurs while moving an internal collection, the server
- MUST NOT move any resources identified by members of the failed
- collection (i.e., the server must skip the error-causing subtree), as
- this would create an inconsistent namespace. In this case, after
- detecting the error, the move operation SHOULD try to finish as much
- of the original move as possible (i.e., the server should still
- attempt to move other subtrees and the resources identified by their
- members that are not descendants of an error-causing collection).
- So, for example, if an infinite-depth move is performed on collection
- /a/, which contains collections /a/b/ and /a/c/, and an error occurs
- moving /a/b/, an attempt should still be made to try moving /a/c/.
- Similarly, after encountering an error moving a non-collection
- resource as part of an infinite-depth move, the server SHOULD try to
- finish as much of the original move operation as possible.
-
- If an error occurs with a resource other than the resource identified
- in the Request-URI, then the response MUST be a 207 (Multi-Status),
- and the errored resource's URL MUST appear with the specific error.
-
- The 424 (Failed Dependency) status code SHOULD NOT be returned in the
- 207 (Multi-Status) response from a MOVE method. These errors can be
- safely omitted because the client will know that the progeny of a
- resource could not be moved when the client receives an error for the
- parent. Additionally, 201 (Created)/204 (No Content) responses
- SHOULD NOT be returned as values in 207 (Multi-Status) responses from
- a MOVE. These responses can be safely omitted because they are the
- default success codes.
-
-9.9.3. MOVE and the Overwrite Header
-
- If a resource exists at the destination and the Overwrite header is
- "T", then prior to performing the move, the server MUST perform a
- DELETE with "Depth: infinity" on the destination resource. If the
- Overwrite header is set to "F", then the operation will fail.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 58]
-
-RFC 4918 WebDAV June 2007
-
-
-9.9.4. Status Codes
-
- In addition to the general status codes possible, the following
- status codes have specific applicability to MOVE:
-
- 201 (Created) - The source resource was successfully moved, and a new
- URL mapping was created at the destination.
-
- 204 (No Content) - The source resource was successfully moved to a
- URL that was already mapped.
-
- 207 (Multi-Status) - Multiple resources were to be affected by the
- MOVE, but errors on some of them prevented the operation from taking
- place. Specific error messages, together with the most appropriate
- of the source and destination URLs, appear in the body of the multi-
- status response. For example, if a source resource was locked and
- could not be moved, then the source resource URL appears with the 423
- (Locked) status.
-
- 403 (Forbidden) - Among many possible reasons for forbidding a MOVE
- operation, this status code is recommended for use when the source
- and destination resources are the same.
-
- 409 (Conflict) - A resource cannot be created at the destination
- until one or more intermediate collections have been created. The
- server MUST NOT create those intermediate collections automatically.
- Or, the server was unable to preserve the behavior of the live
- properties and still move the resource to the destination (see
- 'preserved-live-properties' postcondition).
-
- 412 (Precondition Failed) - A condition header failed. Specific to
- MOVE, this could mean that the Overwrite header is "F" and the
- destination URL is already mapped to a resource.
-
- 423 (Locked) - The source or the destination resource, the source or
- destination resource parent, or some resource within the source or
- destination collection, was locked. This response SHOULD contain the
- 'lock-token-submitted' precondition element.
-
- 502 (Bad Gateway) - This may occur when the destination is on another
- server and the destination server refuses to accept the resource.
- This could also occur when the destination is on another sub-section
- of the same server namespace.
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 59]
-
-RFC 4918 WebDAV June 2007
-
-
-9.9.5. Example - MOVE of a Non-Collection
-
- This example shows resource
- http://www.example.com/~fielding/index.html being moved to the
- location http://www.example.com/users/f/fielding/index.html. The
- contents of the destination resource would have been overwritten if
- the destination URL was already mapped to a resource. In this case,
- since there was nothing at the destination resource, the response
- code is 201 (Created).
-
- >>Request
-
- MOVE /~fielding/index.html HTTP/1.1
- Host: www.example.com
- Destination: http://www.example/users/f/fielding/index.html
-
- >>Response
-
- HTTP/1.1 201 Created
- Location: http://www.example.com/users/f/fielding/index.html
-
-9.9.6. Example - MOVE of a Collection
-
- >>Request
-
- MOVE /container/ HTTP/1.1
- Host: www.example.com
- Destination: http://www.example.com/othercontainer/
- Overwrite: F
- If: ()
- ()
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/othercontainer/C2/
- HTTP/1.1 423 Locked
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 60]
-
-RFC 4918 WebDAV June 2007
-
-
- In this example, the client has submitted a number of lock tokens
- with the request. A lock token will need to be submitted for every
- resource, both source and destination, anywhere in the scope of the
- method, that is locked. In this case, the proper lock token was not
- submitted for the destination
- http://www.example.com/othercontainer/C2/. This means that the
- resource /container/C2/ could not be moved. Because there was an
- error moving /container/C2/, none of /container/C2's members were
- moved. However, no errors were listed for those members due to the
- error minimization rules. User agent authentication has previously
- occurred via a mechanism outside the scope of the HTTP protocol, in
- an underlying transport layer.
-
-9.10. LOCK Method
-
- The following sections describe the LOCK method, which is used to
- take out a lock of any access type and to refresh an existing lock.
- These sections on the LOCK method describe only those semantics that
- are specific to the LOCK method and are independent of the access
- type of the lock being requested.
-
- Any resource that supports the LOCK method MUST, at minimum, support
- the XML request and response formats defined herein.
-
- This method is neither idempotent nor safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.10.1. Creating a Lock on an Existing Resource
-
- A LOCK request to an existing resource will create a lock on the
- resource identified by the Request-URI, provided the resource is not
- already locked with a conflicting lock. The resource identified in
- the Request-URI becomes the root of the lock. LOCK method requests
- to create a new lock MUST have an XML request body. The server MUST
- preserve the information provided by the client in the 'owner'
- element in the LOCK request. The LOCK request MAY have a Timeout
- header.
-
- When a new lock is created, the LOCK response:
-
- o MUST contain a body with the value of the DAV:lockdiscovery
- property in a prop XML element. This MUST contain the full
- information about the lock just granted, while information about
- other (shared) locks is OPTIONAL.
-
- o MUST include the Lock-Token response header with the token
- associated with the new lock.
-
-
-
-
-Dusseault Standards Track [Page 61]
-
-RFC 4918 WebDAV June 2007
-
-
-9.10.2. Refreshing Locks
-
- A lock is refreshed by sending a LOCK request to the URL of a
- resource within the scope of the lock. This request MUST NOT have a
- body and it MUST specify which lock to refresh by using the 'If'
- header with a single lock token (only one lock may be refreshed at a
- time). The request MAY contain a Timeout header, which a server MAY
- accept to change the duration remaining on the lock to the new value.
- A server MUST ignore the Depth header on a LOCK refresh.
-
- If the resource has other (shared) locks, those locks are unaffected
- by a lock refresh. Additionally, those locks do not prevent the
- named lock from being refreshed.
-
- The Lock-Token header is not returned in the response for a
- successful refresh LOCK request, but the LOCK response body MUST
- contain the new value for the DAV:lockdiscovery property.
-
-9.10.3. Depth and Locking
-
- The Depth header may be used with the LOCK method. Values other than
- 0 or infinity MUST NOT be used with the Depth header on a LOCK
- method. All resources that support the LOCK method MUST support the
- Depth header.
-
- A Depth header of value 0 means to just lock the resource specified
- by the Request-URI.
-
- If the Depth header is set to infinity, then the resource specified
- in the Request-URI along with all its members, all the way down the
- hierarchy, are to be locked. A successful result MUST return a
- single lock token. Similarly, if an UNLOCK is successfully executed
- on this token, all associated resources are unlocked. Hence, partial
- success is not an option for LOCK or UNLOCK. Either the entire
- hierarchy is locked or no resources are locked.
-
- If the lock cannot be granted to all resources, the server MUST
- return a Multi-Status response with a 'response' element for at least
- one resource that prevented the lock from being granted, along with a
- suitable status code for that failure (e.g., 403 (Forbidden) or 423
- (Locked)). Additionally, if the resource causing the failure was not
- the resource requested, then the server SHOULD include a 'response'
- element for the Request-URI as well, with a 'status' element
- containing 424 Failed Dependency.
-
- If no Depth header is submitted on a LOCK request, then the request
- MUST act as if a "Depth:infinity" had been submitted.
-
-
-
-
-Dusseault Standards Track [Page 62]
-
-RFC 4918 WebDAV June 2007
-
-
-9.10.4. Locking Unmapped URLs
-
- A successful LOCK method MUST result in the creation of an empty
- resource that is locked (and that is not a collection) when a
- resource did not previously exist at that URL. Later on, the lock
- may go away but the empty resource remains. Empty resources MUST
- then appear in PROPFIND responses including that URL in the response
- scope. A server MUST respond successfully to a GET request to an
- empty resource, either by using a 204 No Content response, or by
- using 200 OK with a Content-Length header indicating zero length
-
-9.10.5. Lock Compatibility Table
-
- The table below describes the behavior that occurs when a lock
- request is made on a resource.
-
- +--------------------------+----------------+-------------------+
- | Current State | Shared Lock OK | Exclusive Lock OK |
- +--------------------------+----------------+-------------------+
- | None | True | True |
- | Shared Lock | True | False |
- | Exclusive Lock | False | False* |
- +--------------------------+----------------+-------------------+
-
- Legend: True = lock may be granted. False = lock MUST NOT be
- granted. *=It is illegal for a principal to request the same lock
- twice.
-
- The current lock state of a resource is given in the leftmost column,
- and lock requests are listed in the first row. The intersection of a
- row and column gives the result of a lock request. For example, if a
- shared lock is held on a resource, and an exclusive lock is
- requested, the table entry is "false", indicating that the lock must
- not be granted.
-
-9.10.6. LOCK Responses
-
- In addition to the general status codes possible, the following
- status codes have specific applicability to LOCK:
-
- 200 (OK) - The LOCK request succeeded and the value of the DAV:
- lockdiscovery property is included in the response body.
-
- 201 (Created) - The LOCK request was to an unmapped URL, the request
- succeeded and resulted in the creation of a new resource, and the
- value of the DAV:lockdiscovery property is included in the response
- body.
-
-
-
-
-Dusseault Standards Track [Page 63]
-
-RFC 4918 WebDAV June 2007
-
-
- 409 (Conflict) - A resource cannot be created at the destination
- until one or more intermediate collections have been created. The
- server MUST NOT create those intermediate collections automatically.
-
- 423 (Locked), potentially with 'no-conflicting-lock' precondition
- code - There is already a lock on the resource that is not compatible
- with the requested lock (see lock compatibility table above).
-
- 412 (Precondition Failed), with 'lock-token-matches-request-uri'
- precondition code - The LOCK request was made with an If header,
- indicating that the client wishes to refresh the given lock.
- However, the Request-URI did not fall within the scope of the lock
- identified by the token. The lock may have a scope that does not
- include the Request-URI, or the lock could have disappeared, or the
- token may be invalid.
-
-9.10.7. Example - Simple Lock Request
-
- >>Request
-
- LOCK /workspace/webdav/proposal.doc HTTP/1.1
- Host: example.com
- Timeout: Infinite, Second-4100000000
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="ejw",
- realm="ejw@example.com", nonce="...",
- uri="/workspace/webdav/proposal.doc",
- response="...", opaque="..."
-
-
-
-
-
-
- http://example.org/~ejw/contact.html
-
-
-
- >>Response
-
- HTTP/1.1 200 OK
- Lock-Token:
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-Dusseault Standards Track [Page 64]
-
-RFC 4918 WebDAV June 2007
-
-
-
-
-
-
- infinity
-
- http://example.org/~ejw/contact.html
-
- Second-604800
-
- urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4
-
-
- http://example.com/workspace/webdav/proposal.doc
-
-
-
-
-
-
- This example shows the successful creation of an exclusive write lock
- on resource http://example.com/workspace/webdav/proposal.doc. The
- resource http://example.org/~ejw/contact.html contains contact
- information for the creator of the lock. The server has an activity-
- based timeout policy in place on this resource, which causes the lock
- to automatically be removed after 1 week (604800 seconds). Note that
- the nonce, response, and opaque fields have not been calculated in
- the Authorization request header.
-
-9.10.8. Example - Refreshing a Write Lock
-
- >>Request
-
- LOCK /workspace/webdav/proposal.doc HTTP/1.1
- Host: example.com
- Timeout: Infinite, Second-4100000000
- If: ()
- Authorization: Digest username="ejw",
- realm="ejw@example.com", nonce="...",
- uri="/workspace/webdav/proposal.doc",
- response="...", opaque="..."
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 65]
-
-RFC 4918 WebDAV June 2007
-
-
- >>Response
-
- HTTP/1.1 200 OK
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- infinity
-
- http://example.org/~ejw/contact.html
-
- Second-604800
-
- urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4
-
-
- http://example.com/workspace/webdav/proposal.doc
-
-
-
-
-
-
- This request would refresh the lock, attempting to reset the timeout
- to the new value specified in the timeout header. Notice that the
- client asked for an infinite time out but the server choose to ignore
- the request. In this example, the nonce, response, and opaque fields
- have not been calculated in the Authorization request header.
-
-9.10.9. Example - Multi-Resource Lock Request
-
- >>Request
-
- LOCK /webdav/ HTTP/1.1
- Host: example.com
- Timeout: Infinite, Second-4100000000
- Depth: infinity
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
- Authorization: Digest username="ejw",
- realm="ejw@example.com", nonce="...",
-
-
-
-Dusseault Standards Track [Page 66]
-
-RFC 4918 WebDAV June 2007
-
-
- uri="/workspace/webdav/proposal.doc",
- response="...", opaque="..."
-
-
-
-
-
-
- http://example.org/~ejw/contact.html
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://example.com/webdav/secret
- HTTP/1.1 403 Forbidden
-
-
- http://example.com/webdav/
- HTTP/1.1 424 Failed Dependency
-
-
-
-
- This example shows a request for an exclusive write lock on a
- collection and all its children. In this request, the client has
- specified that it desires an infinite-length lock, if available,
- otherwise a timeout of 4.1 billion seconds, if available. The
- request entity body contains the contact information for the
- principal taking out the lock -- in this case, a Web page URL.
-
- The error is a 403 (Forbidden) response on the resource
- http://example.com/webdav/secret. Because this resource could not be
- locked, none of the resources were locked. Note also that the a
- 'response' element for the Request-URI itself has been included as
- required.
-
- In this example, the nonce, response, and opaque fields have not been
- calculated in the Authorization request header.
-
-
-
-
-
-Dusseault Standards Track [Page 67]
-
-RFC 4918 WebDAV June 2007
-
-
-9.11. UNLOCK Method
-
- The UNLOCK method removes the lock identified by the lock token in
- the Lock-Token request header. The Request-URI MUST identify a
- resource within the scope of the lock.
-
- Note that use of the Lock-Token header to provide the lock token is
- not consistent with other state-changing methods, which all require
- an If header with the lock token. Thus, the If header is not needed
- to provide the lock token. Naturally, when the If header is present,
- it has its normal meaning as a conditional header.
-
- For a successful response to this method, the server MUST delete the
- lock entirely.
-
- If all resources that have been locked under the submitted lock token
- cannot be unlocked, then the UNLOCK request MUST fail.
-
- A successful response to an UNLOCK method does not mean that the
- resource is necessarily unlocked. It means that the specific lock
- corresponding to the specified token no longer exists.
-
- Any DAV-compliant resource that supports the LOCK method MUST support
- the UNLOCK method.
-
- This method is idempotent, but not safe (see Section 9.1 of
- [RFC2616]). Responses to this method MUST NOT be cached.
-
-9.11.1. Status Codes
-
- In addition to the general status codes possible, the following
- status codes have specific applicability to UNLOCK:
-
- 204 (No Content) - Normal success response (rather than 200 OK, since
- 200 OK would imply a response body, and an UNLOCK success response
- does not normally contain a body).
-
- 400 (Bad Request) - No lock token was provided.
-
- 403 (Forbidden) - The currently authenticated principal does not have
- permission to remove the lock.
-
- 409 (Conflict), with 'lock-token-matches-request-uri' precondition -
- The resource was not locked, or the request was made to a Request-URI
- that was not within the scope of the lock.
-
-
-
-
-
-
-Dusseault Standards Track [Page 68]
-
-RFC 4918 WebDAV June 2007
-
-
-9.11.2. Example - UNLOCK
-
- >>Request
-
- UNLOCK /workspace/webdav/info.doc HTTP/1.1
- Host: example.com
- Lock-Token:
- Authorization: Digest username="ejw"
- realm="ejw@example.com", nonce="...",
- uri="/workspace/webdav/proposal.doc",
- response="...", opaque="..."
-
- >>Response
-
- HTTP/1.1 204 No Content
-
- In this example, the lock identified by the lock token
- "urn:uuid:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7" is successfully
- removed from the resource
- http://example.com/workspace/webdav/info.doc. If this lock included
- more than just one resource, the lock is removed from all resources
- included in the lock.
-
- In this example, the nonce, response, and opaque fields have not been
- calculated in the Authorization request header.
-
-10. HTTP Headers for Distributed Authoring
-
- All DAV headers follow the same basic formatting rules as HTTP
- headers. This includes rules like line continuation and how to
- combine (or separate) multiple instances of the same header using
- commas.
-
- WebDAV adds two new conditional headers to the set defined in HTTP:
- the If and Overwrite headers.
-
-10.1. DAV Header
-
- DAV = "DAV" ":" #( compliance-class )
- compliance-class = ( "1" | "2" | "3" | extend )
- extend = Coded-URL | token
- ; token is defined in RFC 2616, Section 2.2
- Coded-URL = "<" absolute-URI ">"
- ; No linear whitespace (LWS) allowed in Coded-URL
- ; absolute-URI defined in RFC 3986, Section 4.3
-
-
-
-
-
-
-Dusseault Standards Track [Page 69]
-
-RFC 4918 WebDAV June 2007
-
-
- This general-header appearing in the response indicates that the
- resource supports the DAV schema and protocol as specified. All DAV-
- compliant resources MUST return the DAV header with compliance-class
- "1" on all OPTIONS responses. In cases where WebDAV is only
- supported in part of the server namespace, an OPTIONS request to non-
- WebDAV resources (including "/") SHOULD NOT advertise WebDAV support.
-
- The value is a comma-separated list of all compliance class
- identifiers that the resource supports. Class identifiers may be
- Coded-URLs or tokens (as defined by [RFC2616]). Identifiers can
- appear in any order. Identifiers that are standardized through the
- IETF RFC process are tokens, but other identifiers SHOULD be Coded-
- URLs to encourage uniqueness.
-
- A resource must show class 1 compliance if it shows class 2 or 3
- compliance. In general, support for one compliance class does not
- entail support for any other, and in particular, support for
- compliance class 3 does not require support for compliance class 2.
- Please refer to Section 18 for more details on compliance classes
- defined in this specification.
-
- Note that many WebDAV servers do not advertise WebDAV support in
- response to "OPTIONS *".
-
- As a request header, this header allows the client to advertise
- compliance with named features when the server needs that
- information. Clients SHOULD NOT send this header unless a standards
- track specification requires it. Any extension that makes use of
- this as a request header will need to carefully consider caching
- implications.
-
-10.2. Depth Header
-
- Depth = "Depth" ":" ("0" | "1" | "infinity")
-
- The Depth request header is used with methods executed on resources
- that could potentially have internal members to indicate whether the
- method is to be applied only to the resource ("Depth: 0"), to the
- resource and its internal members only ("Depth: 1"), or the resource
- and all its members ("Depth: infinity").
-
- The Depth header is only supported if a method's definition
- explicitly provides for such support.
-
- The following rules are the default behavior for any method that
- supports the Depth header. A method may override these defaults by
- defining different behavior in its definition.
-
-
-
-
-Dusseault Standards Track [Page 70]
-
-RFC 4918 WebDAV June 2007
-
-
- Methods that support the Depth header may choose not to support all
- of the header's values and may define, on a case-by-case basis, the
- behavior of the method if a Depth header is not present. For
- example, the MOVE method only supports "Depth: infinity", and if a
- Depth header is not present, it will act as if a "Depth: infinity"
- header had been applied.
-
- Clients MUST NOT rely upon methods executing on members of their
- hierarchies in any particular order or on the execution being atomic
- unless the particular method explicitly provides such guarantees.
-
- Upon execution, a method with a Depth header will perform as much of
- its assigned task as possible and then return a response specifying
- what it was able to accomplish and what it failed to do.
-
- So, for example, an attempt to COPY a hierarchy may result in some of
- the members being copied and some not.
-
- By default, the Depth header does not interact with other headers.
- That is, each header on a request with a Depth header MUST be applied
- only to the Request-URI if it applies to any resource, unless
- specific Depth behavior is defined for that header.
-
- If a source or destination resource within the scope of the Depth
- header is locked in such a way as to prevent the successful execution
- of the method, then the lock token for that resource MUST be
- submitted with the request in the If request header.
-
- The Depth header only specifies the behavior of the method with
- regards to internal members. If a resource does not have internal
- members, then the Depth header MUST be ignored.
-
-10.3. Destination Header
-
- The Destination request header specifies the URI that identifies a
- destination resource for methods such as COPY and MOVE, which take
- two URIs as parameters.
-
- Destination = "Destination" ":" Simple-ref
-
-
- If the Destination value is an absolute-URI (Section 4.3 of
- [RFC3986]), it may name a different server (or different port or
- scheme). If the source server cannot attempt a copy to the remote
- server, it MUST fail the request. Note that copying and moving
- resources to remote servers is not fully defined in this
- specification (e.g., specific error conditions).
-
-
-
-
-Dusseault Standards Track [Page 71]
-
-RFC 4918 WebDAV June 2007
-
-
- If the Destination value is too long or otherwise unacceptable, the
- server SHOULD return 400 (Bad Request), ideally with helpful
- information in an error body.
-
-10.4. If Header
-
- The If request header is intended to have similar functionality to
- the If-Match header defined in Section 14.24 of [RFC2616]. However,
- the If header handles any state token as well as ETags. A typical
- example of a state token is a lock token, and lock tokens are the
- only state tokens defined in this specification.
-
-10.4.1. Purpose
-
- The If header has two distinct purposes:
-
- o The first purpose is to make a request conditional by supplying a
- series of state lists with conditions that match tokens and ETags
- to a specific resource. If this header is evaluated and all state
- lists fail, then the request MUST fail with a 412 (Precondition
- Failed) status. On the other hand, the request can succeed only
- if one of the described state lists succeeds. The success
- criteria for state lists and matching functions are defined in
- Sections 10.4.3 and 10.4.4.
-
- o Additionally, the mere fact that a state token appears in an If
- header means that it has been "submitted" with the request. In
- general, this is used to indicate that the client has knowledge of
- that state token. The semantics for submitting a state token
- depend on its type (for lock tokens, please refer to Section 6).
-
- Note that these two purposes need to be treated distinctly: a state
- token counts as being submitted independently of whether the server
- actually has evaluated the state list it appears in, and also
- independently of whether or not the condition it expressed was found
- to be true.
-
-10.4.2. Syntax
-
- If = "If" ":" ( 1*No-tag-list | 1*Tagged-list )
-
- No-tag-list = List
- Tagged-list = Resource-Tag 1*List
-
- List = "(" 1*Condition ")"
- Condition = ["Not"] (State-token | "[" entity-tag "]")
- ; entity-tag: see Section 3.11 of [RFC2616]
- ; No LWS allowed between "[", entity-tag and "]"
-
-
-
-Dusseault Standards Track [Page 72]
-
-RFC 4918 WebDAV June 2007
-
-
- State-token = Coded-URL
-
- Resource-Tag = "<" Simple-ref ">"
- ; Simple-ref: see Section 8.3
- ; No LWS allowed in Resource-Tag
-
- The syntax distinguishes between untagged lists ("No-tag-list") and
- tagged lists ("Tagged-list"). Untagged lists apply to the resource
- identified by the Request-URI, while tagged lists apply to the
- resource identified by the preceding Resource-Tag.
-
- A Resource-Tag applies to all subsequent Lists, up to the next
- Resource-Tag.
-
- Note that the two list types cannot be mixed within an If header.
- This is not a functional restriction because the No-tag-list syntax
- is just a shorthand notation for a Tagged-list production with a
- Resource-Tag referring to the Request-URI.
-
- Each List consists of one or more Conditions. Each Condition is
- defined in terms of an entity-tag or state-token, potentially negated
- by the prefix "Not".
-
- Note that the If header syntax does not allow multiple instances of
- If headers in a single request. However, the HTTP header syntax
- allows extending single header values across multiple lines, by
- inserting a line break followed by whitespace (see [RFC2616], Section
- 4.2).
-
-10.4.3. List Evaluation
-
- A Condition that consists of a single entity-tag or state-token
- evaluates to true if the resource matches the described state (where
- the individual matching functions are defined below in
- Section 10.4.4). Prefixing it with "Not" reverses the result of the
- evaluation (thus, the "Not" applies only to the subsequent entity-tag
- or state-token).
-
- Each List production describes a series of conditions. The whole
- list evaluates to true if and only if each condition evaluates to
- true (that is, the list represents a logical conjunction of
- Conditions).
-
- Each No-tag-list and Tagged-list production may contain one or more
- Lists. They evaluate to true if and only if any of the contained
- lists evaluates to true (that is, if there's more than one List, that
- List sequence represents a logical disjunction of the Lists).
-
-
-
-
-Dusseault Standards Track [Page 73]
-
-RFC 4918 WebDAV June 2007
-
-
- Finally, the whole If header evaluates to true if and only if at
- least one of the No-tag-list or Tagged-list productions evaluates to
- true. If the header evaluates to false, the server MUST reject the
- request with a 412 (Precondition Failed) status. Otherwise,
- execution of the request can proceed as if the header wasn't present.
-
-10.4.4. Matching State Tokens and ETags
-
- When performing If header processing, the definition of a matching
- state token or entity tag is as follows:
-
- Identifying a resource: The resource is identified by the URI along
- with the token, in tagged list production, or by the Request-URI in
- untagged list production.
-
- Matching entity tag: Where the entity tag matches an entity tag
- associated with the identified resource. Servers MUST use either the
- weak or the strong comparison function defined in Section 13.3.3 of
- [RFC2616].
-
- Matching state token: Where there is an exact match between the state
- token in the If header and any state token on the identified
- resource. A lock state token is considered to match if the resource
- is anywhere in the scope of the lock.
-
- Handling unmapped URLs: For both ETags and state tokens, treat as if
- the URL identified a resource that exists but does not have the
- specified state.
-
-10.4.5. If Header and Non-DAV-Aware Proxies
-
- Non-DAV-aware proxies will not honor the If header, since they will
- not understand the If header, and HTTP requires non-understood
- headers to be ignored. When communicating with HTTP/1.1 proxies, the
- client MUST use the "Cache-Control: no-cache" request header so as to
- prevent the proxy from improperly trying to service the request from
- its cache. When dealing with HTTP/1.0 proxies, the "Pragma: no-
- cache" request header MUST be used for the same reason.
-
- Because in general clients may not be able to reliably detect non-
- DAV-aware intermediates, they are advised to always prevent caching
- using the request directives mentioned above.
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 74]
-
-RFC 4918 WebDAV June 2007
-
-
-10.4.6. Example - No-tag Production
-
- If: (
- ["I am an ETag"])
- (["I am another ETag"])
-
- The previous header would require that the resource identified in the
- Request-URI be locked with the specified lock token and be in the
- state identified by the "I am an ETag" ETag or in the state
- identified by the second ETag "I am another ETag".
-
- To put the matter more plainly one can think of the previous If
- header as expressing the condition below:
-
- (
- is-locked-with(urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2) AND
- matches-etag("I am an ETag")
- )
- OR
- (
- matches-etag("I am another ETag")
- )
-
-10.4.7. Example - Using "Not" with No-tag Production
-
- If: (Not
- )
-
- This If header requires that the resource must not be locked with a
- lock having the lock token
- urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2 and must be locked by a
- lock with the lock token
- urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092.
-
-10.4.8. Example - Causing a Condition to Always Evaluate to True
-
- There may be cases where a client wishes to submit state tokens, but
- doesn't want the request to fail just because the state token isn't
- current anymore. One simple way to do this is to include a Condition
- that is known to always evaluate to true, such as in:
-
- If: ()
- (Not )
-
- "DAV:no-lock" is known to never represent a current lock token. Lock
- tokens are assigned by the server, following the uniqueness
- requirements described in Section 6.5, therefore cannot use the
- "DAV:" scheme. Thus, by applying "Not" to a state token that is
-
-
-
-Dusseault Standards Track [Page 75]
-
-RFC 4918 WebDAV June 2007
-
-
- known not to be current, the Condition always evaluates to true.
- Consequently, the whole If header will always evaluate to true, and
- the lock token urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2 will be
- submitted in any case.
-
-10.4.9. Example - Tagged List If Header in COPY
-
- >>Request
-
- COPY /resource1 HTTP/1.1
- Host: www.example.com
- Destination: /resource2
- If:
- (
- [W/"A weak ETag"]) (["strong ETag"])
-
- In this example, http://www.example.com/resource1 is being copied to
- http://www.example.com/resource2. When the method is first applied
- to http://www.example.com/resource1, resource1 must be in the state
- specified by "( [W/"A
- weak ETag"]) (["strong ETag"])". That is, either it must be locked
- with a lock token of "urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2"
- and have a weak entity tag W/"A weak ETag" or it must have a strong
- entity tag "strong ETag".
-
-10.4.10. Example - Matching Lock Tokens with Collection Locks
-
- DELETE /specs/rfc2518.txt HTTP/1.1
- Host: www.example.com
- If:
- ()
-
- For this example, the lock token must be compared to the identified
- resource, which is the 'specs' collection identified by the URL in
- the tagged list production. If the 'specs' collection is not locked
- by a lock with the specified lock token, the request MUST fail.
- Otherwise, this request could succeed, because the If header
- evaluates to true, and because the lock token for the lock affecting
- the affected resource has been submitted.
-
-10.4.11. Example - Matching ETags on Unmapped URLs
-
- Consider a collection "/specs" that does not contain the member
- "/specs/rfc2518.doc". In this case, the If header
-
- If: (["4217"])
-
-
-
-
-
-Dusseault Standards Track [Page 76]
-
-RFC 4918 WebDAV June 2007
-
-
- will evaluate to false (the URI isn't mapped, thus the resource
- identified by the URI doesn't have an entity matching the ETag
- "4217").
-
- On the other hand, an If header of
-
- If: (Not ["4217"])
-
- will consequently evaluate to true.
-
- Note that, as defined above in Section 10.4.4, the same
- considerations apply to matching state tokens.
-
-10.5. Lock-Token Header
-
- Lock-Token = "Lock-Token" ":" Coded-URL
-
- The Lock-Token request header is used with the UNLOCK method to
- identify the lock to be removed. The lock token in the Lock-Token
- request header MUST identify a lock that contains the resource
- identified by Request-URI as a member.
-
- The Lock-Token response header is used with the LOCK method to
- indicate the lock token created as a result of a successful LOCK
- request to create a new lock.
-
-10.6. Overwrite Header
-
- Overwrite = "Overwrite" ":" ("T" | "F")
-
- The Overwrite request header specifies whether the server should
- overwrite a resource mapped to the destination URL during a COPY or
- MOVE. A value of "F" states that the server must not perform the
- COPY or MOVE operation if the destination URL does map to a resource.
- If the overwrite header is not included in a COPY or MOVE request,
- then the resource MUST treat the request as if it has an overwrite
- header of value "T". While the Overwrite header appears to duplicate
- the functionality of using an "If-Match: *" header (see [RFC2616]),
- If-Match applies only to the Request-URI, and not to the Destination
- of a COPY or MOVE.
-
- If a COPY or MOVE is not performed due to the value of the Overwrite
- header, the method MUST fail with a 412 (Precondition Failed) status
- code. The server MUST do authorization checks before checking this
- or any conditional header.
-
- All DAV-compliant resources MUST support the Overwrite header.
-
-
-
-
-Dusseault Standards Track [Page 77]
-
-RFC 4918 WebDAV June 2007
-
-
-10.7. Timeout Request Header
-
- TimeOut = "Timeout" ":" 1#TimeType
- TimeType = ("Second-" DAVTimeOutVal | "Infinite")
- ; No LWS allowed within TimeType
- DAVTimeOutVal = 1*DIGIT
-
- Clients MAY include Timeout request headers in their LOCK requests.
- However, the server is not required to honor or even consider these
- requests. Clients MUST NOT submit a Timeout request header with any
- method other than a LOCK method.
-
- The "Second" TimeType specifies the number of seconds that will
- elapse between granting of the lock at the server, and the automatic
- removal of the lock. The timeout value for TimeType "Second" MUST
- NOT be greater than 2^32-1.
-
- See Section 6.6 for a description of lock timeout behavior.
-
-11. Status Code Extensions to HTTP/1.1
-
- The following status codes are added to those defined in HTTP/1.1
- [RFC2616].
-
-11.1. 207 Multi-Status
-
- The 207 (Multi-Status) status code provides status for multiple
- independent operations (see Section 13 for more information).
-
-11.2. 422 Unprocessable Entity
-
- The 422 (Unprocessable Entity) status code means the server
- understands the content type of the request entity (hence a
- 415(Unsupported Media Type) status code is inappropriate), and the
- syntax of the request entity is correct (thus a 400 (Bad Request)
- status code is inappropriate) but was unable to process the contained
- instructions. For example, this error condition may occur if an XML
- request body contains well-formed (i.e., syntactically correct), but
- semantically erroneous, XML instructions.
-
-11.3. 423 Locked
-
- The 423 (Locked) status code means the source or destination resource
- of a method is locked. This response SHOULD contain an appropriate
- precondition or postcondition code, such as 'lock-token-submitted' or
- 'no-conflicting-lock'.
-
-
-
-
-
-Dusseault Standards Track [Page 78]
-
-RFC 4918 WebDAV June 2007
-
-
-11.4. 424 Failed Dependency
-
- The 424 (Failed Dependency) status code means that the method could
- not be performed on the resource because the requested action
- depended on another action and that action failed. For example, if a
- command in a PROPPATCH method fails, then, at minimum, the rest of
- the commands will also fail with 424 (Failed Dependency).
-
-11.5. 507 Insufficient Storage
-
- The 507 (Insufficient Storage) status code means the method could not
- be performed on the resource because the server is unable to store
- the representation needed to successfully complete the request. This
- condition is considered to be temporary. If the request that
- received this status code was the result of a user action, the
- request MUST NOT be repeated until it is requested by a separate user
- action.
-
-12. Use of HTTP Status Codes
-
- These HTTP codes are not redefined, but their use is somewhat
- extended by WebDAV methods and requirements. In general, many HTTP
- status codes can be used in response to any request, not just in
- cases described in this document. Note also that WebDAV servers are
- known to use 300-level redirect responses (and early interoperability
- tests found clients unprepared to see those responses). A 300-level
- response MUST NOT be used when the server has created a new resource
- in response to the request.
-
-12.1. 412 Precondition Failed
-
- Any request can contain a conditional header defined in HTTP (If-
- Match, If-Modified-Since, etc.) or the "If" or "Overwrite"
- conditional headers defined in this specification. If the server
- evaluates a conditional header, and if that condition fails to hold,
- then this error code MUST be returned. On the other hand, if the
- client did not include a conditional header in the request, then the
- server MUST NOT use this status code.
-
-12.2. 414 Request-URI Too Long
-
- This status code is used in HTTP 1.1 only for Request-URIs, not URIs
- in other locations.
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 79]
-
-RFC 4918 WebDAV June 2007
-
-
-13. Multi-Status Response
-
- A Multi-Status response conveys information about multiple resources
- in situations where multiple status codes might be appropriate. The
- default Multi-Status response body is a text/xml or application/xml
- HTTP entity with a 'multistatus' root element. Further elements
- contain 200, 300, 400, and 500 series status codes generated during
- the method invocation. 100 series status codes SHOULD NOT be recorded
- in a 'response' XML element.
-
- Although '207' is used as the overall response status code, the
- recipient needs to consult the contents of the multistatus response
- body for further information about the success or failure of the
- method execution. The response MAY be used in success, partial
- success and also in failure situations.
-
- The 'multistatus' root element holds zero or more 'response' elements
- in any order, each with information about an individual resource.
- Each 'response' element MUST have an 'href' element to identify the
- resource.
-
- A Multi-Status response uses one out of two distinct formats for
- representing the status:
-
- 1. A 'status' element as child of the 'response' element indicates
- the status of the message execution for the identified resource
- as a whole (for instance, see Section 9.6.2). Some method
- definitions provide information about specific status codes
- clients should be prepared to see in a response. However,
- clients MUST be able to handle other status codes, using the
- generic rules defined in Section 10 of [RFC2616].
-
- 2. For PROPFIND and PROPPATCH, the format has been extended using
- the 'propstat' element instead of 'status', providing information
- about individual properties of a resource. This format is
- specific to PROPFIND and PROPPATCH, and is described in detail in
- Sections 9.1 and 9.2.
-
-13.1. Response Headers
-
- HTTP defines the Location header to indicate a preferred URL for the
- resource that was addressed in the Request-URI (e.g., in response to
- successful PUT requests or in redirect responses). However, use of
- this header creates ambiguity when there are URLs in the body of the
- response, as with Multi-Status. Thus, use of the Location header
- with the Multi-Status response is intentionally undefined.
-
-
-
-
-
-Dusseault Standards Track [Page 80]
-
-RFC 4918 WebDAV June 2007
-
-
-13.2. Handling Redirected Child Resources
-
- Redirect responses (300-303, 305, and 307) defined in HTTP 1.1
- normally take a Location header to indicate the new URI for the
- single resource redirected from the Request-URI. Multi-Status
- responses contain many resource addresses, but the original
- definition in [RFC2518] did not have any place for the server to
- provide the new URI for redirected resources. This specification
- does define a 'location' element for this information (see
- Section 14.9). Servers MUST use this new element with redirect
- responses in Multi-Status.
-
- Clients encountering redirected resources in Multi-Status MUST NOT
- rely on the 'location' element being present with a new URI. If the
- element is not present, the client MAY reissue the request to the
- individual redirected resource, because the response to that request
- can be redirected with a Location header containing the new URI.
-
-13.3. Internal Status Codes
-
- Sections 9.2.1, 9.1.2, 9.6.1, 9.8.3, and 9.9.2 define various status
- codes used in Multi-Status responses. This specification does not
- define the meaning of other status codes that could appear in these
- responses.
-
-14. XML Element Definitions
-
- In this section, the final line of each section gives the element
- type declaration using the format defined in [REC-XML]. The "Value"
- field, where present, specifies further restrictions on the allowable
- contents of the XML element using BNF (i.e., to further restrict the
- values of a PCDATA element). Note that all of the elements defined
- here may be extended according to the rules defined in Section 17.
- All elements defined here are in the "DAV:" namespace.
-
-14.1. activelock XML Element
-
- Name: activelock
-
- Purpose: Describes a lock on a resource.
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 81]
-
-RFC 4918 WebDAV June 2007
-
-
-14.2. allprop XML Element
-
- Name: allprop
-
- Purpose: Specifies that all names and values of dead properties and
- the live properties defined by this document existing on the
- resource are to be returned.
-
-
-
-14.3. collection XML Element
-
- Name: collection
-
- Purpose: Identifies the associated resource as a collection. The
- DAV:resourcetype property of a collection resource MUST contain
- this element. It is normally empty but extensions may add sub-
- elements.
-
-
-
-14.4. depth XML Element
-
- Name: depth
-
- Purpose: Used for representing depth values in XML content (e.g.,
- in lock information).
-
- Value: "0" | "1" | "infinity"
-
-
-
-14.5. error XML Element
-
- Name: error
-
- Purpose: Error responses, particularly 403 Forbidden and 409
- Conflict, sometimes need more information to indicate what went
- wrong. In these cases, servers MAY return an XML response body
- with a document element of 'error', containing child elements
- identifying particular condition codes.
-
- Description: Contains at least one XML element, and MUST NOT
- contain text or mixed content. Any element that is a child of the
- 'error' element is considered to be a precondition or
- postcondition code. Unrecognized elements MUST be ignored.
-
-
-
-
-
-Dusseault Standards Track [Page 82]
-
-RFC 4918 WebDAV June 2007
-
-
-14.6. exclusive XML Element
-
- Name: exclusive
-
- Purpose: Specifies an exclusive lock.
-
-
-
-
-
-14.7. href XML Element
-
- Name: href
-
- Purpose: MUST contain a URI or a relative reference.
-
- Description: There may be limits on the value of 'href' depending
- on the context of its use. Refer to the specification text where
- 'href' is used to see what limitations apply in each case.
-
- Value: Simple-ref
-
-
-
-
-14.8. include XML Element
-
- Name: include
-
- Purpose: Any child element represents the name of a property to be
- included in the PROPFIND response. All elements inside an
- 'include' XML element MUST define properties related to the
- resource, although possible property names are in no way limited
- to those property names defined in this document or other
- standards. This element MUST NOT contain text or mixed content.
-
-
-
-14.9. location XML Element
-
- Name: location
-
- Purpose: HTTP defines the "Location" header (see [RFC2616], Section
- 14.30) for use with some status codes (such as 201 and the 300
- series codes). When these codes are used inside a 'multistatus'
- element, the 'location' element can be used to provide the
- accompanying Location header value.
-
-
-
-
-Dusseault Standards Track [Page 83]
-
-RFC 4918 WebDAV June 2007
-
-
- Description: Contains a single href element with the same value
- that would be used in a Location header.
-
-
-
-
-14.10. lockentry XML Element
-
- Name: lockentry
-
- Purpose: Defines the types of locks that can be used with the
- resource.
-
-
-
-14.11. lockinfo XML Element
-
- Name: lockinfo
-
- Purpose: The 'lockinfo' XML element is used with a LOCK method to
- specify the type of lock the client wishes to have created.
-
-
-
-
-14.12. lockroot XML Element
-
- Name: lockroot
-
- Purpose: Contains the root URL of the lock, which is the URL
- through which the resource was addressed in the LOCK request.
-
- Description: The href element contains the root of the lock. The
- server SHOULD include this in all DAV:lockdiscovery property
- values and the response to LOCK requests.
-
-
-
-14.13. lockscope XML Element
-
- Name: lockscope
-
- Purpose: Specifies whether a lock is an exclusive lock, or a shared
- lock.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 84]
-
-RFC 4918 WebDAV June 2007
-
-
-14.14. locktoken XML Element
-
- Name: locktoken
-
- Purpose: The lock token associated with a lock.
-
- Description: The href contains a single lock token URI, which
- refers to the lock.
-
-
-
-14.15. locktype XML Element
-
- Name: locktype
-
- Purpose: Specifies the access type of a lock. At present, this
- specification only defines one lock type, the write lock.
-
-
-
-
-
-14.16. multistatus XML Element
-
- Name: multistatus
-
- Purpose: Contains multiple response messages.
-
- Description: The 'responsedescription' element at the top level is
- used to provide a general message describing the overarching
- nature of the response. If this value is available, an
- application may use it instead of presenting the individual
- response descriptions contained within the responses.
-
-
-
-
-
-14.17. owner XML Element
-
- Name: owner
-
- Purpose: Holds client-supplied information about the creator of a
- lock.
-
- Description: Allows a client to provide information sufficient for
- either directly contacting a principal (such as a telephone number
- or Email URI), or for discovering the principal (such as the URL
-
-
-
-Dusseault Standards Track [Page 85]
-
-RFC 4918 WebDAV June 2007
-
-
- of a homepage) who created a lock. The value provided MUST be
- treated as a dead property in terms of XML Information Item
- preservation. The server MUST NOT alter the value unless the
- owner value provided by the client is empty. For a certain amount
- of interoperability between different client implementations, if
- clients have URI-formatted contact information for the lock
- creator suitable for user display, then clients SHOULD put those
- URIs in 'href' child elements of the 'owner' element.
-
- Extensibility: MAY be extended with child elements, mixed content,
- text content or attributes.
-
-
-
-14.18. prop XML Element
-
- Name: prop
-
- Purpose: Contains properties related to a resource.
-
- Description: A generic container for properties defined on
- resources. All elements inside a 'prop' XML element MUST define
- properties related to the resource, although possible property
- names are in no way limited to those property names defined in
- this document or other standards. This element MUST NOT contain
- text or mixed content.
-
-
-
-14.19. propertyupdate XML Element
-
- Name: propertyupdate
-
- Purpose: Contains a request to alter the properties on a resource.
-
- Description: This XML element is a container for the information
- required to modify the properties on the resource.
-
-
-
-14.20. propfind XML Element
-
- Name: propfind
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 86]
-
-RFC 4918 WebDAV June 2007
-
-
- Purpose: Specifies the properties to be returned from a PROPFIND
- method. Four special elements are specified for use with
- 'propfind': 'prop', 'allprop', 'include', and 'propname'. If
- 'prop' is used inside 'propfind', it MUST NOT contain property
- values.
-
-
-
-14.21. propname XML Element
-
- Name: propname
-
- Purpose: Specifies that only a list of property names on the
- resource is to be returned.
-
-
-
-14.22. propstat XML Element
-
- Name: propstat
-
- Purpose: Groups together a prop and status element that is
- associated with a particular 'href' element.
-
- Description: The propstat XML element MUST contain one prop XML
- element and one status XML element. The contents of the prop XML
- element MUST only list the names of properties to which the result
- in the status element applies. The optional precondition/
- postcondition element and 'responsedescription' text also apply to
- the properties named in 'prop'.
-
-
-
-14.23. remove XML Element
-
- Name: remove
-
- Purpose: Lists the properties to be removed from a resource.
-
- Description: Remove instructs that the properties specified in prop
- should be removed. Specifying the removal of a property that does
- not exist is not an error. All the XML elements in a 'prop' XML
- element inside of a 'remove' XML element MUST be empty, as only
- the names of properties to be removed are required.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 87]
-
-RFC 4918 WebDAV June 2007
-
-
-14.24. response XML Element
-
- Name: response
-
- Purpose: Holds a single response describing the effect of a method
- on resource and/or its properties.
-
- Description: The 'href' element contains an HTTP URL pointing to a
- WebDAV resource when used in the 'response' container. A
- particular 'href' value MUST NOT appear more than once as the
- child of a 'response' XML element under a 'multistatus' XML
- element. This requirement is necessary in order to keep
- processing costs for a response to linear time. Essentially, this
- prevents having to search in order to group together all the
- responses by 'href'. There are, however, no requirements
- regarding ordering based on 'href' values. The optional
- precondition/postcondition element and 'responsedescription' text
- can provide additional information about this resource relative to
- the request or result.
-
-
-
-
-14.25. responsedescription XML Element
-
- Name: responsedescription
-
- Purpose: Contains information about a status response within a
- Multi-Status.
-
- Description: Provides information suitable to be presented to a
- user.
-
-
-
-14.26. set XML Element
-
- Name: set
-
- Purpose: Lists the property values to be set for a resource.
-
- Description: The 'set' element MUST contain only a 'prop' element.
- The elements contained by the 'prop' element inside the 'set'
- element MUST specify the name and value of properties that are set
- on the resource identified by Request-URI. If a property already
- exists, then its value is replaced. Language tagging information
- appearing in the scope of the 'prop' element (in the "xml:lang"
-
-
-
-Dusseault Standards Track [Page 88]
-
-RFC 4918 WebDAV June 2007
-
-
- attribute, if present) MUST be persistently stored along with the
- property, and MUST be subsequently retrievable using PROPFIND.
-
-
-
-14.27. shared XML Element
-
- Name: shared
-
- Purpose: Specifies a shared lock.
-
-
-
-
-
-14.28. status XML Element
-
- Name: status
-
- Purpose: Holds a single HTTP status-line.
-
- Value: status-line (defined in Section 6.1 of [RFC2616])
-
-
-
-14.29. timeout XML Element
-
- Name: timeout
-
- Purpose: The number of seconds remaining before a lock expires.
-
- Value: TimeType (defined in Section 10.7)
-
-
-
-
-14.30. write XML Element
-
- Name: write
-
- Purpose: Specifies a write lock.
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 89]
-
-RFC 4918 WebDAV June 2007
-
-
-15. DAV Properties
-
- For DAV properties, the name of the property is also the same as the
- name of the XML element that contains its value. In the section
- below, the final line of each section gives the element type
- declaration using the format defined in [REC-XML]. The "Value"
- field, where present, specifies further restrictions on the allowable
- contents of the XML element using BNF (i.e., to further restrict the
- values of a PCDATA element).
-
- A protected property is one that cannot be changed with a PROPPATCH
- request. There may be other requests that would result in a change
- to a protected property (as when a LOCK request affects the value of
- DAV:lockdiscovery). Note that a given property could be protected on
- one type of resource, but not protected on another type of resource.
-
- A computed property is one with a value defined in terms of a
- computation (based on the content and other properties of that
- resource, or even of some other resource). A computed property is
- always a protected property.
-
- COPY and MOVE behavior refers to local COPY and MOVE operations.
-
- For properties defined based on HTTP GET response headers (DAV:get*),
- the header value could include LWS as defined in [RFC2616], Section
- 4.2. Server implementors SHOULD strip LWS from these values before
- using as WebDAV property values.
-
-15.1. creationdate Property
-
- Name: creationdate
-
- Purpose: Records the time and date the resource was created.
-
- Value: date-time (defined in [RFC3339], see the ABNF in Section
- 5.6.)
-
- Protected: MAY be protected. Some servers allow DAV:creationdate
- to be changed to reflect the time the document was created if that
- is more meaningful to the user (rather than the time it was
- uploaded). Thus, clients SHOULD NOT use this property in
- synchronization logic (use DAV:getetag instead).
-
- COPY/MOVE behavior: This property value SHOULD be kept during a
- MOVE operation, but is normally re-initialized when a resource is
- created with a COPY. It should not be set in a COPY.
-
-
-
-
-
-Dusseault Standards Track [Page 90]
-
-RFC 4918 WebDAV June 2007
-
-
- Description: The DAV:creationdate property SHOULD be defined on all
- DAV compliant resources. If present, it contains a timestamp of
- the moment when the resource was created. Servers that are
- incapable of persistently recording the creation date SHOULD
- instead leave it undefined (i.e. report "Not Found").
-
-
-
-15.2. displayname Property
-
- Name: displayname
-
- Purpose: Provides a name for the resource that is suitable for
- presentation to a user.
-
- Value: Any text.
-
- Protected: SHOULD NOT be protected. Note that servers implementing
- [RFC2518] might have made this a protected property as this is a
- new requirement.
-
- COPY/MOVE behavior: This property value SHOULD be preserved in COPY
- and MOVE operations.
-
- Description: Contains a description of the resource that is
- suitable for presentation to a user. This property is defined on
- the resource, and hence SHOULD have the same value independent of
- the Request-URI used to retrieve it (thus, computing this property
- based on the Request-URI is deprecated). While generic clients
- might display the property value to end users, client UI designers
- must understand that the method for identifying resources is still
- the URL. Changes to DAV:displayname do not issue moves or copies
- to the server, but simply change a piece of meta-data on the
- individual resource. Two resources can have the same DAV:
- displayname value even within the same collection.
-
-
-
-15.3. getcontentlanguage Property
-
- Name: getcontentlanguage
-
- Purpose: Contains the Content-Language header value (from Section
- 14.12 of [RFC2616]) as it would be returned by a GET without
- accept headers.
-
- Value: language-tag (language-tag is defined in Section 3.10 of
- [RFC2616])
-
-
-
-Dusseault Standards Track [Page 91]
-
-RFC 4918 WebDAV June 2007
-
-
- Protected: SHOULD NOT be protected, so that clients can reset the
- language. Note that servers implementing [RFC2518] might have
- made this a protected property as this is a new requirement.
-
- COPY/MOVE behavior: This property value SHOULD be preserved in COPY
- and MOVE operations.
-
- Description: The DAV:getcontentlanguage property MUST be defined on
- any DAV-compliant resource that returns the Content-Language
- header on a GET.
-
-
-
-15.4. getcontentlength Property
-
- Name: getcontentlength
-
- Purpose: Contains the Content-Length header returned by a GET
- without accept headers.
-
- Value: See Section 14.13 of [RFC2616].
-
- Protected: This property is computed, therefore protected.
-
- Description: The DAV:getcontentlength property MUST be defined on
- any DAV-compliant resource that returns the Content-Length header
- in response to a GET.
-
- COPY/MOVE behavior: This property value is dependent on the size of
- the destination resource, not the value of the property on the
- source resource.
-
-
-
-15.5. getcontenttype Property
-
- Name: getcontenttype
-
- Purpose: Contains the Content-Type header value (from Section 14.17
- of [RFC2616]) as it would be returned by a GET without accept
- headers.
-
- Value: media-type (defined in Section 3.7 of [RFC2616])
-
- Protected: Potentially protected if the server prefers to assign
- content types on its own (see also discussion in Section 9.7.1).
-
-
-
-
-
-Dusseault Standards Track [Page 92]
-
-RFC 4918 WebDAV June 2007
-
-
- COPY/MOVE behavior: This property value SHOULD be preserved in COPY
- and MOVE operations.
-
- Description: This property MUST be defined on any DAV-compliant
- resource that returns the Content-Type header in response to a
- GET.
-
-
-
-15.6. getetag Property
-
- Name: getetag
-
- Purpose: Contains the ETag header value (from Section 14.19 of
- [RFC2616]) as it would be returned by a GET without accept
- headers.
-
- Value: entity-tag (defined in Section 3.11 of [RFC2616])
-
- Protected: MUST be protected because this value is created and
- controlled by the server.
-
- COPY/MOVE behavior: This property value is dependent on the final
- state of the destination resource, not the value of the property
- on the source resource. Also note the considerations in
- Section 8.8.
-
- Description: The getetag property MUST be defined on any DAV-
- compliant resource that returns the Etag header. Refer to Section
- 3.11 of RFC 2616 for a complete definition of the semantics of an
- ETag, and to Section 8.6 for a discussion of ETags in WebDAV.
-
-
-
-15.7. getlastmodified Property
-
- Name: getlastmodified
-
- Purpose: Contains the Last-Modified header value (from Section
- 14.29 of [RFC2616]) as it would be returned by a GET method
- without accept headers.
-
- Value: rfc1123-date (defined in Section 3.3.1 of [RFC2616])
-
- Protected: SHOULD be protected because some clients may rely on the
- value for appropriate caching behavior, or on the value of the
- Last-Modified header to which this property is linked.
-
-
-
-
-Dusseault Standards Track [Page 93]
-
-RFC 4918 WebDAV June 2007
-
-
- COPY/MOVE behavior: This property value is dependent on the last
- modified date of the destination resource, not the value of the
- property on the source resource. Note that some server
- implementations use the file system date modified value for the
- DAV:getlastmodified value, and this can be preserved in a MOVE
- even when the HTTP Last-Modified value SHOULD change. Note that
- since [RFC2616] requires clients to use ETags where provided, a
- server implementing ETags can count on clients using a much better
- mechanism than modification dates for offline synchronization or
- cache control. Also note the considerations in Section 8.8.
-
- Description: The last-modified date on a resource SHOULD only
- reflect changes in the body (the GET responses) of the resource.
- A change in a property only SHOULD NOT cause the last-modified
- date to change, because clients MAY rely on the last-modified date
- to know when to overwrite the existing body. The DAV:
- getlastmodified property MUST be defined on any DAV-compliant
- resource that returns the Last-Modified header in response to a
- GET.
-
-
-
-15.8. lockdiscovery Property
-
- Name: lockdiscovery
-
- Purpose: Describes the active locks on a resource
-
- Protected: MUST be protected. Clients change the list of locks
- through LOCK and UNLOCK, not through PROPPATCH.
-
- COPY/MOVE behavior: The value of this property depends on the lock
- state of the destination, not on the locks of the source resource.
- Recall that locks are not moved in a MOVE operation.
-
- Description: Returns a listing of who has a lock, what type of lock
- he has, the timeout type and the time remaining on the timeout,
- and the associated lock token. Owner information MAY be omitted
- if it is considered sensitive. If there are no locks, but the
- server supports locks, the property will be present but contain
- zero 'activelock' elements. If there are one or more locks, an
- 'activelock' element appears for each lock on the resource. This
- property is NOT lockable with respect to write locks (Section 7).
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 94]
-
-RFC 4918 WebDAV June 2007
-
-
-15.8.1. Example - Retrieving DAV:lockdiscovery
-
- >>Request
-
- PROPFIND /container/ HTTP/1.1
- Host: www.example.com
- Content-Length: xxxx
- Content-Type: application/xml; charset="utf-8"
-
-
-
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/container/
-
-
-
-
-
-
- 0
- Jane Smith
- Infinite
-
- urn:uuid:f81de2ad-7f3d-a1b2-4f3c-00a0c91a9d76
-
-
- http://www.example.com/container/
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 95]
-
-RFC 4918 WebDAV June 2007
-
-
- This resource has a single exclusive write lock on it, with an
- infinite timeout.
-
-15.9. resourcetype Property
-
- Name: resourcetype
-
- Purpose: Specifies the nature of the resource.
-
- Protected: SHOULD be protected. Resource type is generally decided
- through the operation creating the resource (MKCOL vs PUT), not by
- PROPPATCH.
-
- COPY/MOVE behavior: Generally a COPY/MOVE of a resource results in
- the same type of resource at the destination.
-
- Description: MUST be defined on all DAV-compliant resources. Each
- child element identifies a specific type the resource belongs to,
- such as 'collection', which is the only resource type defined by
- this specification (see Section 14.3). If the element contains
- the 'collection' child element plus additional unrecognized
- elements, it should generally be treated as a collection. If the
- element contains no recognized child elements, it should be
- treated as a non-collection resource. The default value is empty.
- This element MUST NOT contain text or mixed content. Any custom
- child element is considered to be an identifier for a resource
- type.
-
- Example: (fictional example to show extensibility)
-
-
-
-
-
-
-15.10. supportedlock Property
-
- Name: supportedlock
-
- Purpose: To provide a listing of the lock capabilities supported by
- the resource.
-
- Protected: MUST be protected. Servers, not clients, determine what
- lock mechanisms are supported.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 96]
-
-RFC 4918 WebDAV June 2007
-
-
- COPY/MOVE behavior: This property value is dependent on the kind of
- locks supported at the destination, not on the value of the
- property at the source resource. Servers attempting to COPY to a
- destination should not attempt to set this property at the
- destination.
-
- Description: Returns a listing of the combinations of scope and
- access types that may be specified in a lock request on the
- resource. Note that the actual contents are themselves controlled
- by access controls, so a server is not required to provide
- information the client is not authorized to see. This property is
- NOT lockable with respect to write locks (Section 7).
-
-
-
-15.10.1. Example - Retrieving DAV:supportedlock
-
- >>Request
-
- PROPFIND /container/ HTTP/1.1
- Host: www.example.com
- Content-Length: xxxx
- Content-Type: application/xml; charset="utf-8"
-
-
-
-
-
-
- >>Response
-
- HTTP/1.1 207 Multi-Status
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- http://www.example.com/container/
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 97]
-
-RFC 4918 WebDAV June 2007
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-
-16. Precondition/Postcondition XML Elements
-
- As introduced in Section 8.7, extra information on error conditions
- can be included in the body of many status responses. This section
- makes requirements on the use of the error body mechanism and
- introduces a number of precondition and postcondition codes.
-
- A "precondition" of a method describes the state of the server that
- must be true for that method to be performed. A "postcondition" of a
- method describes the state of the server that must be true after that
- method has been completed.
-
- Each precondition and postcondition has a unique XML element
- associated with it. In a 207 Multi-Status response, the XML element
- MUST appear inside an 'error' element in the appropriate 'propstat or
- 'response' element depending on whether the condition applies to one
- or more properties or to the resource as a whole. In all other error
- responses where this specification's 'error' body is used, the
- precondition/postcondition XML element MUST be returned as the child
- of a top-level 'error' element in the response body, unless otherwise
- negotiated by the request, along with an appropriate response status.
- The most common response status codes are 403 (Forbidden) if the
- request should not be repeated because it will always fail, and 409
- (Conflict) if it is expected that the user might be able to resolve
- the conflict and resubmit the request. The 'error' element MAY
- contain child elements with specific error information and MAY be
- extended with any custom child elements.
-
- This mechanism does not take the place of using a correct numeric
- status code as defined here or in HTTP, because the client must
- always be able to take a reasonable course of action based only on
- the numeric code. However, it does remove the need to define new
- numeric codes. The new machine-readable codes used for this purpose
- are XML elements classified as preconditions and postconditions, so
- naturally, any group defining a new condition code can use their own
- namespace. As always, the "DAV:" namespace is reserved for use by
- IETF-chartered WebDAV working groups.
-
-
-
-
-
-Dusseault Standards Track [Page 98]
-
-RFC 4918 WebDAV June 2007
-
-
- A server supporting this specification SHOULD use the XML error
- whenever a precondition or postcondition defined in this document is
- violated. For error conditions not specified in this document, the
- server MAY simply choose an appropriate numeric status and leave the
- response body blank. However, a server MAY instead use a custom
- condition code and other supporting text, because even when clients
- do not automatically recognize condition codes, they can be quite
- useful in interoperability testing and debugging.
-
- Example - Response with precondition code
-
- >>Response
-
- HTTP/1.1 423 Locked
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /workspace/webdav/
-
-
-
- In this example, a client unaware of a depth-infinity lock on the
- parent collection "/workspace/webdav/" attempted to modify the
- collection member "/workspace/webdav/proposal.doc".
-
- Some other useful preconditions and postconditions have been defined
- in other specifications extending WebDAV, such as [RFC3744] (see
- particularly Section 7.1.1), [RFC3253], and [RFC3648].
-
- All these elements are in the "DAV:" namespace. If not specified
- otherwise, the content for each condition's XML element is defined to
- be empty.
-
-
- Name: lock-token-matches-request-uri
-
- Use with: 409 Conflict
-
- Purpose: (precondition) -- A request may include a Lock-Token header
- to identify a lock for the UNLOCK method. However, if the
- Request-URI does not fall within the scope of the lock identified
- by the token, the server SHOULD use this error. The lock may have
- a scope that does not include the Request-URI, or the lock could
- have disappeared, or the token may be invalid.
-
-
-
-
-Dusseault Standards Track [Page 99]
-
-RFC 4918 WebDAV June 2007
-
-
- Name: lock-token-submitted (precondition)
-
- Use with: 423 Locked
-
- Purpose: The request could not succeed because a lock token should
- have been submitted. This element, if present, MUST contain at
- least one URL of a locked resource that prevented the request. In
- cases of MOVE, COPY, and DELETE where collection locks are
- involved, it can be difficult for the client to find out which
- locked resource made the request fail -- but the server is only
- responsible for returning one such locked resource. The server
- MAY return every locked resource that prevented the request from
- succeeding if it knows them all.
-
-
-
-
- Name: no-conflicting-lock (precondition)
-
- Use with: Typically 423 Locked
-
- Purpose: A LOCK request failed due the presence of an already
- existing conflicting lock. Note that a lock can be in conflict
- although the resource to which the request was directed is only
- indirectly locked. In this case, the precondition code can be
- used to inform the client about the resource that is the root of
- the conflicting lock, avoiding a separate lookup of the
- "lockdiscovery" property.
-
-
-
-
- Name: no-external-entities
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- If the server rejects a client request
- because the request body contains an external entity, the server
- SHOULD use this error.
-
-
- Name: preserved-live-properties
-
- Use with: 409 Conflict
-
- Purpose: (postcondition) -- The server received an otherwise-valid
- MOVE or COPY request, but cannot maintain the live properties with
- the same behavior at the destination. It may be that the server
-
-
-
-Dusseault Standards Track [Page 100]
-
-RFC 4918 WebDAV June 2007
-
-
- only supports some live properties in some parts of the
- repository, or simply has an internal error.
-
-
- Name: propfind-finite-depth
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- This server does not allow infinite-depth
- PROPFIND requests on collections.
-
-
- Name: cannot-modify-protected-property
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- The client attempted to set a protected
- property in a PROPPATCH (such as DAV:getetag). See also
- [RFC3253], Section 3.12.
-
-17. XML Extensibility in DAV
-
- The XML namespace extension ([REC-XML-NAMES]) is used in this
- specification in order to allow for new XML elements to be added
- without fear of colliding with other element names. Although WebDAV
- request and response bodies can be extended by arbitrary XML
- elements, which can be ignored by the message recipient, an XML
- element in the "DAV:" namespace SHOULD NOT be used in the request or
- response body unless that XML element is explicitly defined in an
- IETF RFC reviewed by a WebDAV working group.
-
- For WebDAV to be both extensible and backwards-compatible, both
- clients and servers need to know how to behave when unexpected or
- unrecognized command extensions are received. For XML processing,
- this means that clients and servers MUST process received XML
- documents as if unexpected elements and attributes (and all children
- of unrecognized elements) were not there. An unexpected element or
- attribute includes one that may be used in another context but is not
- expected here. Ignoring such items for purposes of processing can of
- course be consistent with logging all information or presenting for
- debugging.
-
- This restriction also applies to the processing, by clients, of DAV
- property values where unexpected XML elements SHOULD be ignored
- unless the property's schema declares otherwise.
-
- This restriction does not apply to setting dead DAV properties on the
- server where the server MUST record all XML elements.
-
-
-
-Dusseault Standards Track [Page 101]
-
-RFC 4918 WebDAV June 2007
-
-
- Additionally, this restriction does not apply to the use of XML where
- XML happens to be the content type of the entity body, for example,
- when used as the body of a PUT.
-
- Processing instructions in XML SHOULD be ignored by recipients.
- Thus, specifications extending WebDAV SHOULD NOT use processing
- instructions to define normative behavior.
-
- XML DTD fragments are included for all the XML elements defined in
- this specification. However, correct XML will not be valid according
- to any DTD due to namespace usage and extension rules. In
- particular:
-
- o Elements (from this specification) are in the "DAV:" namespace,
-
- o Element ordering is irrelevant unless otherwise stated,
-
- o Extension attributes MAY be added,
-
- o For element type definitions of "ANY", the normative text
- definition for that element defines what can be in it and what
- that means.
-
- o For element type definitions of "#PCDATA", extension elements MUST
- NOT be added.
-
- o For other element type definitions, including "EMPTY", extension
- elements MAY be added.
-
- Note that this means that elements containing elements cannot be
- extended to contain text, and vice versa.
-
- With DTD validation relaxed by the rules above, the constraints
- described by the DTD fragments are normative (see for example
- Appendix A). A recipient of a WebDAV message with an XML body MUST
- NOT validate the XML document according to any hard-coded or
- dynamically-declared DTD.
-
- Note that this section describes backwards-compatible extensibility
- rules. There might also be times when an extension is designed not
- to be backwards-compatible, for example, defining an extension that
- reuses an XML element defined in this document but omitting one of
- the child elements required by the DTDs in this specification.
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 102]
-
-RFC 4918 WebDAV June 2007
-
-
-18. DAV Compliance Classes
-
- A DAV-compliant resource can advertise several classes of compliance.
- A client can discover the compliance classes of a resource by
- executing OPTIONS on the resource and examining the "DAV" header
- which is returned. Note particularly that resources, rather than
- servers, are spoken of as being compliant. That is because
- theoretically some resources on a server could support different
- feature sets. For example, a server could have a sub-repository
- where an advanced feature like versioning was supported, even if that
- feature was not supported on all sub-repositories.
-
- Since this document describes extensions to the HTTP/1.1 protocol,
- minimally all DAV-compliant resources, clients, and proxies MUST be
- compliant with [RFC2616].
-
- A resource that is class 2 or class 3 compliant must also be class 1
- compliant.
-
-18.1. Class 1
-
- A class 1 compliant resource MUST meet all "MUST" requirements in all
- sections of this document.
-
- Class 1 compliant resources MUST return, at minimum, the value "1" in
- the DAV header on all responses to the OPTIONS method.
-
-18.2. Class 2
-
- A class 2 compliant resource MUST meet all class 1 requirements and
- support the LOCK method, the DAV:supportedlock property, the DAV:
- lockdiscovery property, the Time-Out response header and the Lock-
- Token request header. A class 2 compliant resource SHOULD also
- support the Timeout request header and the 'owner' XML element.
-
- Class 2 compliant resources MUST return, at minimum, the values "1"
- and "2" in the DAV header on all responses to the OPTIONS method.
-
-18.3. Class 3
-
- A resource can explicitly advertise its support for the revisions to
- [RFC2518] made in this document. Class 1 MUST be supported as well.
- Class 2 MAY be supported. Advertising class 3 support in addition to
- class 1 and 2 means that the server supports all the requirements in
- this specification. Advertising class 3 and class 1 support, but not
- class 2, means that the server supports all the requirements in this
- specification except possibly those that involve locking support.
-
-
-
-
-Dusseault Standards Track [Page 103]
-
-RFC 4918 WebDAV June 2007
-
-
- Example:
-
- DAV: 1, 3
-
-19. Internationalization Considerations
-
- In the realm of internationalization, this specification complies
- with the IETF Character Set Policy [RFC2277]. In this specification,
- human-readable fields can be found either in the value of a property,
- or in an error message returned in a response entity body. In both
- cases, the human-readable content is encoded using XML, which has
- explicit provisions for character set tagging and encoding, and
- requires that XML processors read XML elements encoded, at minimum,
- using the UTF-8 [RFC3629] and UTF-16 [RFC2781] encodings of the ISO
- 10646 multilingual plane. XML examples in this specification
- demonstrate use of the charset parameter of the Content-Type header
- (defined in [RFC3023]), as well as XML charset declarations.
-
- XML also provides a language tagging capability for specifying the
- language of the contents of a particular XML element. The "xml:lang"
- attribute appears on an XML element to identify the language of its
- content and attributes. See [REC-XML] for definitions of values and
- scoping.
-
- WebDAV applications MUST support the character set tagging, character
- set encoding, and the language tagging functionality of the XML
- specification. Implementors of WebDAV applications are strongly
- encouraged to read "XML Media Types" [RFC3023] for instruction on
- which MIME media type to use for XML transport, and on use of the
- charset parameter of the Content-Type header.
-
- Names used within this specification fall into four categories: names
- of protocol elements such as methods and headers, names of XML
- elements, names of properties, and names of conditions. Naming of
- protocol elements follows the precedent of HTTP, using English names
- encoded in US-ASCII for methods and headers. Since these protocol
- elements are not visible to users, and are simply long token
- identifiers, they do not need to support multiple languages.
- Similarly, the names of XML elements used in this specification are
- not visible to the user and hence do not need to support multiple
- languages.
-
- WebDAV property names are qualified XML names (pairs of XML namespace
- name and local name). Although some applications (e.g., a generic
- property viewer) will display property names directly to their users,
- it is expected that the typical application will use a fixed set of
- properties, and will provide a mapping from the property name and
- namespace to a human-readable field when displaying the property name
-
-
-
-Dusseault Standards Track [Page 104]
-
-RFC 4918 WebDAV June 2007
-
-
- to a user. It is only in the case where the set of properties is not
- known ahead of time that an application need display a property name
- to a user. We recommend that applications provide human-readable
- property names wherever feasible.
-
- For error reporting, we follow the convention of HTTP/1.1 status
- codes, including with each status code a short, English description
- of the code (e.g., 423 (Locked)). While the possibility exists that
- a poorly crafted user agent would display this message to a user,
- internationalized applications will ignore this message, and display
- an appropriate message in the user's language and character set.
-
- Since interoperation of clients and servers does not require locale
- information, this specification does not specify any mechanism for
- transmission of this information.
-
-20. Security Considerations
-
- This section is provided to detail issues concerning security
- implications of which WebDAV applications need to be aware.
-
- All of the security considerations of HTTP/1.1 (discussed in
- [RFC2616]) and XML (discussed in [RFC3023]) also apply to WebDAV. In
- addition, the security risks inherent in remote authoring require
- stronger authentication technology, introduce several new privacy
- concerns, and may increase the hazards from poor server design.
- These issues are detailed below.
-
-20.1. Authentication of Clients
-
- Due to their emphasis on authoring, WebDAV servers need to use
- authentication technology to protect not just access to a network
- resource, but the integrity of the resource as well. Furthermore,
- the introduction of locking functionality requires support for
- authentication.
-
- A password sent in the clear over an insecure channel is an
- inadequate means for protecting the accessibility and integrity of a
- resource as the password may be intercepted. Since Basic
- authentication for HTTP/1.1 performs essentially clear text
- transmission of a password, Basic authentication MUST NOT be used to
- authenticate a WebDAV client to a server unless the connection is
- secure. Furthermore, a WebDAV server MUST NOT send a Basic
- authentication challenge in a WWW-Authenticate header unless the
- connection is secure. An example of a secure connection would be a
- Transport Layer Security (TLS) connection employing a strong cipher
- suite and server authentication.
-
-
-
-
-Dusseault Standards Track [Page 105]
-
-RFC 4918 WebDAV June 2007
-
-
- WebDAV applications MUST support the Digest authentication scheme
- [RFC2617]. Since Digest authentication verifies that both parties to
- a communication know a shared secret, a password, without having to
- send that secret in the clear, Digest authentication avoids the
- security problems inherent in Basic authentication while providing a
- level of authentication that is useful in a wide range of scenarios.
-
-20.2. Denial of Service
-
- Denial-of-service attacks are of special concern to WebDAV servers.
- WebDAV plus HTTP enables denial-of-service attacks on every part of a
- system's resources.
-
- o The underlying storage can be attacked by PUTting extremely large
- files.
-
- o Asking for recursive operations on large collections can attack
- processing time.
-
- o Making multiple pipelined requests on multiple connections can
- attack network connections.
-
- WebDAV servers need to be aware of the possibility of a denial-of-
- service attack at all levels. The proper response to such an attack
- MAY be to simply drop the connection. Or, if the server is able to
- make a response, the server MAY use a 400-level status request such
- as 400 (Bad Request) and indicate why the request was refused (a 500-
- level status response would indicate that the problem is with the
- server, whereas unintentional DoS attacks are something the client is
- capable of remedying).
-
-20.3. Security through Obscurity
-
- WebDAV provides, through the PROPFIND method, a mechanism for listing
- the member resources of a collection. This greatly diminishes the
- effectiveness of security or privacy techniques that rely only on the
- difficulty of discovering the names of network resources. Users of
- WebDAV servers are encouraged to use access control techniques to
- prevent unwanted access to resources, rather than depending on the
- relative obscurity of their resource names.
-
-20.4. Privacy Issues Connected to Locks
-
- When submitting a lock request, a user agent may also submit an
- 'owner' XML field giving contact information for the person taking
- out the lock (for those cases where a person, rather than a robot, is
- taking out the lock). This contact information is stored in a DAV:
- lockdiscovery property on the resource, and can be used by other
-
-
-
-Dusseault Standards Track [Page 106]
-
-RFC 4918 WebDAV June 2007
-
-
- collaborators to begin negotiation over access to the resource.
- However, in many cases, this contact information can be very private,
- and should not be widely disseminated. Servers SHOULD limit read
- access to the DAV:lockdiscovery property as appropriate.
- Furthermore, user agents SHOULD provide control over whether contact
- information is sent at all, and if contact information is sent,
- control over exactly what information is sent.
-
-20.5. Privacy Issues Connected to Properties
-
- Since property values are typically used to hold information such as
- the author of a document, there is the possibility that privacy
- concerns could arise stemming from widespread access to a resource's
- property data. To reduce the risk of inadvertent release of private
- information via properties, servers are encouraged to develop access
- control mechanisms that separate read access to the resource body and
- read access to the resource's properties. This allows a user to
- control the dissemination of their property data without overly
- restricting access to the resource's contents.
-
-20.6. Implications of XML Entities
-
- XML supports a facility known as "external entities", defined in
- Section 4.2.2 of [REC-XML], which instructs an XML processor to
- retrieve and include additional XML. An external XML entity can be
- used to append or modify the document type declaration (DTD)
- associated with an XML document. An external XML entity can also be
- used to include XML within the content of an XML document. For non-
- validating XML, such as the XML used in this specification, including
- an external XML entity is not required by XML. However, XML does
- state that an XML processor may, at its discretion, include the
- external XML entity.
-
- External XML entities have no inherent trustworthiness and are
- subject to all the attacks that are endemic to any HTTP GET request.
- Furthermore, it is possible for an external XML entity to modify the
- DTD, and hence affect the final form of an XML document, in the worst
- case, significantly modifying its semantics or exposing the XML
- processor to the security risks discussed in [RFC3023]. Therefore,
- implementers must be aware that external XML entities should be
- treated as untrustworthy. If a server chooses not to handle external
- XML entities, it SHOULD respond to requests containing external
- entities with the 'no-external-entities' condition code.
-
- There is also the scalability risk that would accompany a widely
- deployed application that made use of external XML entities. In this
- situation, it is possible that there would be significant numbers of
- requests for one external XML entity, potentially overloading any
-
-
-
-Dusseault Standards Track [Page 107]
-
-RFC 4918 WebDAV June 2007
-
-
- server that fields requests for the resource containing the external
- XML entity.
-
- Furthermore, there's also a risk based on the evaluation of "internal
- entities" as defined in Section 4.2.2 of [REC-XML]. A small,
- carefully crafted request using nested internal entities may require
- enormous amounts of memory and/or processing time to process. Server
- implementers should be aware of this risk and configure their XML
- parsers so that requests like these can be detected and rejected as
- early as possible.
-
-20.7. Risks Connected with Lock Tokens
-
- This specification encourages the use of "A Universally Unique
- Identifier (UUID) URN Namespace" ([RFC4122]) for lock tokens
- (Section 6.5), in order to guarantee their uniqueness across space
- and time. Version 1 UUIDs (defined in Section 4) MAY contain a
- "node" field that "consists of an IEEE 802 MAC address, usually the
- host address. For systems with multiple IEEE addresses, any
- available one can be used". Since a WebDAV server will issue many
- locks over its lifetime, the implication is that it may also be
- publicly exposing its IEEE 802 address.
-
- There are several risks associated with exposure of IEEE 802
- addresses. Using the IEEE 802 address:
-
- o It is possible to track the movement of hardware from subnet to
- subnet.
-
- o It may be possible to identify the manufacturer of the hardware
- running a WebDAV server.
-
- o It may be possible to determine the number of each type of
- computer running WebDAV.
-
- This risk only applies to host-address-based UUID versions. Section
- 4 of [RFC4122] describes several other mechanisms for generating
- UUIDs that do not involve the host address and therefore do not
- suffer from this risk.
-
-20.8. Hosting Malicious Content
-
- HTTP has the ability to host programs that are executed on client
- machines. These programs can take many forms including Web scripts,
- executables, plug-in modules, and macros in documents. WebDAV does
- not change any of the security concerns around these programs, yet
- often WebDAV is used in contexts where a wide range of users can
- publish documents on a server. The server might not have a close
-
-
-
-Dusseault Standards Track [Page 108]
-
-RFC 4918 WebDAV June 2007
-
-
- trust relationship with the author that is publishing the document.
- Servers that allow clients to publish arbitrary content can usefully
- implement precautions to check that content published to the server
- is not harmful to other clients. Servers could do this by techniques
- such as restricting the types of content that is allowed to be
- published and running virus and malware detection software on
- published content. Servers can also mitigate the risk by having
- appropriate access restriction and authentication of users that are
- allowed to publish content to the server.
-
-21. IANA Considerations
-
-21.1. New URI Schemes
-
- This specification defines two URI schemes:
-
- 1. the "opaquelocktoken" scheme defined in Appendix C, and
-
- 2. the "DAV" URI scheme, which historically was used in [RFC2518] to
- disambiguate WebDAV property and XML element names and which
- continues to be used for that purpose in this specification and
- others extending WebDAV. Creation of identifiers in the "DAV:"
- namespace is controlled by the IETF.
-
- Note that defining new URI schemes for XML namespaces is now
- discouraged. "DAV:" was defined before standard best practices
- emerged.
-
-21.2. XML Namespaces
-
- XML namespaces disambiguate WebDAV property names and XML elements.
- Any WebDAV user or application can define a new namespace in order to
- create custom properties or extend WebDAV XML syntax. IANA does not
- need to manage such namespaces, property names, or element names.
-
-21.3. Message Header Fields
-
- The message header fields below should be added to the permanent
- registry (see [RFC3864]).
-
-21.3.1. DAV
-
- Header field name: DAV
-
- Applicable protocol: http
-
- Status: standard
-
-
-
-
-Dusseault Standards Track [Page 109]
-
-RFC 4918 WebDAV June 2007
-
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.1)
-
-21.3.2. Depth
-
- Header field name: Depth
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.2)
-
-21.3.3. Destination
-
- Header field name: Destination
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.3)
-
-21.3.4. If
-
- Header field name: If
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.4)
-
-21.3.5. Lock-Token
-
- Header field name: Lock-Token
-
- Applicable protocol: http
-
- Status: standard
-
-
-
-
-Dusseault Standards Track [Page 110]
-
-RFC 4918 WebDAV June 2007
-
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.5)
-
-21.3.6. Overwrite
-
- Header field name: Overwrite
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.6)
-
-21.3.7. Timeout
-
- Header field name: Timeout
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document: this specification (Section 10.7)
-
-21.4. HTTP Status Codes
-
- This specification defines the HTTP status codes
-
- o 207 Multi-Status (Section 11.1)
-
- o 422 Unprocessable Entity (Section 11.2),
-
- o 423 Locked (Section 11.3),
-
- o 424 Failed Dependency (Section 11.4) and
-
- o 507 Insufficient Storage (Section 11.5),
-
- to be updated in the registry at
- .
-
- Note: the HTTP status code 102 (Processing) has been removed in this
- specification; its IANA registration should continue to reference RFC
- 2518.
-
-
-
-Dusseault Standards Track [Page 111]
-
-RFC 4918 WebDAV June 2007
-
-
-22. Acknowledgements
-
- A specification such as this thrives on piercing critical review and
- withers from apathetic neglect. The authors gratefully acknowledge
- the contributions of the following people, whose insights were so
- valuable at every stage of our work.
-
- Contributors to RFC 2518
-
- Terry Allen, Harald Alvestrand, Jim Amsden, Becky Anderson, Alan
- Babich, Sanford Barr, Dylan Barrell, Bernard Chester, Tim Berners-
- Lee, Dan Connolly, Jim Cunningham, Ron Daniel, Jr., Jim Davis, Keith
- Dawson, Mark Day, Brian Deen, Martin Duerst, David Durand, Lee
- Farrell, Chuck Fay, Wesley Felter, Roy Fielding, Mark Fisher, Alan
- Freier, George Florentine, Jim Gettys, Phill Hallam-Baker, Dennis
- Hamilton, Steve Henning, Mead Himelstein, Alex Hopmann, Andre van der
- Hoek, Ben Laurie, Paul Leach, Ora Lassila, Karen MacArthur, Steven
- Martin, Larry Masinter, Michael Mealling, Keith Moore, Thomas Narten,
- Henrik Nielsen, Kenji Ota, Bob Parker, Glenn Peterson, Jon Radoff,
- Saveen Reddy, Henry Sanders, Christopher Seiwald, Judith Slein, Mike
- Spreitzer, Einar Stefferud, Greg Stein, Ralph Swick, Kenji Takahashi,
- Richard N. Taylor, Robert Thau, John Turner, Sankar Virdhagriswaran,
- Fabio Vitali, Gregory Woodhouse, and Lauren Wood.
-
- Two from this list deserve special mention. The contributions by
- Larry Masinter have been invaluable; he both helped the formation of
- the working group and patiently coached the authors along the way.
- In so many ways he has set high standards that we have toiled to
- meet. The contributions of Judith Slein were also invaluable; by
- clarifying the requirements and in patiently reviewing version after
- version, she both improved this specification and expanded our minds
- on document management.
-
- We would also like to thank John Turner for developing the XML DTD.
-
- The authors of RFC 2518 were Yaron Goland, Jim Whitehead, A. Faizi,
- Steve Carter, and D. Jensen. Although their names had to be removed
- due to IETF author count restrictions, they can take credit for the
- majority of the design of WebDAV.
-
- Additional Acknowledgements for This Specification
-
- Significant contributors of text for this specification are listed as
- contributors in the section below. We must also gratefully
- acknowledge Geoff Clemm, Joel Soderberg, and Dan Brotsky for hashing
- out specific text on the list or in meetings. Joe Hildebrand and
- Cullen Jennings helped close many issues. Barry Lind described an
- additional security consideration and Cullen Jennings provided text
-
-
-
-Dusseault Standards Track [Page 112]
-
-RFC 4918 WebDAV June 2007
-
-
- for that consideration. Jason Crawford tracked issue status for this
- document for a period of years, followed by Elias Sinderson.
-
-23. Contributors to This Specification
-
- Julian Reschke
- bytes GmbH
- Hafenweg 16, 48155 Muenster, Germany
- EMail: julian.reschke@greenbytes.de
-
-
- Elias Sinderson
- University of California, Santa Cruz
- 1156 High Street, Santa Cruz, CA 95064
- EMail: elias@cse.ucsc.edu
-
-
- Jim Whitehead
- University of California, Santa Cruz
- 1156 High Street, Santa Cruz, CA 95064
- EMail: ejw@soe.ucsc.edu
-
-24. Authors of RFC 2518
-
- Y. Y. Goland
- Microsoft Corporation
- One Microsoft Way
- Redmond, WA 98052-6399
- EMail: yarong@microsoft.com
-
-
- E. J. Whitehead, Jr.
- Dept. Of Information and Computer Science
- University of California, Irvine
- Irvine, CA 92697-3425
- EMail: ejw@ics.uci.edu
-
-
- A. Faizi
- Netscape
- 685 East Middlefield Road
- Mountain View, CA 94043
- EMail: asad@netscape.com
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 113]
-
-RFC 4918 WebDAV June 2007
-
-
- S. R. Carter
- Novell
- 1555 N. Technology Way
- M/S ORM F111
- Orem, UT 84097-2399
- EMail: srcarter@novell.com
-
-
- D. Jensen
- Novell
- 1555 N. Technology Way
- M/S ORM F111
- Orem, UT 84097-2399
- EMail: dcjensen@novell.com
-
-25. References
-
-25.1. Normative References
-
- [REC-XML] Bray, T., Paoli, J., Sperberg-McQueen, C., Maler,
- E., and F. Yergeau, "Extensible Markup Language
- (XML) 1.0 (Fourth Edition)", W3C REC-xml-20060816,
- August 2006,
- .
-
- [REC-XML-INFOSET] Cowan, J. and R. Tobin, "XML Information Set
- (Second Edition)", W3C REC-xml-infoset-20040204,
- February 2004, .
-
- [REC-XML-NAMES] Bray, T., Hollander, D., Layman, A., and R. Tobin,
- "Namespaces in XML 1.0 (Second Edition)", W3C REC-
- xml-names-20060816, August 2006, .
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to
- Indicate Requirement Levels", BCP 14, RFC 2119,
- March 1997.
-
- [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and
- Languages", BCP 18, RFC 2277, January 1998.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P., and T. Berners-Lee,
- "Hypertext Transfer Protocol -- HTTP/1.1",
- RFC 2616, June 1999.
-
-
-
-
-
-Dusseault Standards Track [Page 114]
-
-RFC 4918 WebDAV June 2007
-
-
- [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.
-
- [RFC3339] Klyne, G., Ed. and C. Newman, "Date and Time on
- the Internet: Timestamps", RFC 3339, July 2002.
-
- [RFC3629] Yergeau, F., "UTF-8, a transformation format of
- ISO 10646", STD 63, RFC 3629, November 2003.
-
- [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter,
- "Uniform Resource Identifier (URI): Generic
- Syntax", STD 66, RFC 3986, January 2005.
-
- [RFC4122] Leach, P., Mealling, M., and R. Salz, "A
- Universally Unique IDentifier (UUID) URN
- Namespace", RFC 4122, July 2005.
-
-25.2. Informative References
-
- [RFC2291] Slein, J., Vitali, F., Whitehead, E., and D.
- Durand, "Requirements for a Distributed Authoring
- and Versioning Protocol for the World Wide Web",
- RFC 2291, February 1998.
-
- [RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, S.,
- and D. Jensen, "HTTP Extensions for Distributed
- Authoring -- WEBDAV", RFC 2518, February 1999.
-
- [RFC2781] Hoffman, P. and F. Yergeau, "UTF-16, an encoding
- of ISO 10646", RFC 2781, February 2000.
-
- [RFC3023] Murata, M., St. Laurent, S., and D. Kohn, "XML
- Media Types", RFC 3023, January 2001.
-
- [RFC3253] Clemm, G., Amsden, J., Ellison, T., Kaler, C., and
- J. Whitehead, "Versioning Extensions to WebDAV
- (Web Distributed Authoring and Versioning)",
- RFC 3253, March 2002.
-
- [RFC3648] Whitehead, J. and J. Reschke, Ed., "Web
- Distributed Authoring and Versioning (WebDAV)
- Ordered Collections Protocol", RFC 3648,
- December 2003.
-
-
-
-
-
-
-Dusseault Standards Track [Page 115]
-
-RFC 4918 WebDAV June 2007
-
-
- [RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J.
- Whitehead, "Web Distributed Authoring and
- Versioning (WebDAV) Access Control Protocol",
- RFC 3744, May 2004.
-
- [RFC3864] Klyne, G., Nottingham, M., and J. Mogul,
- "Registration Procedures for Message Header
- Fields", BCP 90, RFC 3864, September 2004.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 116]
-
-RFC 4918 WebDAV June 2007
-
-
-Appendix A. Notes on Processing XML Elements
-
-A.1. Notes on Empty XML Elements
-
- XML supports two mechanisms for indicating that an XML element does
- not have any content. The first is to declare an XML element of the
- form . The second is to declare an XML element of the form
- . The two XML elements are semantically identical.
-
-A.2. Notes on Illegal XML Processing
-
- XML is a flexible data format that makes it easy to submit data that
- appears legal but in fact is not. The philosophy of "Be flexible in
- what you accept and strict in what you send" still applies, but it
- must not be applied inappropriately. XML is extremely flexible in
- dealing with issues of whitespace, element ordering, inserting new
- elements, etc. This flexibility does not require extension,
- especially not in the area of the meaning of elements.
-
- There is no kindness in accepting illegal combinations of XML
- elements. At best, it will cause an unwanted result and at worst it
- can cause real damage.
-
-A.3. Example - XML Syntax Error
-
- The following request body for a PROPFIND method is illegal.
-
-
-
-
-
-
-
- The definition of the propfind element only allows for the allprop or
- the propname element, not both. Thus, the above is an error and must
- be responded to with a 400 (Bad Request).
-
- Imagine, however, that a server wanted to be "kind" and decided to
- pick the allprop element as the true element and respond to it. A
- client running over a bandwidth limited line who intended to execute
- a propname would be in for a big surprise if the server treated the
- command as an allprop.
-
- Additionally, if a server were lenient and decided to reply to this
- request, the results would vary randomly from server to server, with
- some servers executing the allprop directive, and others executing
- the propname directive. This reduces interoperability rather than
- increasing it.
-
-
-
-Dusseault Standards Track [Page 117]
-
-RFC 4918 WebDAV June 2007
-
-
-A.4. Example - Unexpected XML Element
-
- The previous example was illegal because it contained two elements
- that were explicitly banned from appearing together in the propfind
- element. However, XML is an extensible language, so one can imagine
- new elements being defined for use with propfind. Below is the
- request body of a PROPFIND and, like the previous example, must be
- rejected with a 400 (Bad Request) by a server that does not
- understand the expired-props element.
-
-
-
-
-
-
- To understand why a 400 (Bad Request) is returned, let us look at the
- request body as the server unfamiliar with expired-props sees it.
-
-
-
-
-
- As the server does not understand the 'expired-props' element,
- according to the WebDAV-specific XML processing rules specified in
- Section 17, it must process the request as if the element were not
- there. Thus, the server sees an empty propfind, which by the
- definition of the propfind element is illegal.
-
- Please note that had the extension been additive, it would not
- necessarily have resulted in a 400 (Bad Request). For example,
- imagine the following request body for a PROPFIND:
-
-
-
-
-
- *boss*
-
-
- The previous example contains the fictitious element leave-out. Its
- purpose is to prevent the return of any property whose name matches
- the submitted pattern. If the previous example were submitted to a
- server unfamiliar with 'leave-out', the only result would be that the
- 'leave-out' element would be ignored and a propname would be
- executed.
-
-
-
-Dusseault Standards Track [Page 118]
-
-RFC 4918 WebDAV June 2007
-
-
-Appendix B. Notes on HTTP Client Compatibility
-
- WebDAV was designed to be, and has been found to be, backward-
- compatible with HTTP 1.1. The PUT and DELETE methods are defined in
- HTTP and thus may be used by HTTP clients as well as WebDAV-aware
- clients, but the responses to PUT and DELETE have been extended in
- this specification in ways that only a WebDAV client would be
- entirely prepared for. Some theoretical concerns were raised about
- whether those responses would cause interoperability problems with
- HTTP-only clients, and this section addresses those concerns.
-
- Since any HTTP client ought to handle unrecognized 400-level and 500-
- level status codes as errors, the following new status codes should
- not present any issues: 422, 423, and 507 (424 is also a new status
- code but it appears only in the body of a Multistatus response.) So,
- for example, if an HTTP client attempted to PUT or DELETE a locked
- resource, the 423 Locked response ought to result in a generic error
- presented to the user.
-
- The 207 Multistatus response is interesting because an HTTP client
- issuing a DELETE request to a collection might interpret a 207
- response as a success, even though it does not realize the resource
- is a collection and cannot understand that the DELETE operation might
- have been a complete or partial failure. That interpretation isn't
- entirely justified, because a 200-level response indicates that the
- server "received, understood, and accepted" the request, not that the
- request resulted in complete success.
-
- One option is that a server could treat a DELETE of a collection as
- an atomic operation, and use either 204 No Content in case of
- success, or some appropriate error response (400 or 500 level) for an
- error. This approach would indeed maximize backward compatibility.
- However, since interoperability tests and working group discussions
- have not turned up any instances of HTTP clients issuing a DELETE
- request against a WebDAV collection, this concern is more theoretical
- than practical. Thus, servers are likely to be completely successful
- at interoperating with HTTP clients even if they treat any collection
- DELETE request as a WebDAV request and send a 207 Multi-Status
- response.
-
- In general, server implementations are encouraged to use the detailed
- responses and other mechanisms defined in this document rather than
- make changes for theoretical interoperability concerns.
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 119]
-
-RFC 4918 WebDAV June 2007
-
-
-Appendix C. The 'opaquelocktoken' Scheme and URIs
-
- The 'opaquelocktoken' URI scheme was defined in [RFC2518] (and
- registered by IANA) in order to create syntactically correct and
- easy-to-generate URIs out of UUIDs, intended to be used as lock
- tokens and to be unique across all resources for all time.
-
- An opaquelocktoken URI is constructed by concatenating the
- 'opaquelocktoken' scheme with a UUID, along with an optional
- extension. Servers can create new UUIDs for each new lock token. If
- a server wishes to reuse UUIDs, the server MUST add an extension, and
- the algorithm generating the extension MUST guarantee that the same
- extension will never be used twice with the associated UUID.
-
- OpaqueLockToken-URI = "opaquelocktoken:" UUID [Extension]
- ; UUID is defined in Section 3 of [RFC4122]. Note that LWS
- ; is not allowed between elements of
- ; this production.
-
- Extension = path
- ; path is defined in Section 3.3 of [RFC3986]
-
-
-Appendix D. Lock-null Resources
-
- The original WebDAV model for locking unmapped URLs created "lock-
- null resources". This model was over-complicated and some
- interoperability and implementation problems were discovered. The
- new WebDAV model for locking unmapped URLs (see Section 7.3) creates
- "locked empty resources". Lock-null resources are deprecated. This
- section discusses the original model briefly because clients MUST be
- able to handle either model.
-
- In the original "lock-null resource" model, which is no longer
- recommended for implementation:
-
- o A lock-null resource sometimes appeared as "Not Found". The
- server responds with a 404 or 405 to any method except for PUT,
- MKCOL, OPTIONS, PROPFIND, LOCK, UNLOCK.
-
- o A lock-null resource does however show up as a member of its
- parent collection.
-
- o The server removes the lock-null resource entirely (its URI
- becomes unmapped) if its lock goes away before it is converted to
- a regular resource. Recall that locks go away not only when they
- expire or are unlocked, but are also removed if a resource is
- renamed or moved, or if any parent collection is renamed or moved.
-
-
-
-Dusseault Standards Track [Page 120]
-
-RFC 4918 WebDAV June 2007
-
-
- o The server converts the lock-null resource into a regular resource
- if a PUT request to the URL is successful.
-
- o The server converts the lock-null resource into a collection if a
- MKCOL request to the URL is successful (though interoperability
- experience showed that not all servers followed this requirement).
-
- o Property values were defined for DAV:lockdiscovery and DAV:
- supportedlock properties but not necessarily for other properties
- like DAV:getcontenttype.
-
- Clients can easily interoperate both with servers that support the
- old model "lock-null resources" and the recommended model of "locked
- empty resources" by only attempting PUT after a LOCK to an unmapped
- URL, not MKCOL or GET.
-
-D.1. Guidance for Clients Using LOCK to Create Resources
-
- A WebDAV client implemented to this specification might find servers
- that create lock-null resources (implemented before this
- specification using [RFC2518]) as well as servers that create locked
- empty resources. The response to the LOCK request will not indicate
- what kind of resource was created. There are a few techniques that
- help the client deal with either type.
-
- If the client wishes to avoid accidentally creating either lock-
- null or empty locked resources, an "If-Match: *" header can be
- included with LOCK requests to prevent the server from creating a
- new resource.
-
- If a LOCK request creates a resource and the client subsequently
- wants to overwrite that resource using a COPY or MOVE request, the
- client should include an "Overwrite: T" header.
-
- If a LOCK request creates a resource and the client then decides
- to get rid of that resource, a DELETE request is supposed to fail
- on a lock-null resource and UNLOCK should be used instead. But
- with a locked empty resource, UNLOCK doesn't make the resource
- disappear. Therefore, the client might have to try both requests
- and ignore an error in one of the two requests.
-
-Appendix E. Guidance for Clients Desiring to Authenticate
-
- Many WebDAV clients that have already been implemented have account
- settings (similar to the way email clients store IMAP account
- settings). Thus, the WebDAV client would be able to authenticate
- with its first couple requests to the server, provided it had a way
- to get the authentication challenge from the server with realm name,
-
-
-
-Dusseault Standards Track [Page 121]
-
-RFC 4918 WebDAV June 2007
-
-
- nonce, and other challenge information. Note that the results of
- some requests might vary according to whether or not the client is
- authenticated -- a PROPFIND might return more visible resources if
- the client is authenticated, yet not fail if the client is anonymous.
-
- There are a number of ways the client might be able to trigger the
- server to provide an authentication challenge. This appendix
- describes a couple approaches that seem particularly likely to work.
-
- The first approach is to perform a request that ought to require
- authentication. However, it's possible that a server might handle
- any request even without authentication, so to be entirely safe, the
- client could add a conditional header to ensure that even if the
- request passes permissions checks, it's not actually handled by the
- server. An example of following this approach would be to use a PUT
- request with an "If-Match" header with a made-up ETag value. This
- approach might fail to result in an authentication challenge if the
- server does not test authorization before testing conditionals as is
- required (see Section 8.5), or if the server does not need to test
- authorization.
-
- Example - forcing auth challenge with write request
-
- >>Request
-
- PUT /forceauth.txt HTTP/1.1
- Host: www.example.com
- If-Match: "xxx"
- Content-Type: text/plain
- Content-Length: 0
-
-
- The second approach is to use an Authorization header (defined in
- [RFC2617]), which is likely to be rejected by the server but which
- will then prompt a proper authentication challenge. For example, the
- client could start with a PROPFIND request containing an
- Authorization header containing a made-up Basic userid:password
- string or with actual plausible credentials. This approach relies on
- the server responding with a "401 Unauthorized" along with a
- challenge if it receives an Authorization header with an unrecognized
- username, invalid password, or if it doesn't even handle Basic
- authentication. This seems likely to work because of the
- requirements of RFC 2617:
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 122]
-
-RFC 4918 WebDAV June 2007
-
-
- "If the origin server does not wish to accept the credentials sent
- with a request, it SHOULD return a 401 (Unauthorized) response. The
- response MUST include a WWW-Authenticate header field containing at
- least one (possibly new) challenge applicable to the requested
- resource."
-
- There's a slight problem with implementing that recommendation in
- some cases, because some servers do not even have challenge
- information for certain resources. Thus, when there's no way to
- authenticate to a resource or the resource is entirely publicly
- available over all accepted methods, the server MAY ignore the
- Authorization header, and the client will presumably try again later.
-
- Example - forcing auth challenge with Authorization header
-
- >>Request
-
- PROPFIND /docs/ HTTP/1.1
- Host: www.example.com
- Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- Content-type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
- [body omitted]
-
-
-Appendix F. Summary of Changes from RFC 2518
-
- This section lists major changes between this document and RFC 2518,
- starting with those that are likely to result in implementation
- changes. Servers will advertise support for all changes in this
- specification by returning the compliance class "3" in the DAV
- response header (see Sections 10.1 and 18.3).
-
-F.1. Changes for Both Client and Server Implementations
-
- Collections and Namespace Operations
-
- o The semantics of PROPFIND 'allprop' (Section 9.1) have been
- relaxed so that servers return results including, at a minimum,
- the live properties defined in this specification, but not
- necessarily return other live properties. The 'allprop' directive
- therefore means something more like "return all properties that
- are supposed to be returned when 'allprop' is requested" -- a set
- of properties that may include custom properties and properties
- defined in other specifications if those other specifications so
- require. Related to this, 'allprop' requests can now be extended
- with the 'include' syntax to include specific named properties,
-
-
-
-Dusseault Standards Track [Page 123]
-
-RFC 4918 WebDAV June 2007
-
-
- thereby avoiding additional requests due to changed 'allprop'
- semantics.
-
- o Servers are now allowed to reject PROPFIND requests with Depth:
- Infinity. Clients that used this will need to be able to do a
- series of Depth:1 requests instead.
-
- o Multi-Status response bodies now can transport the value of HTTP's
- Location response header in the new 'location' element. Clients
- may use this to avoid additional roundtrips to the server when
- there is a 'response' element with a 3xx status (see
- Section 14.24).
-
- o The definition of COPY has been relaxed so that it doesn't require
- servers to first delete the target resources anymore (this was a
- known incompatibility with [RFC3253]). See Section 9.8.
-
- Headers and Marshalling
-
- o The Destination and If request headers now allow absolute paths in
- addition to full URIs (see Section 8.3). This may be useful for
- clients operating through a reverse proxy that does rewrite the
- Host request header, but not WebDAV-specific headers.
-
- o This specification adopts the error marshalling extensions and the
- "precondition/postcondition" terminology defined in [RFC3253] (see
- Section 16). Related to that, it adds the "error" XML element
- inside multistatus response bodies (see Section 14.5, however note
- that it uses a format different from the one recommended in RFC
- 3253).
-
- o Senders and recipients are now required to support the UTF-16
- character encoding in XML message bodies (see Section 19).
-
- o Clients are now required to send the Depth header on PROPFIND
- requests, although servers are still encouraged to support clients
- that don't.
-
- Locking
-
- o RFC 2518's concept of "lock-null resources" (LNRs) has been
- replaced by a simplified approach, the "locked empty resources"
- (see Section 7.3). There are some aspects of lock-null resources
- clients cannot rely on anymore, namely, the ability to use them to
- create a locked collection or the fact that they disappear upon
- UNLOCK when no PUT or MKCOL request was issued. Note that servers
- are still allowed to implement LNRs as per RFC 2518.
-
-
-
-
-Dusseault Standards Track [Page 124]
-
-RFC 4918 WebDAV June 2007
-
-
- o There is no implicit refresh of locks anymore. Locks are only
- refreshed upon explicit request (see Section 9.10.2).
-
- o Clarified that the DAV:owner value supplied in the LOCK request
- must be preserved by the server just like a dead property
- (Section 14.17). Also added the DAV:lockroot element
- (Section 14.12), which allows clients to discover the root of
- lock.
-
-F.2. Changes for Server Implementations
-
- Collections and Namespace Operations
-
- o Due to interoperability problems, allowable formats for contents
- of 'href' elements in multistatus responses have been limited (see
- Section 8.3).
-
- o Due to lack of implementation, support for the 'propertybehavior'
- request body for COPY and MOVE has been removed. Instead,
- requirements for property preservation have been clarified (see
- Sections 9.8 and 9.9).
-
- Properties
-
- o Strengthened server requirements for storage of property values,
- in particular persistence of language information (xml:lang),
- whitespace, and XML namespace information (see Section 4.3).
-
- o Clarified requirements on which properties should be writable by
- the client; in particular, setting "DAV:displayname" should be
- supported by servers (see Section 15).
-
- o Only 'rfc1123-date' productions are legal as values for DAV:
- getlastmodified (see Section 15.7).
-
- Headers and Marshalling
-
- o Servers are now required to do authorization checks before
- processing conditional headers (see Section 8.5).
-
- Locking
-
- o Strengthened requirement to check identity of lock creator when
- accessing locked resources (see Section 6.4). Clients should be
- aware that lock tokens returned to other principals can only be
- used to break a lock, if at all.
-
-
-
-
-
-Dusseault Standards Track [Page 125]
-
-RFC 4918 WebDAV June 2007
-
-
- o Section 8.10.4 of [RFC2518] incorrectly required servers to return
- a 409 status where a 207 status was really appropriate. This has
- been corrected (Section 9.10).
-
-F.3. Other Changes
-
- The definition of collection state has been fixed so it doesn't vary
- anymore depending on the Request-URI (see Section 5.2).
-
- The DAV:source property introduced in Section 4.6 of [RFC2518] was
- removed due to lack of implementation experience.
-
- The DAV header now allows non-IETF extensions through URIs in
- addition to compliance class tokens. It also can now be used in
- requests, although this specification does not define any associated
- semantics for the compliance classes defined in here (see
- Section 10.1).
-
- In RFC 2518, the definition of the Depth header (Section 9.2)
- required that, by default, request headers would be applied to each
- resource in scope. Based on implementation experience, the default
- has now been reversed (see Section 10.2).
-
- The definitions of HTTP status code 102 ([RFC2518], Section 10.1) and
- the Status-URI response header (Section 9.7) have been removed due to
- lack of implementation.
-
- The TimeType format used in the Timeout request header and the
- "timeout" XML element used to be extensible. Now, only the two
- formats defined by this specification are allowed (see Section 10.7).
-
-Author's Address
-
- Lisa Dusseault (editor)
- CommerceNet
- 2064 Edgewood Dr.
- Palo Alto, CA 94303
- US
-
- EMail: ldusseault@commerce.net
-
-
-
-
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 126]
-
-RFC 4918 WebDAV June 2007
-
-
-Full Copyright Statement
-
- Copyright (C) The IETF Trust (2007).
-
- This document is subject to the rights, licenses and restrictions
- contained in BCP 78, and except as set forth therein, the authors
- retain all their rights.
-
- This document and the information contained herein are provided on an
- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
- THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
- THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- Intellectual Property Rights or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; nor does it represent that it has
- made any independent effort to identify any such rights. Information
- on the procedures with respect to rights in RFC documents can be
- found in BCP 78 and BCP 79.
-
- Copies of IPR disclosures made to the IETF Secretariat and any
- assurances of licenses to be made available, or the result of an
- attempt made to obtain a general license or permission for the use of
- such proprietary rights by implementers or users of this
- specification can be obtained from the IETF on-line IPR repository at
- http://www.ietf.org/ipr.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights that may cover technology that may be required to implement
- this standard. Please address the information to the IETF at
- ietf-ipr@ietf.org.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-Dusseault Standards Track [Page 127]
-
diff --git a/doc/rfc5397-webdav-current-principal-extension.txt b/doc/rfc5397-webdav-current-principal-extension.txt
deleted file mode 100644
index 616055e7..00000000
--- a/doc/rfc5397-webdav-current-principal-extension.txt
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
-Network Working Group W. Sanchez
-Request for Comments: 5397 C. Daboo
-Category: Standards Track Apple Inc.
- December 2008
-
-
- WebDAV Current Principal Extension
-
-Status of This Memo
-
- This document specifies an Internet standards track protocol for the
- Internet community, and requests discussion and suggestions for
- improvements. Please refer to the current edition of the "Internet
- Official Protocol Standards" (STD 1) for the standardization state
- and status of this protocol. Distribution of this memo is unlimited.
-
-Copyright Notice
-
- Copyright (c) 2008 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.
-
-Abstract
-
- This specification defines a new WebDAV property that allows clients
- to quickly determine the principal corresponding to the current
- authenticated user.
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
- 2. Conventions Used in This Document . . . . . . . . . . . . . . . 2
- 3. DAV:current-user-principal . . . . . . . . . . . . . . . . . . 3
- 4. Security Considerations . . . . . . . . . . . . . . . . . . . . 4
- 5. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 4
- 6. Normative References . . . . . . . . . . . . . . . . . . . . . 4
-
-
-
-
-
-
-
-
-
-Sanchez & Daboo Standards Track [Page 1]
-
-RFC 5397 WebDAV Current Principal December 2008
-
-
-1. Introduction
-
- WebDAV [RFC4918] is an extension to HTTP [RFC2616] to support
- improved document authoring capabilities. The WebDAV Access Control
- Protocol ("WebDAV ACL") [RFC3744] extension adds access control
- capabilities to WebDAV. It introduces the concept of a "principal"
- resource, which is used to represent information about authenticated
- entities on the system.
-
- Some clients have a need to determine which [RFC3744] principal a
- server is associating with the currently authenticated HTTP user.
- While [RFC3744] defines a DAV:current-user-privilege-set property for
- retrieving the privileges granted to that principal, there is no
- recommended way to identify the principal in question, which is
- necessary to perform other useful operations. For example, a client
- may wish to determine which groups the current user is a member of,
- or modify a property of the principal resource associated with the
- current user.
-
- The DAV:principal-match REPORT provides some useful functionality,
- but there are common situations where the results from that query can
- be ambiguous. For example, not only is an individual user principal
- returned, but also every group principal that the user is a member
- of, and there is no clear way to distinguish which is which.
-
- This specification proposes an extension to WebDAV ACL that adds a
- DAV:current-user-principal property to resources under access control
- on the server. This property provides a URL to a principal resource
- corresponding to the currently authenticated user. This allows a
- client to "bootstrap" itself by performing additional queries on the
- principal resource to obtain additional information from that
- resource, which is the purpose of this extension. Note that while it
- is possible for multiple URLs to refer to the same principal
- resource, or for multiple principal resources to correspond to a
- single principal, this specification only allows for a single http(s)
- URL in the DAV:current-user-principal property. If a client wishes
- to obtain alternate URLs for the principal, it can query the
- principal resource for this information; it is not the purpose of
- this extension to provide a complete list of such URLs, but simply to
- provide a means to locate a resource which contains that (and other)
- information.
-
-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].
-
-
-
-
-Sanchez & Daboo Standards Track [Page 2]
-
-RFC 5397 WebDAV Current Principal December 2008
-
-
- When XML element types in the namespace "DAV:" are referenced in this
- document outside of the context of an XML fragment, the string "DAV:"
- will be prefixed to the element type names.
-
- Processing of XML by clients and servers MUST follow the rules
- defined in Section 17 of WebDAV [RFC4918].
-
- Some of the declarations refer to XML elements defined by WebDAV
- [RFC4918].
-
-3. DAV:current-user-principal
-
- Name: current-user-principal
-
- Namespace: DAV:
-
- Purpose: Indicates a URL for the currently authenticated user's
- principal resource on the server.
-
- Value: A single DAV:href or DAV:unauthenticated element.
-
- Protected: This property is computed on a per-request basis, and
- therefore is protected.
-
- Description: The DAV:current-user-principal property contains either
- a DAV:href or DAV:unauthenticated XML element. The DAV:href
- element contains a URL to a principal resource corresponding to
- the currently authenticated user. That URL MUST be one of the
- URLs in the DAV:principal-URL or DAV:alternate-URI-set properties
- defined on the principal resource and MUST be an http(s) scheme
- URL. When authentication has not been done or has failed, this
- property MUST contain the DAV:unauthenticated pseudo-principal.
-
- In some cases, there may be multiple principal resources
- corresponding to the same authenticated principal. In that case,
- the server is free to choose any one of the principal resource
- URIs for the value of the DAV:current-user-principal property.
- However, servers SHOULD be consistent and use the same principal
- resource URI for each authenticated principal.
-
- COPY/MOVE behavior: This property is computed on a per-request
- basis, and is thus never copied or moved.
-
- Definition:
-
-
-
-
-
-
-
-Sanchez & Daboo Standards Track [Page 3]
-
-RFC 5397 WebDAV Current Principal December 2008
-
-
- Example:
-
-
- /principals/users/cdaboo
-
-
-4. Security Considerations
-
- This specification does not introduce any additional security issues
- beyond those defined for HTTP [RFC2616], WebDAV [RFC4918], and WebDAV
- ACL [RFC3744].
-
-5. Acknowledgments
-
- This specification is based on discussions 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 authors thank Julian Reschke for his valuable input via the
- WebDAV working group mailing list.
-
-6. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
- Transfer 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 Distributed
- Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
-
-Authors' Addresses
-
- Wilfredo Sanchez
- Apple Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: wsanchez@wsanchez.net
- URI: http://www.apple.com/
-
-
-
-
-Sanchez & Daboo Standards Track [Page 4]
-
-RFC 5397 WebDAV Current Principal December 2008
-
-
- Cyrus Daboo
- Apple Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Sanchez & Daboo Standards Track [Page 5]
-
-
diff --git a/doc/rfc5785-well-known-uris.txt b/doc/rfc5785-well-known-uris.txt
deleted file mode 100644
index c28ccf6b..00000000
--- a/doc/rfc5785-well-known-uris.txt
+++ /dev/null
@@ -1,451 +0,0 @@
-
-
-
-
-
-
-Internet Engineering Task Force (IETF) M. Nottingham
-Request for Comments: 5785 E. Hammer-Lahav
-Updates: 2616, 2818 April 2010
-Category: Standards Track
-ISSN: 2070-1721
-
-
- Defining Well-Known Uniform Resource Identifiers (URIs)
-
-Abstract
-
- This memo defines a path prefix for "well-known locations",
- "/.well-known/", in selected Uniform Resource Identifier (URI)
- schemes.
-
-Status of This Memo
-
- This is an Internet Standards Track document.
-
- This document is a product of the Internet Engineering Task Force
- (IETF). It represents the consensus of the IETF community. It has
- received public review and has been approved for publication by the
- Internet Engineering Steering Group (IESG). Further information on
- Internet Standards is available in Section 2 of RFC 5741.
-
- Information about the current status of this document, any errata,
- and how to provide feedback on it may be obtained at
- http://www.rfc-editor.org/info/rfc5785.
-
-Copyright Notice
-
- 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
- (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 Simplified BSD License.
-
-
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 1]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
- 1.1. Appropriate Use of Well-Known URIs . . . . . . . . . . . . 3
- 2. Notational Conventions . . . . . . . . . . . . . . . . . . . . 3
- 3. Well-Known URIs . . . . . . . . . . . . . . . . . . . . . . . . 3
- 4. Security Considerations . . . . . . . . . . . . . . . . . . . . 4
- 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 4
- 5.1. The Well-Known URI Registry . . . . . . . . . . . . . . . . 4
- 5.1.1. Registration Template . . . . . . . . . . . . . . . . . 5
- 6. References . . . . . . . . . . . . . . . . . . . . . . . . . . 5
- 6.1. Normative References . . . . . . . . . . . . . . . . . . . 5
- 6.2. Informative References . . . . . . . . . . . . . . . . . . 5
- Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . . 7
- Appendix B. Frequently Asked Questions . . . . . . . . . . . . . . 7
-
-1. Introduction
-
- It is increasingly common for Web-based protocols to require the
- discovery of policy or other information about a host ("site-wide
- metadata") before making a request. For example, the Robots
- Exclusion Protocol specifies a way for
- automated processes to obtain permission to access resources;
- likewise, the Platform for Privacy Preferences [W3C.REC-P3P-20020416]
- tells user-agents how to discover privacy policy beforehand.
-
- While there are several ways to access per-resource metadata (e.g.,
- HTTP headers, WebDAV's PROPFIND [RFC4918]), the perceived overhead
- (either in terms of client-perceived latency and/or deployment
- difficulties) associated with them often precludes their use in these
- scenarios.
-
- When this happens, it is common to designate a "well-known location"
- for such data, so that it can be easily located. However, this
- approach has the drawback of risking collisions, both with other such
- designated "well-known locations" and with pre-existing resources.
-
- To address this, this memo defines a path prefix in HTTP(S) URIs for
- these "well-known locations", "/.well-known/". Future specifications
- that need to define a resource for such site-wide metadata can
- register their use to avoid collisions and minimise impingement upon
- sites' URI space.
-
-
-
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 2]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
-1.1. Appropriate Use of Well-Known URIs
-
- There are a number of possible ways that applications could use Well-
- known URIs. However, in keeping with the Architecture of the World-
- Wide Web [W3C.REC-webarch-20041215], well-known URIs are not intended
- for general information retrieval or establishment of large URI
- namespaces on the Web. Rather, they are designed to facilitate
- discovery of information on a site when it isn't practical to use
- other mechanisms; for example, when discovering policy that needs to
- be evaluated before a resource is accessed, or when using multiple
- round-trips is judged detrimental to performance.
-
- As such, the well-known URI space was created with the expectation
- that it will be used to make site-wide policy information and other
- metadata available directly (if sufficiently concise), or provide
- references to other URIs that provide such metadata.
-
-2. Notational Conventions
-
- 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 RFC 2119 [RFC2119].
-
-3. Well-Known URIs
-
- A well-known URI is a URI [RFC3986] whose path component begins with
- the characters "/.well-known/", and whose scheme is "HTTP", "HTTPS",
- or another scheme that has explicitly been specified to use well-
- known URIs.
-
- Applications that wish to mint new well-known URIs MUST register
- them, following the procedures in Section 5.1.
-
- For example, if an application registers the name 'example', the
- corresponding well-known URI on 'http://www.example.com/' would be
- 'http://www.example.com/.well-known/example'.
-
- Registered names MUST conform to the segment-nz production in
- [RFC3986].
-
- Note that this specification defines neither how to determine the
- authority to use for a particular context, nor the scope of the
- metadata discovered by dereferencing the well-known URI; both should
- be defined by the application itself.
-
- Typically, a registration will reference a specification that defines
- the format and associated media type to be obtained by dereferencing
- the well-known URI.
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 3]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
- It MAY also contain additional information, such as the syntax of
- additional path components, query strings and/or fragment identifiers
- to be appended to the well-known URI, or protocol-specific details
- (e.g., HTTP [RFC2616] method handling).
-
- Note that this specification does not define a format or media-type
- for the resource located at "/.well-known/" and clients should not
- expect a resource to exist at that location.
-
-4. Security Considerations
-
- This memo does not specify the scope of applicability of metadata or
- policy obtained from a well-known URI, and does not specify how to
- discover a well-known URI for a particular application. Individual
- applications using this mechanism must define both aspects.
-
- Applications minting new well-known URIs, as well as administrators
- deploying them, will need to consider several security-related
- issues, including (but not limited to) exposure of sensitive data,
- denial-of-service attacks (in addition to normal load issues), server
- and client authentication, vulnerability to DNS rebinding attacks,
- and attacks where limited access to a server grants the ability to
- affect how well-known URIs are served.
-
-5. IANA Considerations
-
-5.1. The Well-Known URI Registry
-
- This document establishes the well-known URI registry.
-
- Well-known URIs are registered on the advice of one or more
- Designated Experts (appointed by the IESG or their delegate), with a
- Specification Required (using terminology from [RFC5226]). However,
- to allow for the allocation of values prior to publication, the
- Designated Expert(s) may approve registration once they are satisfied
- that such a specification will be published.
-
- Registration requests should be sent to the
- wellknown-uri-review@ietf.org mailing list for review and comment,
- with an appropriate subject (e.g., "Request for well-known URI:
- example").
-
- Before a period of 14 days has passed, the Designated Expert(s) will
- either approve or deny the registration request, communicating this
- decision both to the review list and to IANA. Denials should include
- an explanation and, if applicable, suggestions as to how to make the
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 4]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
- request successful. Registration requests that are undetermined for
- a period longer than 21 days can be brought to the IESG's attention
- (using the iesg@iesg.org mailing list) for resolution.
-
-5.1.1. Registration Template
-
- URI suffix: The name requested for the well-known URI, relative to
- "/.well-known/"; e.g., "example".
-
- Change controller: For Standards-Track RFCs, state "IETF". For
- others, give the name of the responsible party. Other details
- (e.g., postal address, e-mail address, home page URI) may also be
- included.
-
- Specification document(s): Reference to the document that specifies
- the field, preferably including a URI that can be used to retrieve
- a copy of the document. An indication of the relevant sections
- may also be included, but is not required.
-
- Related information: Optionally, citations to additional documents
- containing further relevant information.
-
-6. References
-
-6.1. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
- Resource Identifier (URI): Generic Syntax", STD 66,
- RFC 3986, January 2005.
-
- [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an
- IANA Considerations Section in RFCs", BCP 26, RFC 5226,
- May 2008.
-
-6.2. Informative References
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter,
- L., Leach, P., and T. Berners-Lee, "Hypertext Transfer
- Protocol -- HTTP/1.1", RFC 2616, June 1999.
-
- [RFC4918] Dusseault, L., "HTTP Extensions for Web Distributed
- Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 5]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
- [W3C.REC-P3P-20020416]
- Marchiori, M., "The Platform for Privacy Preferences 1.0
- (P3P1.0) Specification", World Wide Web Consortium
- Recommendation REC-P3P-20020416, April 2002,
- .
-
- [W3C.REC-webarch-20041215]
- Jacobs, I. and N. Walsh, "Architecture of the World Wide
- Web, Volume One", World Wide Web Consortium
- Recommendation REC- webarch-20041215, December 2004,
- .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 6]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
-Appendix A. Acknowledgements
-
- We would like to acknowledge the contributions of everyone who
- provided feedback and use cases for this document; in particular,
- Phil Archer, Dirk Balfanz, Adam Barth, Tim Bray, Brian Eaton, Brad
- Fitzpatrick, Joe Gregorio, Paul Hoffman, Barry Leiba, Ashok Malhotra,
- Breno de Medeiros, John Panzer, and Drummond Reed. However, they are
- not responsible for errors and omissions.
-
-Appendix B. Frequently Asked Questions
-
- 1. Aren't well-known locations bad for the Web?
-
- They are, but for various reasons -- both technical and social --
- they are commonly used and their use is increasing. This memo
- defines a "sandbox" for them, to reduce the risks of collision and
- to minimise the impact upon pre-existing URIs on sites.
-
- 2. Why /.well-known?
-
- It's short, descriptive, and according to search indices, not
- widely used.
-
- 3. What impact does this have on existing mechanisms, such as P3P and
- robots.txt?
-
- None, until they choose to use this mechanism.
-
- 4. Why aren't per-directory well-known locations defined?
-
- Allowing every URI path segment to have a well-known location
- (e.g., "/images/.well-known/") would increase the risks of
- colliding with a pre-existing URI on a site, and generally these
- solutions are found not to scale well, because they're too
- "chatty".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 7]
-
-RFC 5785 Defining Well-Known URIs April 2010
-
-
-Authors' Addresses
-
- Mark Nottingham
-
- EMail: mnot@mnot.net
- URI: http://www.mnot.net/
-
-
- Eran Hammer-Lahav
-
- EMail: eran@hueniverse.com
- URI: http://hueniverse.com/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Nottingham & Hammer-Lahav Standards Track [Page 8]
-
diff --git a/doc/rfc6352-carddav.txt b/doc/rfc6352-carddav.txt
deleted file mode 100644
index cb03747b..00000000
--- a/doc/rfc6352-carddav.txt
+++ /dev/null
@@ -1,2691 +0,0 @@
-
-
-
-
-
-
-Internet Engineering Task Force (IETF) C. Daboo
-Request for Comments: 6352 Apple
-Category: Standards Track August 2011
-ISSN: 2070-1721
-
-
- CardDAV: vCard Extensions to
- Web Distributed Authoring and Versioning (WebDAV)
-
-Abstract
-
- This document defines extensions to the Web Distributed Authoring and
- Versioning (WebDAV) protocol to specify a standard way of accessing,
- managing, and sharing contact information based on the vCard format.
-
-Status of This Memo
-
- This is an Internet Standards Track document.
-
- This document is a product of the Internet Engineering Task Force
- (IETF). It represents the consensus of the IETF community. It has
- received public review and has been approved for publication by the
- Internet Engineering Steering Group (IESG). Further information on
- Internet Standards is available in Section 2 of RFC 5741.
-
- Information about the current status of this document, any errata,
- and how to provide feedback on it may be obtained at
- http://www.rfc-editor.org/info/rfc6352.
-
-Copyright Notice
-
- Copyright (c) 2011 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 Simplified BSD License.
-
- This document may contain material from IETF Documents or IETF
- Contributions published or made publicly available before November
- 10, 2008. The person(s) controlling the copyright in some of this
- material may not have granted the IETF Trust the right to allow
-
-
-
-Daboo Standards Track [Page 1]
-
-RFC 6352 CardDAV August 2011
-
-
- modifications of such material outside the IETF Standards Process.
- Without obtaining an adequate license from the person(s) controlling
- the copyright in such materials, this document may not be modified
- outside the IETF Standards Process, and derivative works of it may
- not be created outside the IETF Standards Process, except to format
- it for publication as an RFC or to translate it into languages other
- than English.
-
-Table of Contents
-
- 1. Introduction and Overview . . . . . . . . . . . . . . . . . . 4
- 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 5
- 3. Requirements Overview . . . . . . . . . . . . . . . . . . . . 6
- 4. Address Book Data Model . . . . . . . . . . . . . . . . . . . 7
- 4.1. Address Book Server . . . . . . . . . . . . . . . . . . . 7
- 5. Address Book Resources . . . . . . . . . . . . . . . . . . . . 7
- 5.1. Address Object Resources . . . . . . . . . . . . . . . . . 7
- 5.1.1. Data Type Conversion . . . . . . . . . . . . . . . . . 8
- 5.1.1.1. Additional Precondition for GET . . . . . . . . . 8
- 5.2. Address Book Collections . . . . . . . . . . . . . . . . . 9
- 6. Address Book Feature . . . . . . . . . . . . . . . . . . . . . 10
- 6.1. Address Book Support . . . . . . . . . . . . . . . . . . . 10
- 6.1.1. Example: Using OPTIONS for the Discovery of
- Support for CardDAV . . . . . . . . . . . . . . . . . 10
- 6.2. Address Book Properties . . . . . . . . . . . . . . . . . 10
- 6.2.1. CARDDAV:addressbook-description Property . . . . . . . 10
- 6.2.2. CARDDAV:supported-address-data Property . . . . . . . 11
- 6.2.3. CARDDAV:max-resource-size Property . . . . . . . . . . 12
- 6.3. Creating Resources . . . . . . . . . . . . . . . . . . . . 13
- 6.3.1. Extended MKCOL Method . . . . . . . . . . . . . . . . 13
- 6.3.1.1. Example - Successful MKCOL Request . . . . . . . . 14
- 6.3.2. Creating Address Object Resources . . . . . . . . . . 15
- 6.3.2.1. Additional Preconditions for PUT, COPY, and
- MOVE . . . . . . . . . . . . . . . . . . . . . . . 16
- 6.3.2.2. Non-Standard vCard Properties and Parameters . . . 17
- 6.3.2.3. Address Object Resource Entity Tag . . . . . . . . 18
- 7. Address Book Access Control . . . . . . . . . . . . . . . . . 18
- 7.1. Additional Principal Properties . . . . . . . . . . . . . 18
- 7.1.1. CARDDAV:addressbook-home-set Property . . . . . . . . 19
- 7.1.2. CARDDAV:principal-address Property . . . . . . . . . . 19
- 8. Address Book Reports . . . . . . . . . . . . . . . . . . . . . 20
- 8.1. REPORT Method . . . . . . . . . . . . . . . . . . . . . . 20
- 8.2. Ordinary Collections . . . . . . . . . . . . . . . . . . . 21
- 8.3. Searching Text: Collations . . . . . . . . . . . . . . . . 21
- 8.3.1. CARDDAV:supported-collation-set Property . . . . . . . 22
- 8.4. Partial Retrieval . . . . . . . . . . . . . . . . . . . . 23
- 8.5. Non-Standard Properties and Parameters . . . . . . . . . . 23
-
-
-
-
-Daboo Standards Track [Page 2]
-
-RFC 6352 CardDAV August 2011
-
-
- 8.6. CARDDAV:addressbook-query Report . . . . . . . . . . . . . 23
- 8.6.1. Limiting Results . . . . . . . . . . . . . . . . . . . 25
- 8.6.2. Truncation of Results . . . . . . . . . . . . . . . . 25
- 8.6.3. Example: Partial Retrieval of vCards Matching
- NICKNAME . . . . . . . . . . . . . . . . . . . . . . . 26
- 8.6.4. Example: Partial Retrieval of vCards Matching a
- Full Name or Email Address . . . . . . . . . . . . . . 27
- 8.6.5. Example: Truncated Results . . . . . . . . . . . . . . 29
- 8.7. CARDDAV:addressbook-multiget Report . . . . . . . . . . . 31
- 8.7.1. Example: CARDDAV:addressbook-multiget Report . . . . . 32
- 8.7.2. Example: CARDDAV:addressbook-multiget Report . . . . . 33
- 9. Client Guidelines . . . . . . . . . . . . . . . . . . . . . . 34
- 9.1. Restrict the Properties Returned . . . . . . . . . . . . . 34
- 9.2. Avoiding Lost Updates . . . . . . . . . . . . . . . . . . 35
- 9.3. Client Configuration . . . . . . . . . . . . . . . . . . . 35
- 9.4. Finding Other Users' Address Books . . . . . . . . . . . . 35
- 10. XML Element Definitions . . . . . . . . . . . . . . . . . . . 36
- 10.1. CARDDAV:addressbook XML Element . . . . . . . . . . . . . 36
- 10.2. CARDDAV:supported-collation XML Element . . . . . . . . . 36
- 10.3. CARDDAV:addressbook-query XML Element . . . . . . . . . . 37
- 10.4. CARDDAV:address-data XML Element . . . . . . . . . . . . . 37
- 10.4.1. CARDDAV:allprop XML Element . . . . . . . . . . . . . 39
- 10.4.2. CARDDAV:prop XML Element . . . . . . . . . . . . . . . 39
- 10.5. CARDDAV:filter XML Element . . . . . . . . . . . . . . . . 40
- 10.5.1. CARDDAV:prop-filter XML Element . . . . . . . . . . . 40
- 10.5.2. CARDDAV:param-filter XML Element . . . . . . . . . . . 41
- 10.5.3. CARDDAV:is-not-defined XML Element . . . . . . . . . . 42
- 10.5.4. CARDDAV:text-match XML Element . . . . . . . . . . . . 42
- 10.6. CARDDAV:limit XML Element . . . . . . . . . . . . . . . . 43
- 10.6.1. CARDDAV:nresults XML Element . . . . . . . . . . . . . 44
- 10.7. CARDDAV:addressbook-multiget XML Element . . . . . . . . . 44
- 11. Service Discovery via SRV Records . . . . . . . . . . . . . . 45
- 12. Internationalization Considerations . . . . . . . . . . . . . 45
- 13. Security Considerations . . . . . . . . . . . . . . . . . . . 45
- 14. IANA Consideration . . . . . . . . . . . . . . . . . . . . . . 46
- 14.1. Namespace Registration . . . . . . . . . . . . . . . . . . 46
- 15. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 46
- 16. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47
- 16.1. Normative References . . . . . . . . . . . . . . . . . . . 47
- 16.2. Informative References . . . . . . . . . . . . . . . . . . 48
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 3]
-
-RFC 6352 CardDAV August 2011
-
-
-1. Introduction and Overview
-
- Address books containing contact information are a key component of
- personal information management tools, such as email, calendaring and
- scheduling, and instant messaging clients. To date several protocols
- have been used for remote access to contact data, including the
- Lightweight Directory Access Protocol (LDAP) [RFC4510], Internet
- Message Support Protocol [IMSP], and Application Configuration Access
- Protocol (ACAP) [RFC2244], together with SyncML used for
- synchronization of such data.
-
- WebDAV [RFC4918] offers a number of advantages as a framework or
- basis for address book access and management. Most of these
- advantages boil down to a significant reduction in the costs of
- design, implementation, interoperability testing, and deployment.
-
- The key features of address book support with WebDAV are:
-
- 1. Ability to use multiple address books with hierarchical layout.
-
- 2. Ability to control access to individual address books and address
- entries as per WebDAV Access Control List (ACL) [RFC3744].
-
- 3. Principal collections can be used to enumerate and query other
- users on the system as per WebDAV ACL [RFC3744].
-
- 4. Server-side searching of address data, avoiding the need for
- clients to download an entire address book in order to do a quick
- address 'expansion' operation.
-
- 5. Well-defined internationalization support through WebDAV's use of
- XML.
-
- 6. Use of vCards [RFC2426] for well-defined address schema to
- enhance client interoperability.
-
- 7. Many limited clients (e.g., mobile devices) contain an HTTP stack
- that makes implementing WebDAV much easier than other protocols.
-
- The key disadvantage of address book support in WebDAV is:
-
- 1. Lack of change notification. Many of the alternative protocols
- also lack this ability. However, an extension for push
- notifications could easily be developed.
-
- vCard is a MIME directory profile aimed at encapsulating personal
- addressing and contact information about people. The specification
- of vCard was originally done by the Versit consortium, with a
-
-
-
-Daboo Standards Track [Page 4]
-
-RFC 6352 CardDAV August 2011
-
-
- subsequent 3.0 version standardized by the IETF [RFC2426]. vCard is
- in widespread use in email clients and mobile devices as a means of
- encapsulating address information for transport via email or for
- import/export and synchronization operations.
-
- An update to vCard -- vCard v4 -- is currently being developed
- [RFC6350] and is compatible with this specification.
-
-2. Conventions
-
- 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].
-
- The term "protected" is used in the Conformance field of property
- definitions as defined in Section 15 of [RFC4918].
-
- This document uses XML DTD fragments ([W3C.REC-xml-20081126], Section
- 3.2) as a purely notational convention. WebDAV request and response
- bodies cannot be validated by a DTD due to the specific extensibility
- rules defined in Section 17 of [RFC4918] and due to the fact that all
- XML elements defined by that specification use the XML namespace name
- "DAV:". In particular:
-
- 1. Element names use the "DAV:" namespace.
-
- 2. Element ordering is irrelevant unless explicitly stated.
-
- 3. Extension elements (elements not already defined as valid child
- elements) may be added anywhere, except when explicitly stated
- otherwise.
-
- 4. Extension attributes (attributes not already defined as valid for
- this element) may be added anywhere, except when explicitly
- stated otherwise.
-
- The namespace "urn:ietf:params:xml:ns:carddav" is reserved for the
- XML elements defined in this specification, its revisions, and
- related CardDAV specifications. XML elements defined by individual
- implementations MUST NOT use the "urn:ietf:params:xml:ns:carddav"
- namespace, and instead should use a namespace that they control.
-
- When XML element types in the namespaces "DAV:" and
- "urn:ietf:params:xml:ns:carddav" are referenced in this document
- outside of the context of an XML fragment, the strings "DAV:" and
- "CARDDAV:" will be prefixed to the element types, respectively.
-
-
-
-
-
-Daboo Standards Track [Page 5]
-
-RFC 6352 CardDAV August 2011
-
-
- This document inherits, and sometimes extends, DTD productions from
- Section 14 of [RFC4918].
-
- Also, note that some CardDAV XML element names are identical to
- WebDAV XML element names, though their namespace differs. Care must
- be taken not to confuse the two sets of names.
-
-3. Requirements Overview
-
- This section lists what functionality is required of a CardDAV
- server. To advertise support for CardDAV, a server:
-
- o MUST support vCard v3 [RFC2426] as a media type for the address
- object resource format;
-
- o MUST support WebDAV Class 3 [RFC4918];
-
- o MUST support WebDAV ACL [RFC3744];
-
- o MUST support secure transport as defined in [RFC2818] using
- Transport Layer Security (TLS) [RFC5246] and using the certificate
- validation procedures described in [RFC5280];
-
- o MUST support ETags [RFC2616] with additional requirements
- specified in Section 6.3.2.3 of this document;
-
- o MUST support all address book reports defined in Section 8 of this
- document; and
-
- o MUST advertise support on all address book collections and address
- object resources for the address book reports in the
- DAV:supported-report-set property, as defined in Versioning
- Extensions to WebDAV [RFC3253].
-
- In addition, a server:
-
- o SHOULD support vCard v4 [RFC6350] as a media type for the address
- object resource format;
-
- o SHOULD support the extended MKCOL method [RFC5689] to create
- address book collections as defined in Section 6.3.1 of this
- document.
-
- o SHOULD support the DAV:current-user-principal-URL property as
- defined in [RFC5397] to give clients a fast way to locate user
- principals.
-
-
-
-
-
-Daboo Standards Track [Page 6]
-
-RFC 6352 CardDAV August 2011
-
-
-4. Address Book Data Model
-
- As a brief overview, a CardDAV address book is modeled as a WebDAV
- collection with a well-defined structure; each of these address book
- collections contains a number of resources representing address
- objects as their direct child resources. Each resource representing
- an address object is called an "address object resource". Each
- address object resource and each address book collection can be
- individually locked and have individual WebDAV properties.
- Requirements derived from this model are provided in Sections 5.1 and
- 5.2.
-
-4.1. Address Book Server
-
- A CardDAV server is an address-aware engine combined with a WebDAV
- server. The server may include address data in some parts of its URL
- namespace and non-address data in other parts.
-
- A WebDAV server can advertise itself as a CardDAV server if it
- supports the functionality defined in this specification at any point
- within the root of its repository. That might mean that address data
- is spread throughout the repository and mixed with non-address data
- in nearby collections (e.g., address data may be found in /lisa/
- addressbook/ as well as in /bernard/addressbook/, and non-address
- data in /lisa/calendars/). Or, it might mean that address data can
- be found only in certain sections of the repository (e.g.,
- /addressbooks/user/). Address book features are only required in the
- repository sections that are or contain address objects. So, a
- repository confining address data to the /carddav/ collection would
- only need to support the CardDAV required features within that
- collection.
-
- The CardDAV server is the canonical location for address data and
- state information. Clients may submit requests to change data or
- download data. Clients may store address objects offline and attempt
- to synchronize at a later time. Address data on the server can
- change between the time of last synchronization and when attempting
- an update, as address book collections may be shared and accessible
- via multiple clients. Entity tags and locking help this work.
-
-5. Address Book Resources
-
-5.1. Address Object Resources
-
- This specification uses vCard as the default format for address or
- contact information being stored on the server. However, this
- specification does allow other formats for address data provided that
- the server advertises support for those additional formats as
-
-
-
-Daboo Standards Track [Page 7]
-
-RFC 6352 CardDAV August 2011
-
-
- described below. The requirements in this section pertain to vCard
- address data or formats that follow the semantics of vCard data.
-
- Address object resources contained in address book collections MUST
- contain a single vCard component only.
-
- vCard components in an address book collection MUST have a UID
- property value that MUST be unique in the scope of the address book
- collection in which it is contained.
-
-5.1.1. Data Type Conversion
-
- Servers might support more than one primary media type for address
- object resources, for example, vCard v3.0 and vCard v4.0. In such
- cases, servers have to accept all media types that they advertise via
- the CARDDAV:supported-address-data WebDAV property (see
- Section 6.2.2).
-
- However, clients can use standard HTTP content negotiation behavior
- (the Accept request header defined in Section 14.1 of [RFC2616]) to
- request that an address object resource's data be returned in a
- specific media type format. For example, a client merely capable of
- handling vCard v3.0 would only want to have address object resources
- returned in v3.0 format.
-
- Additionally, REPORT requests, defined later in this specification,
- allow for the return of address object resource data within an XML
- response body. Again, the client can use content negotiation to
- request that data be returned in a specific media type by specifying
- appropriate attributes on the CARDDAV:address-data XML element used
- in the request body (see Section 10.4).
-
- In some cases, it might not be possible for a server to convert from
- one media type to another. When that happens, the server MUST return
- the CARDDAV:supported-address-data-conversion precondition (see
- below) in the response body (when the failure to convert applies to
- the entire response) or use that same precondition code in the
- DAV:response XML element in the response for the targeted address
- object resource when one of the REPORTs defined below is used. See
- Section 8.7.2 for an example of this.
-
-5.1.1.1. Additional Precondition for GET
-
- This specification creates additional preconditions for the GET
- method.
-
-
-
-
-
-
-Daboo Standards Track [Page 8]
-
-RFC 6352 CardDAV August 2011
-
-
- The new precondition is:
-
- (CARDDAV:supported-address-data-conversion): The resource targeted
- by the GET request can be converted to the media type specified in
- the Accept request header included with the request.
-
-5.2. Address Book Collections
-
- Address book collections appear to clients as a WebDAV collection
- resource, identified by a URL. An address book collection MUST
- report the DAV:collection and CARDDAV:addressbook XML elements in the
- value of the DAV:resourcetype property. The element type declaration
- for CARDDAV:addressbook is:
-
-
-
- An address book collection can be created through provisioning (e.g.,
- automatically created when a user's account is provisioned), or it
- can be created with the extended MKCOL method (see Section 6.3.1).
- This can be used by a user to create additional address books (e.g.,
- "soccer team members") or for users to share an address book (e.g.,
- "sales team contacts"). However, note that this document doesn't
- define what extra address book collections are for. Users must rely
- on non-standard cues to find out what an address book collection is
- for, or use the CARDDAV:addressbook-description property defined in
- Section 6.2.1 to provide such a cue.
-
- The following restrictions are applied to the resources within an
- address book collection:
-
- a. Address book collections MUST only contain address object
- resources and collections that are not address book collections.
- That is, the only "top-level" non-collection resources allowed in
- an address book collection are address object resources. This
- ensures that address book clients do not have to deal with non-
- address data in an address book collection, though they do have
- to distinguish between address object resources and collections
- when using standard WebDAV techniques to examine the contents of
- a collection.
-
- b. Collections contained in address book collections MUST NOT
- contain address book collections at any depth. That is,
- "nesting" of address book collections within other address book
- collections at any depth is not allowed. This specification does
- not define how collections contained in an address book
- collection are used or how they relate to any address object
- resources contained in the address book collection.
-
-
-
-
-Daboo Standards Track [Page 9]
-
-RFC 6352 CardDAV August 2011
-
-
- Multiple address book collections MAY be children of the same
- collection.
-
-6. Address Book Feature
-
-6.1. Address Book Support
-
- A server supporting the features described in this document MUST
- include "addressbook" as a field in the DAV response header from an
- OPTIONS request on any resource that supports any address book
- properties, reports, or methods. A value of "addressbook" in the DAV
- response header MUST indicate that the server supports all MUST level
- requirements and REQUIRED features specified in this document.
-
-6.1.1. Example: Using OPTIONS for the Discovery of Support for CardDAV
-
- >> Request <<
-
- OPTIONS /addressbooks/users/ HTTP/1.1
- Host: addressbook.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
- Allow: MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
- DAV: 1, 2, 3, access-control, addressbook
- DAV: extended-mkcol
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Length: 0
-
- In this example, the OPTIONS response indicates that the server
- supports CardDAV in this namespace; therefore, the '/addressbooks/
- users/' collection may be used as a parent for address book
- collections as the extended MKCOL method is available and as a
- possible target for REPORT requests for address book reports.
-
-6.2. Address Book Properties
-
-6.2.1. CARDDAV:addressbook-description Property
-
- Name: addressbook-description
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Provides a human-readable description of the address book
- collection.
-
-
-
-
-Daboo Standards Track [Page 10]
-
-RFC 6352 CardDAV August 2011
-
-
- Value: Any text.
-
- Protected: SHOULD NOT be protected so that users can specify a
- description.
-
- COPY/MOVE behavior: This property value SHOULD be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
- Description: This property contains a description of the address
- book collection that is suitable for presentation to a user. The
- xml:lang attribute can be used to add a language tag for the value
- of this property.
-
- Definition:
-
-
-
-
- Example:
-
- Adresses de Oliver Daboo
-
-6.2.2. CARDDAV:supported-address-data Property
-
- Name: supported-address-data
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies what media types are allowed for address object
- resources in an address book collection.
-
- Protected: MUST be protected as it indicates the level of support
- provided by the server.
-
- COPY/MOVE behavior: This property value MUST be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
- Description: The CARDDAV:supported-address-data property is used to
- specify the media type supported for the address object resources
- contained in a given address book collection (e.g., vCard version
-
-
-
-Daboo Standards Track [Page 11]
-
-RFC 6352 CardDAV August 2011
-
-
- 3.0). Any attempt by the client to store address object resources
- with a media type not listed in this property MUST result in an
- error, with the CARDDAV:supported-address-data precondition
- (Section 6.3.2.1) being violated. In the absence of this
- property, the server MUST only accept data with the media type
- "text/vcard" and vCard version 3.0, and clients can assume that is
- all the server will accept.
-
- Definition:
-
-
-
-
-
-
-
-
- Example:
-
-
-
-
-
-6.2.3. CARDDAV:max-resource-size Property
-
- Name: max-resource-size
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Provides a numeric value indicating the maximum size in
- octets of a resource that the server is willing to accept when an
- address object resource is stored in an address book collection.
-
- Value: Any text representing a numeric value.
-
- Protected: MUST be protected as it indicates limits provided by the
- server.
-
- COPY/MOVE behavior: This property value MUST be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
-
-
-
-
-
-Daboo Standards Track [Page 12]
-
-RFC 6352 CardDAV August 2011
-
-
- Description: The CARDDAV:max-resource-size is used to specify a
- numeric value that represents the maximum size in octets that the
- server is willing to accept when an address object resource is
- stored in an address book collection. Any attempt to store an
- address book object resource exceeding this size MUST result in an
- error, with the CARDDAV:max-resource-size precondition
- (Section 6.3.2.1) being violated. In the absence of this
- property, the client can assume that the server will allow storing
- a resource of any reasonable size.
-
- Definition:
-
-
-
-
- Example:
-
- 102400
-
-6.3. Creating Resources
-
- Address book collections and address object resources may be created
- by either a CardDAV client or the CardDAV server. This specification
- defines restrictions and a data model that both clients and servers
- MUST adhere to when manipulating such address data.
-
-6.3.1. Extended MKCOL Method
-
- An HTTP request using the extended MKCOL method [RFC5689] can be used
- to create a new address book collection resource. A server MAY
- restrict address book collection creation to particular collections.
-
- To create an address book, the client sends an extended MKCOL request
- to the server and in the body of the request sets the
- DAV:resourcetype property to the resource type for an address book
- collection as defined in Section 5.2.
-
- Support for creating address books on the server is only RECOMMENDED
- and not REQUIRED because some address book stores only support one
- address book per user (or principal), and those are typically pre-
- created for each account. However, servers and clients are strongly
- encouraged to support address book creation whenever possible to
- allow users to create multiple address book collections to help
- organize their data better.
-
-
-
-
-
-
-Daboo Standards Track [Page 13]
-
-RFC 6352 CardDAV August 2011
-
-
- The DAV:displayname property can be used for a human-readable name of
- the address book. Clients can either specify the value of the
- DAV:displayname property in the request body of the extended MKCOL
- request or, alternatively, issue a PROPPATCH request to change the
- DAV:displayname property to the appropriate value immediately after
- using the extended MKCOL request. When displaying address book
- collections to users, clients SHOULD check the DAV:displayname
- property and use that value as the name of the address book. In the
- event that the DAV:displayname property is not set, the client MAY
- use the last part of the address book collection URI as the name;
- however, that path segment may be "opaque" and not represent any
- meaningful human-readable text.
-
-6.3.1.1. Example - Successful MKCOL Request
-
- This example creates an address book collection called /home/lisa/
- addressbook/ on the server addressbook.example.com with specific
- values for the properties DAV:resourcetype, DAV:displayname, and
- CARDDAV:addressbook-description.
-
- >> Request <<
-
- MKCOL /home/lisa/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxx
-
-
-
-
-
-
-
-
-
- Lisa's Contacts
- My primary address book.
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 14]
-
-RFC 6352 CardDAV August 2011
-
-
- >> Response <<
-
- HTTP/1.1 201 Created
- Cache-Control: no-cache
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
- HTTP/1.1 200 OK
-
-
-
-6.3.2. Creating Address Object Resources
-
- Clients populate address book collections with address object
- resources. The URL for each address object resource is entirely
- arbitrary and does not need to bear a specific relationship (but
- might) to the address object resource's vCard properties or other
- metadata. New address object resources MUST be created with a PUT
- request targeted at an unmapped URI. A PUT request targeted at a
- mapped URI updates an existing address object resource.
-
- When servers create new resources, it's not hard for the server to
- choose a unique URL. It's slightly tougher for clients, because a
- client might not want to examine all resources in the collection and
- might not want to lock the entire collection to ensure that a new one
- isn't created with a name collision. However, there is an HTTP
- feature to mitigate this. If the client intends to create a new
- address resource, the client SHOULD use the HTTP header "If-None-
- Match: *" on the PUT request. The Request-URI on the PUT request
- MUST include the target collection, where the resource is to be
- created, plus the name of the resource in the last path segment. The
- "If-None-Match" header ensures that the client will not inadvertently
- overwrite an existing resource even if the last path segment turned
- out to already be used.
-
-
-
-
-
-
-
-Daboo Standards Track [Page 15]
-
-RFC 6352 CardDAV August 2011
-
-
- >> Request <<
-
- PUT /lisa/addressbook/newvcard.vcf HTTP/1.1
- If-None-Match: *
- Host: addressbook.example.com
- Content-Type: text/vcard
- Content-Length: xxx
-
- BEGIN:VCARD
- VERSION:3.0
- FN:Cyrus Daboo
- N:Daboo;Cyrus
- ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
- EMAIL;TYPE=INTERNET,PREF:cyrus@example.com
- NICKNAME:me
- NOTE:Example VCard.
- ORG:Self Employed
- TEL;TYPE=WORK,VOICE:412 605 0499
- TEL;TYPE=FAX:412 605 0705
- URL:http://www.example.com
- UID:1234-5678-9000-1
- END:VCARD
-
- >> Response <<
-
- HTTP/1.1 201 Created
- Date: Thu, 02 Sep 2004 16:53:32 GMT
- Content-Length: 0
- ETag: "123456789-000-111"
-
- The request to change an existing address object resource without
- overwriting a change made on the server uses a specific ETag in an
- "If-Match" header, rather than the "If-None-Match" header.
-
- File names for vCards are commonly suffixed by ".vcf", and clients
- may choose to use the same convention for URLs.
-
-6.3.2.1. Additional Preconditions for PUT, COPY, and MOVE
-
- This specification creates additional preconditions for the PUT,
- COPY, and MOVE methods. These preconditions apply:
-
- o When a PUT operation of an address object resource into an address
- book collection occurs.
-
- o When a COPY or MOVE operation of an address object resource into
- an address book collection occurs.
-
-
-
-
-Daboo Standards Track [Page 16]
-
-RFC 6352 CardDAV August 2011
-
-
- The new preconditions are:
-
- (CARDDAV:supported-address-data): The resource submitted in the
- PUT request, or targeted by a COPY or MOVE request, MUST be a
- supported media type (i.e., vCard) for address object resources.
-
- (CARDDAV:valid-address-data): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST be valid data
- for the media type being specified (i.e., MUST contain valid vCard
- data).
-
- (CARDDAV:no-uid-conflict): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST NOT specify a
- vCard UID property value already in use in the targeted address
- book collection or overwrite an existing address object resource
- with one that has a different UID property value. Servers SHOULD
- report the URL of the resource that is already making use of the
- same UID property value in the DAV:href element.
-
-
-
- (CARDDAV:addressbook-collection-location-ok): In a COPY or MOVE
- request, when the Request-URI is an address book collection, the
- URI targeted by the Destination HTTP Request header MUST identify
- a location where an address book collection can be created.
-
- (CARDDAV:max-resource-size): The resource submitted in the PUT
- request, or targeted by a COPY or MOVE request, MUST have a size
- in octets less than or equal to the value of the
- CARDDAV:max-resource-size property value (Section 6.2.3) on the
- address book collection where the resource will be stored.
-
-6.3.2.2. Non-Standard vCard Properties and Parameters
-
- vCard provides a "standard mechanism for doing non-standard things".
- This extension support allows implementers to make use of non-
- standard vCard properties and parameters whose names are prefixed
- with the text "X-".
-
- Servers MUST support the use of non-standard properties and
- parameters in address object resources stored via the PUT method.
-
- Servers may need to enforce rules for their own "private" properties
- or parameters, so servers MAY reject any attempt by the client to
- change those or use values for those outside of any restrictions the
- server may have. A server SHOULD ensure that any "private"
-
-
-
-
-
-Daboo Standards Track [Page 17]
-
-RFC 6352 CardDAV August 2011
-
-
- properties or parameters it uses follow the convention of including a
- vendor ID in the "X-" name, as described in Section 3.8 of [RFC2426],
- e.g., "X-ABC-PRIVATE".
-
-6.3.2.3. Address Object Resource Entity Tag
-
- The DAV:getetag property MUST be defined and set to a strong entity
- tag on all address object resources.
-
- A response to a GET request targeted at an address object resource
- MUST contain an ETag response header field indicating the current
- value of the strong entity tag of the address object resource.
-
- Servers SHOULD return a strong entity tag (ETag header) in a PUT
- response when the stored address object resource is equivalent by
- octet equality to the address object resource submitted in the body
- of the PUT request. This allows clients to reliably use the returned
- strong entity tag for data synchronization purposes. For instance,
- the client can do a PROPFIND request on the stored address object
- resource, have the DAV:getetag property returned, compare that value
- with the strong entity tag it received on the PUT response, and know
- that if they are equal, then the address object resource on the
- server has not been changed.
-
- In the case where the data stored by a server as a result of a PUT
- request is not equivalent by octet equality to the submitted address
- object resource, the behavior of the ETag response header is not
- specified here, with the exception that a strong entity tag MUST NOT
- be returned in the response. As a result, a client may need to
- retrieve the modified address object resource (and ETag) as a basis
- for further changes, rather than use the address object resource it
- had sent with the PUT request.
-
-7. Address Book Access Control
-
- CardDAV servers MUST support and adhere to the requirements of WebDAV
- ACL [RFC3744]. WebDAV ACL provides a framework for an extensible set
- of privileges that can be applied to WebDAV collections and ordinary
- resources.
-
-7.1. Additional Principal Properties
-
- This section defines additional properties for WebDAV principal
- resources as defined in [RFC3744].
-
-
-
-
-
-
-
-Daboo Standards Track [Page 18]
-
-RFC 6352 CardDAV August 2011
-
-
-7.1.1. CARDDAV:addressbook-home-set Property
-
- Name: addressbook-home-set
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Identifies the URL of any WebDAV collections that contain
- address book collections owned by the associated principal
- resource.
-
- Protected: MAY be protected if the server has fixed locations in
- which address books are created.
-
- COPY/MOVE behavior: This property value MUST be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
- Description: The CARDDAV:addressbook-home-set property is meant to
- allow users to easily find the address book collections owned by
- the principal. Typically, users will group all the address book
- collections that they own under a common collection. This
- property specifies the URL of collections that are either address
- book collections or ordinary collections that have child or
- descendant address book collections owned by the principal.
-
- Definition:
-
-
-
- Example:
-
-
- /bernard/addresses/
-
-
-7.1.2. CARDDAV:principal-address Property
-
- Name: principal-address
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Identifies the URL of an address object resource that
- corresponds to the user represented by the principal.
-
-
-
-
-
-Daboo Standards Track [Page 19]
-
-RFC 6352 CardDAV August 2011
-
-
- Protected: MAY be protected if the server provides a fixed location
- for principal addresses.
-
- COPY/MOVE behavior: This property value MUST be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
- Description: The CARDDAV:principal-address property is meant to
- allow users to easily find contact information for users
- represented by principals on the system. This property specifies
- the URL of the resource containing the corresponding contact
- information. The resource could be an address object resource in
- an address book collection, or it could be a resource in a
- "regular" collection.
-
- Definition:
-
-
-
- Example:
-
-
- /system/cyrus.vcf
-
-
-8. Address Book Reports
-
- This section defines the reports that CardDAV servers MUST support on
- address book collections and address object resources.
-
- CardDAV servers MUST advertise support for these reports on all
- address book collections and address object resources with the
- DAV:supported-report-set property defined in Section 3.1.5 of
- [RFC3253]. CardDAV servers MAY also advertise support for these
- reports on ordinary collections.
-
- Some of these reports allow address data (from possibly multiple
- resources) to be returned.
-
-8.1. REPORT Method
-
- The REPORT method (defined in Section 3.6 of [RFC3253]) provides an
- extensible mechanism for obtaining information about a resource.
- Unlike the PROPFIND method, which returns the value of one or more
- named properties, the REPORT method can involve more complex
-
-
-
-Daboo Standards Track [Page 20]
-
-RFC 6352 CardDAV August 2011
-
-
- processing. REPORT is valuable in cases where the server has access
- to all of the information needed to perform the complex request (such
- as a query), and where it would require multiple requests for the
- client to retrieve the information needed to perform the same
- request.
-
- A server that supports this specification MUST support the
- DAV:expand-property report (defined in Section 3.8 of [RFC3253]).
-
-8.2. Ordinary Collections
-
- Servers MAY support the reports defined in this document on ordinary
- collections (collections that are not address book collections) in
- addition to address book collections or address object resources. In
- computing responses to the reports on ordinary collections, servers
- MUST only consider address object resources contained in address book
- collections that are targeted by the REPORT based on the value of the
- Depth request header.
-
-8.3. Searching Text: Collations
-
- Some of the reports defined in this section do text matches of
- character strings provided by the client and compared to stored
- address data. Since vCard data is by default encoded in the UTF-8
- charset and may include characters outside of the US-ASCII charset
- range in some property and parameter values, there is a need to
- ensure that text matching follows well-defined rules.
-
- To deal with this, this specification makes use of the IANA Collation
- Registry defined in [RFC4790] to specify collations that may be used
- to carry out the text comparison operations with a well-defined rule.
-
- Collations supported by the server MUST support "equality" and
- "substring" match operations as per [RFC4790], Section 4.2, including
- the "prefix" and "suffix" options for "substring" matching. CardDAV
- uses these match options for "equals", "contains", "starts-with", and
- "ends-with" match operations.
-
- CardDAV servers are REQUIRED to support the "i;ascii-casemap"
- [RFC4790] and "i;unicode-casemap" [RFC5051] collations and MAY
- support other collations.
-
- Servers MUST advertise the set of collations that they support via
- the CARDDAV:supported-collation-set property defined on any resource
- that supports reports that use collations.
-
-
-
-
-
-
-Daboo Standards Track [Page 21]
-
-RFC 6352 CardDAV August 2011
-
-
- In the absence of a collation explicitly specified by the client, or
- if the client specifies the "default" collation identifier (as
- defined in [RFC4790], Section 3.1), the server MUST default to using
- "i;unicode-casemap" as the collation.
-
- Wildcards (as defined in [RFC4790], Section 3.2) MUST NOT be used in
- the collation identifier.
-
- If the client chooses a collation not supported by the server, the
- server MUST respond with a CARDDAV:supported-collation precondition
- error response.
-
-8.3.1. CARDDAV:supported-collation-set Property
-
- Name: supported-collation-set
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Identifies the set of collations supported by the server
- for text matching operations.
-
- Protected: MUST be protected as it indicates support provided by the
- server.
-
- COPY/MOVE behavior: This property value MUST be preserved in COPY
- and MOVE operations.
-
- allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
- request.
-
- Description: The CARDDAV:supported-collation-set property contains
- two or more CARDDAV:supported-collation elements that specify the
- identifiers of the collations supported by the server.
-
- Definition:
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 22]
-
-RFC 6352 CardDAV August 2011
-
-
- Example:
-
-
- i;ascii-casemap
- i;octet
- i;unicode-casemap
-
-
-8.4. Partial Retrieval
-
- Some address book reports defined in this document allow partial
- retrieval of address object resources. A CardDAV client can specify
- what information to return in the body of an address book REPORT
- request.
-
- A CardDAV client can request particular WebDAV property values, all
- WebDAV property values, or a list of the names of the resource's
- WebDAV properties. A CardDAV client can also request address data to
- be returned and whether all vCard properties should be returned or
- only particular ones. See CARDDAV:address-data in Section 10.4.
-
-8.5. Non-Standard Properties and Parameters
-
- Servers MUST support the use of non-standard vCard property or
- parameter names in the CARDDAV:address-data XML element in address
- book REPORT requests to allow clients to request that non-standard
- properties and parameters be returned in the address data provided in
- the response.
-
- Servers MAY support the use of non-standard vCard property or
- parameter names in the CARDDAV:prop-filter and CARDDAV:param-filter
- XML elements specified in the CARDDAV:filter XML element of address
- book REPORT requests.
-
- Servers MUST fail with the CARDDAV:supported-filter precondition if
- an address book REPORT request uses a CARDDAV:prop-filter or
- CARDDAV:param-filter XML element that makes reference to a non-
- standard vCard property or parameter name on which the server does
- not support queries.
-
-8.6. CARDDAV:addressbook-query Report
-
- The CARDDAV:addressbook-query REPORT performs a search for all
- address object resources that match a specified filter. The response
- of this report will contain all the WebDAV properties and address
- object resource data specified in the request. In the case of the
-
-
-
-
-Daboo Standards Track [Page 23]
-
-RFC 6352 CardDAV August 2011
-
-
- CARDDAV:address-data XML element, one can explicitly specify the
- vCard properties that should be returned in the address object
- resource data that matches the filter.
-
- The format of this report is modeled on the PROPFIND method. The
- request and response bodies of the CARDDAV:addressbook-query report
- use XML elements that are also used by PROPFIND. In particular, the
- request can include XML elements to request WebDAV properties to be
- returned. When that occurs, the response should follow the same
- behavior as PROPFIND with respect to the DAV:multistatus response
- elements used to return specific WebDAV property results. For
- instance, a request to retrieve the value of a WebDAV property that
- does not exist is an error and MUST be noted with a response XML
- element that contains a 404 (Not Found) status value.
-
- Support for the CARDDAV:addressbook-query REPORT is REQUIRED.
-
- Marshalling:
-
- The request body MUST be a CARDDAV:addressbook-query XML element
- as defined in Section 10.3.
-
- The request MUST include a Depth header. The scope of the query
- is determined by the value of the Depth header. For example, to
- query all address object resources in an address book collection,
- the REPORT would use the address book collection as the Request-
- URI and specify a Depth of 1 or infinity.
-
- The response body for a successful request MUST be a
- DAV:multistatus XML element (i.e., the response uses the same
- format as the response for PROPFIND). In the case where there are
- no response elements, the returned DAV:multistatus XML element is
- empty.
-
- The response body for a successful CARDDAV:addressbook-query
- REPORT request MUST contain a DAV:response element for each
- address object that matched the search filter. Address data is
- returned in the CARDDAV:address-data XML element inside the
- DAV:propstat XML element.
-
- Preconditions:
-
- (CARDDAV:supported-address-data): The attributes "content-type"
- and "version" of the CARDDAV:address-data XML element (see
- Section 10.4) specify a media type supported by the server for
- address object resources.
-
-
-
-
-
-Daboo Standards Track [Page 24]
-
-RFC 6352 CardDAV August 2011
-
-
- (CARDDAV:supported-filter): The CARDDAV:prop-filter (see
- Section 10.5.1) and CARDDAV:param-filter (see Section 10.5.2) XML
- elements used in the CARDDAV:filter XML element (see Section 10.5)
- in the REPORT request only make reference to vCard properties and
- parameters for which queries are supported by the server. That
- is, if the CARDDAV:filter element attempts to reference an
- unsupported vCard property or parameter, this precondition is
- violated. A server SHOULD report the CARDDAV:prop-filter or
- CARDDAV:param-filter for which it does not provide support.
-
-
-
- (CARDDAV:supported-collation): Any XML attribute specifying a
- collation MUST specify a collation supported by the server as
- described in Section 8.3.
-
- Postconditions:
-
- (DAV:number-of-matches-within-limits): The number of matching
- address object resources must fall within server-specific,
- predefined limits. For example, this condition might be triggered
- if a search specification would cause the return of an extremely
- large number of responses.
-
-8.6.1. Limiting Results
-
- A client can limit the number of results returned by the server
- through use of the CARDDAV:limit element in the request body. This
- is useful when clients are only interested in a few matches or only
- have limited space to display results to users and thus don't need
- the overhead of receiving more than that. When the results are
- truncated by the server, the server MUST follow the rules below for
- indicating a result set truncation to the client.
-
-8.6.2. 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 query,
- or as the result of an explicit limit set by the client. If the
- result set is truncated because of such a limit, the response MUST
- use status code 207 (Multi-Status), 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.
-
-
-
-
-
-Daboo Standards Track [Page 25]
-
-RFC 6352 CardDAV August 2011
-
-
- The server SHOULD also include the partial results in additional
- DAV:response elements. If a client-requested limit is being applied,
- the 507 response for the Request-URI MUST NOT be included in
- calculating the limit (e.g., if the client requests that only a
- single result be returned, and multiple matches are present, then the
- DAV:multistatus response will include one DAV:response for the
- matching resource and one DAV:response for the 507 status on the
- Request-URI).
-
-8.6.3. Example: Partial Retrieval of vCards Matching NICKNAME
-
- In this example, the client requests that the server search for
- address object resources that contain a NICKNAME property whose value
- equals some specific text and return specific vCard properties for
- those vCards found. In addition, the DAV:getetag property is also
- requested and returned as part of the response.
-
- >> Request <<
-
- REPORT /home/bernard/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Depth: 1
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- me
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 26]
-
-RFC 6352 CardDAV August 2011
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /home/bernard/addressbook/v102.vcf
-
-
- "23ba4d-ff11fb"
- BEGIN:VCARD
- VERSION:3.0
- NICKNAME:me
- UID:34222-232@example.com
- FN:Cyrus Daboo
- EMAIL:daboo@example.com
- END:VCARD
-
-
- HTTP/1.1 200 OK
-
-
-
-
-8.6.4. Example: Partial Retrieval of vCards Matching a Full Name or
- Email Address
-
- In this example, the client requests that the server search for
- address object resources that contain a FN property whose value
- contains some specific text or that contain an EMAIL property whose
- value contains other text and return specific vCard properties for
- those vCards found. In addition, the DAV:getetag property is also
- requested and returned as part of the response.
-
- >> Request <<
-
- REPORT /home/bernard/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Depth: 1
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-Daboo Standards Track [Page 27]
-
-RFC 6352 CardDAV August 2011
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- daboo
-
-
- daboo
-
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /home/bernard/addressbook/v102.vcf
-
-
- "23ba4d-ff11fb"
- BEGIN:VCARD
- VERSION:3.0
- NICKNAME:me
- UID:34222-232@example.com
- FN:David Boo
- EMAIL:daboo@example.com
-
-
-
-Daboo Standards Track [Page 28]
-
-RFC 6352 CardDAV August 2011
-
-
- END:VCARD
-
-
- HTTP/1.1 200 OK
-
-
-
- /home/bernard/addressbook/v104.vcf
-
-
- "23ba4d-ff11fc"
- BEGIN:VCARD
- VERSION:3.0
- NICKNAME:oliver
- UID:34222-23222@example.com
- FN:Oliver Daboo
- EMAIL:oliver@example.com
- END:VCARD
-
-
- HTTP/1.1 200 OK
-
-
-
-
-8.6.5. Example: Truncated Results
-
- In this example, the client requests that the server search for
- address object resources that contain a FN property whose value
- contains some specific text and return the DAV:getetag property for
- two results only. The server response includes a 507 status for the
- Request-URI indicating that there were more than two resources that
- matched the query, but that the server truncated the result set as
- requested by the client.
-
- >> Request <<
-
- REPORT /home/bernard/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Depth: 1
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 29]
-
-RFC 6352 CardDAV August 2011
-
-
-
-
-
-
-
- daboo
-
-
-
- 2
-
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /home/bernard/addressbook/
- HTTP/1.1 507 Insufficient Storage
-
-
- Only two matching records were returned
-
-
-
- /home/bernard/addressbook/v102.vcf
-
-
- "23ba4d-ff11fb"
-
- HTTP/1.1 200 OK
-
-
-
- /home/bernard/addressbook/v104.vcf
-
-
- "23ba4d-ff11fc"
-
-
-
-
-Daboo Standards Track [Page 30]
-
-RFC 6352 CardDAV August 2011
-
-
- HTTP/1.1 200 OK
-
-
-
-
-8.7. CARDDAV:addressbook-multiget Report
-
- The CARDDAV:addressbook-multiget REPORT is used to retrieve specific
- address object resources from within a collection, if the Request-URI
- is a collection, or to retrieve a specific address object resource,
- if the Request-URI is an address object resource. This report is
- similar to the CARDDAV:addressbook-query REPORT (see Section 8.6),
- except that it takes a list of DAV:href elements instead of a
- CARDDAV:filter element to determine which address object resources to
- return.
-
- Support for the addressbook-multiget REPORT is REQUIRED.
-
- Marshalling:
-
- The request body MUST be a CARDDAV:addressbook-multiget XML
- element (see Section 10.7), which MUST contain at least one
- DAV:href XML element and one optional CARDDAV:address-data element
- as defined in Section 10.4. If DAV:href elements are present, the
- scope of the request is the set of resources identified by these
- elements, which all need to be members (not necessarily internal
- members) of the resource identified by the Request-URI.
- Otherwise, the scope is the resource identified by the Request-URI
- itself.
-
- The request MUST include a Depth: 0 header; however, the actual
- scope of the REPORT is determined as described above.
-
- The response body for a successful request MUST be a
- DAV:multistatus XML element.
-
- The response body for a successful CARDDAV:addressbook-multiget
- REPORT request MUST contain a DAV:response element for each
- address object resource referenced by the provided set of DAV:href
- elements. Address data is returned in the CARDDAV:address-data
- element inside the DAV:prop element.
-
- In the case of an error accessing any of the provided DAV:href
- resources, the server MUST return the appropriate error status
- code in the DAV:status element of the corresponding DAV:response
- element.
-
-
-
-
-
-Daboo Standards Track [Page 31]
-
-RFC 6352 CardDAV August 2011
-
-
- Preconditions:
-
- (CARDDAV:supported-address-data): The attributes "content-type"
- and "version" of the CARDDAV:address-data XML elements (see
- Section 10.4) specify a media type supported by the server for
- address object resources.
-
- Postconditions:
-
- None.
-
-8.7.1. Example: CARDDAV:addressbook-multiget Report
-
- In this example, the client requests the server to return specific
- vCard properties of the address components referenced by specific
- URIs. In addition, the DAV:getetag property is also requested and
- returned as part of the response. Note that, in this example, the
- resource at
- http://addressbook.example.com/home/bernard/addressbook/vcf1.vcf does
- not exist, resulting in an error status response.
-
- >> Request <<
-
- REPORT /home/bernard/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Depth: 1
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-
-
-
-
-
- /home/bernard/addressbook/vcf102.vcf
- /home/bernard/addressbook/vcf1.vcf
-
-
-
-
-
-
-
-Daboo Standards Track [Page 32]
-
-RFC 6352 CardDAV August 2011
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /home/bernard/addressbook/vcf102.vcf
-
-
- "23ba4d-ff11fb"
- BEGIN:VCARD
- VERSION:3.0
- NICKNAME:me
- UID:34222-232@example.com
- FN:Cyrus Daboo
- EMAIL:daboo@example.com
- END:VCARD
-
-
- HTTP/1.1 200 OK
-
-
-
- /home/bernard/addressbook/vcf1.vcf
- HTTP/1.1 404 Resource not found
-
-
-
-8.7.2. Example: CARDDAV:addressbook-multiget Report
-
- In this example, the client requests the server to return vCard v4.0
- data of the address components referenced by specific URIs. In
- addition, the DAV:getetag property is also requested and returned as
- part of the response. Note that, in this example, the resource at
- http://addressbook.example.com/home/bernard/addressbook/vcf3.vcf
- exists but in a media type format that the server is unable to
- convert, resulting in an error status response.
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 33]
-
-RFC 6352 CardDAV August 2011
-
-
- >> Request <<
-
- REPORT /home/bernard/addressbook/ HTTP/1.1
- Host: addressbook.example.com
- Depth: 1
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
- /home/bernard/addressbook/vcf3.vcf
-
-
- >> Response <<
-
- HTTP/1.1 207 Multi-Status
- Date: Sat, 11 Nov 2006 09:32:12 GMT
- Content-Type: text/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
- /home/bernard/addressbook/vcf3.vcf
- HTTP/1.1 415 Unsupported Media Type
-
- Unable to convert from vCard v3.0
- to vCard v4.0
-
-
-
-9. Client Guidelines
-
-9.1. Restrict the Properties Returned
-
- Clients may not need all the properties in a vCard object when
- presenting information to the user, or looking up specific items for
- their email address, for example. Since some property data can be
- large (e.g., PHOTO or SOUND with in-line content) clients can choose
- to ignore those by only requesting the specific items it knows it
- will use, through use of the CARDDAV:address-data XML element in the
- relevant reports.
-
-
-
-Daboo Standards Track [Page 34]
-
-RFC 6352 CardDAV August 2011
-
-
- However, if a client needs to make a change to a vCard, it can only
- change the entire vCard data via a PUT request. There is no way to
- incrementally make a change to a set of properties within a vCard
- object resource. As a result, the client will have to cache the
- entire set of properties on a resource that is being changed.
-
-9.2. Avoiding Lost Updates
-
- When resources are accessed by multiple clients, the possibility of
- clients overwriting each other's changes exists. To alleviate this,
- clients SHOULD use the If-Match request header on PUT requests with
- the ETag of the previously retrieved resource data to check whether
- the resource was modified since it was previously retrieved. If a
- precondition failure occurs, clients need to reload the resource and
- go through their own merge or conflict resolution process before
- writing back the data (again using the If-Match check).
-
-9.3. Client Configuration
-
- When CardDAV clients need to be configured, the key piece of
- information that they require is the principal-URL of the user whose
- address book information is desired. Servers SHOULD support the
- DAV:current-user-principal-URL property as defined in [RFC5397] to
- give clients a fast way to locate user principals.
-
- Given support for SRV records (Section 11) and DAV:current-user-
- principal-URL [RFC5397], users only need enter a user identifier,
- host name, and password to configure their client. The client would
- take the host name and do an SRV lookup to locate the CardDAV server,
- then execute an authenticated PROPFIND on the root/resource looking
- for the DAV:current-user-principal-URL property. The value returned
- gives the client direct access to the user's principal-URL and from
- there all the related CardDAV properties needed to locate address
- books.
-
-9.4. Finding Other Users' Address Books
-
- For use cases of address book sharing, one might wish to find the
- address book belonging to another user. To find other users' address
- books on the same server, the DAV:principal-property-search REPORT
- [RFC3744] can be used to search principals for matching properties
- and return specified properties for the matching principal resources.
- To search for an address book owned by a user named "Laurie", the
- REPORT request body would look like this:
-
-
-
-
-
-
-
-Daboo Standards Track [Page 35]
-
-RFC 6352 CardDAV August 2011
-
-
-
-
-
-
-
-
- Laurie
-
-
-
-
-
-
-
- The server performs a case-sensitive or caseless search for a
- matching string subset of "Laurie" within the DAV:displayname
- property. Thus, the server might return "Laurie Dusseault", "Laurier
- Desruisseaux", or "Wilfrid Laurier" all as matching DAV:displayname
- values, and the address books for each of these.
-
-10. XML Element Definitions
-
-10.1. CARDDAV:addressbook XML Element
-
- Name: addressbook
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies the resource type of an address book collection.
-
- Description: See Section 5.2.
-
- Definition:
-
-
-
-10.2. CARDDAV:supported-collation XML Element
-
- Name: supported-collation
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Identifies a single collation via its collation identifier
- as defined by [RFC4790].
-
- Description: The CARDDAV:supported-collation contains the text of a
- collation identifier as described in Section 8.3.1.
-
-
-
-Daboo Standards Track [Page 36]
-
-RFC 6352 CardDAV August 2011
-
-
- Definition:
-
-
-
-
-10.3. CARDDAV:addressbook-query XML Element
-
- Name: addressbook-query
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Defines a report for querying address book data
-
- Description: See Section 8.6.
-
- Definition:
-
-
-
-10.4. CARDDAV:address-data XML Element
-
- Name: address-data
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies one of the following:
-
- 1. The parts of an address object resource that should be
- returned by a given address book REPORT request, and the media
- type and version for the returned data; or
-
- 2. The content of an address object resource in a response to an
- address book REPORT request.
-
- Description: When used in an address book REPORT request, the
- CARDDAV:address-data XML element specifies which parts of address
- object resources need to be returned in the response. If the
- CARDDAV:address-data XML element doesn't contain any CARDDAV:prop
- elements, address object resources will be returned in their
- entirety. Additionally, a media type and version can be specified
- to request that the server return the data in that format if
- possible.
-
- Finally, when used in an address book REPORT response, the
- CARDDAV:address-data XML element specifies the content of an
- address object resource. Given that XML parsers normalize the
-
-
-
-Daboo Standards Track [Page 37]
-
-RFC 6352 CardDAV August 2011
-
-
- two-character sequence CRLF (US-ASCII decimal 13 and US-ASCII
- decimal 10) to a single LF character (US-ASCII decimal 10), the CR
- character (US-ASCII decimal 13) MAY be omitted in address object
- resources specified in the CARDDAV:address-data XML element.
- Furthermore, address object resources specified in the
- CARDDAV:address-data XML element MAY be invalid per their media
- type specification if the CARDDAV:address-data XML element part of
- the address book REPORT request did not specify required vCard
- properties (e.g., UID, etc.) or specified a CARDDAV:prop XML
- element with the "novalue" attribute set to "yes".
-
- Note: The CARDDAV:address-data XML element is specified in requests
- and responses inside the DAV:prop XML element as if it were a
- WebDAV property. However, the CARDDAV:address-data XML element is
- not a WebDAV property and as such it is not returned in PROPFIND
- responses nor used in PROPPATCH requests.
-
- Note: The address data embedded within the CARDDAV:address-data XML
- element MUST follow the standard XML character data encoding
- rules, including use of <, >, & etc., entity encoding or
- the use of a construct. In the latter case, the
- vCard data cannot contain the character sequence "]]>", which is
- the end delimiter for the CDATA section.
-
- Definition:
-
-
-
- when nested in the DAV:prop XML element in an address book
- REPORT request to specify which parts of address object
- resources should be returned in the response;
-
-
-
-
- when nested in the DAV:prop XML element in an address book
- REPORT response to specify the content of a returned
- address object resource.
-
-
-
-
-
- attributes can be used on each variant of the
- CALDAV:address-data XML element.
-
-
-
-
-
-Daboo Standards Track [Page 38]
-
-RFC 6352 CardDAV August 2011
-
-
-10.4.1. CARDDAV:allprop XML Element
-
- Name: allprop
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies that all vCard properties shall be returned.
-
- Description: This element can be used when the client wants all
- vCard properties of components returned by a report.
-
- Definition:
-
-
-
- Note: The CARDDAV:allprop element defined here has the same name as
- the DAV:allprop element defined in WebDAV. However, the
- CARDDAV:allprop element defined here uses the
- "urn:ietf:params:xml:ns:carddav" namespace, as opposed to the "DAV:"
- namespace used for the DAV:allprop element defined in WebDAV.
-
-10.4.2. CARDDAV:prop XML Element
-
- Name: prop
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Defines which vCard properties to return in the response.
-
- Description: The "name" attribute specifies the name of the vCard
- property to return (e.g., "NICKNAME"). The "novalue" attribute
- can be used by clients to request that the actual value of the
- property not be returned (if the "novalue" attribute is set to
- "yes"). In that case, the server will return just the vCard
- property name and any vCard parameters and a trailing ":" without
- the subsequent value data.
-
- vCard allows a "group" prefix to appear before a property name in
- the vCard data. When the "name" attribute does not specify a
- group prefix, it MUST match properties in the vCard data without a
- group prefix or with any group prefix. When the "name" attribute
- includes a group prefix, it MUST match properties that have
- exactly the same group prefix and name. For example, a "name" set
- to "TEL" will match "TEL", "X-ABC.TEL", and "X-ABC-1.TEL" vCard
- properties. A "name" set to "X-ABC.TEL" will match an "X-ABC.TEL"
- vCard property only; it will not match "TEL" or "X-ABC-1.TEL".
-
-
-
-
-
-Daboo Standards Track [Page 39]
-
-RFC 6352 CardDAV August 2011
-
-
- Definition:
-
-
-
-
-
-
-
- Note: The CARDDAV:prop element defined here has the same name as the
- DAV:prop element defined in WebDAV. However, the CARDDAV:prop
- element defined here uses the "urn:ietf:params:xml:ns:carddav"
- namespace, as opposed to the "DAV:" namespace used for the DAV:prop
- element defined in WebDAV.
-
-10.5. CARDDAV:filter XML Element
-
- Name: filter
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Determines which matching objects are returned.
-
- Description: The "filter" element specifies the search filter used
- to match address objects that should be returned by a report. The
- "test" attribute specifies whether any (logical OR) or all
- (logical AND) of the prop-filter tests need to match in order for
- the overall filter to match.
-
- Definition:
-
-
-
-
-
-
-10.5.1. CARDDAV:prop-filter XML Element
-
- Name: prop-filter
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Limits the search to specific vCard properties.
-
-
-
-
-
-
-Daboo Standards Track [Page 40]
-
-RFC 6352 CardDAV August 2011
-
-
- Description: The CARDDAV:prop-filter XML element specifies search
- criteria on a specific vCard property (e.g., "NICKNAME"). An
- address object is said to match a CARDDAV:prop-filter if:
-
- * A vCard property of the type specified by the "name" attribute
- exists, and the CARDDAV:prop-filter is empty, or it matches any
- specified CARDDAV:text-match or CARDDAV:param-filter
- conditions. The "test" attribute specifies whether any
- (logical OR) or all (logical AND) of the text-filter and param-
- filter tests need to match in order for the overall filter to
- match.
-
- or:
-
- * A vCard property of the type specified by the "name" attribute
- does not exist, and the CARDDAV:is-not-defined element is
- specified.
-
- vCard allows a "group" prefix to appear before a property name in
- the vCard data. When the "name" attribute does not specify a
- group prefix, it MUST match properties in the vCard data without a
- group prefix or with any group prefix. When the "name" attribute
- includes a group prefix, it MUST match properties that have
- exactly the same group prefix and name. For example, a "name" set
- to "TEL" will match "TEL", "X-ABC.TEL", "X-ABC-1.TEL" vCard
- properties. A "name" set to "X-ABC.TEL" will match an "X-ABC.TEL"
- vCard property only, it will not match "TEL" or "X-ABC-1.TEL".
-
- Definition:
-
-
-
-
-
-
-10.5.2. CARDDAV:param-filter XML Element
-
- Name: param-filter
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Limits the search to specific parameter values.
-
-
-
-
-Daboo Standards Track [Page 41]
-
-RFC 6352 CardDAV August 2011
-
-
- Description: The CARDDAV:param-filter XML element specifies search
- criteria on a specific vCard property parameter (e.g., TYPE) in
- the scope of a given CARDDAV:prop-filter. A vCard property is
- said to match a CARDDAV:param-filter if:
-
- * A parameter of the type specified by the "name" attribute
- exists, and the CARDDAV:param-filter is empty, or it matches
- the CARDDAV:text-match conditions if specified.
-
- or:
-
- * A parameter of the type specified by the "name" attribute does
- not exist, and the CARDDAV:is-not-defined element is specified.
-
- Definition:
-
-
-
-
-
-
-10.5.3. CARDDAV:is-not-defined XML Element
-
- Name: is-not-defined
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies that a match should occur if the enclosing vCard
- property or parameter does not exist.
-
- Description: The CARDDAV:is-not-defined XML element specifies that a
- match occurs if the enclosing vCard property or parameter value
- specified in an address book REPORT request does not exist in the
- address data being tested.
-
- Definition:
-
-
-
-10.5.4. CARDDAV:text-match XML Element
-
- Name: text-match
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies a substring match on a vCard property or
- parameter value.
-
-
-
-
-Daboo Standards Track [Page 42]
-
-RFC 6352 CardDAV August 2011
-
-
- Description: The CARDDAV:text-match XML element specifies text used
- for a substring match against the vCard property or parameter
- value specified in an address book REPORT request.
-
- The "collation" attribute is used to select the collation that the
- server MUST use for character string matching. In the absence of
- this attribute, the server MUST use the "i;unicode-casemap"
- collation.
-
- The "negate-condition" attribute is used to indicate that this
- test returns a match if the text matches, when the attribute value
- is set to "no", or return a match if the text does not match, if
- the attribute value is set to "yes". For example, this can be
- used to match components with a CATEGORIES property not set to
- PERSON.
-
- The "match-type" attribute is used to indicate the type of match
- operation to use. Possible choices are:
-
- "equals" - an exact match to the target string
-
- "contains" - a substring match, matching anywhere within the
- target string
-
- "starts-with" - a substring match, matching only at the start
- of the target string
-
- "ends-with" - a substring match, matching only at the end of
- the target string
-
- Definition:
-
-
-
-
-
-
-10.6. CARDDAV:limit XML Element
-
- Name: limit
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies different types of limits that can be applied to
- the results returned by the server.
-
-
-
-Daboo Standards Track [Page 43]
-
-RFC 6352 CardDAV August 2011
-
-
- Description: The CARDDAV:limit XML element can be used to specify
- different types of limits that the client can request the server
- to apply to the results returned by the server. Currently, only
- the CARDDAV:nresults limit can be used; other types of limit could
- be defined in the future.
-
- Definition:
-
-
-
-10.6.1. CARDDAV:nresults XML Element
-
- Name: nresults
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: Specifies a limit on the number of results returned by the
- server.
-
- Description: The CARDDAV:nresults XML element contains a requested
- maximum number of DAV:response elements to be returned in the
- response body of a query. The server MAY disregard this limit.
- The value of this element is an unsigned integer.
-
- Definition:
-
-
-
-
-10.7. CARDDAV:addressbook-multiget XML Element
-
- Name: addressbook-multiget
-
- Namespace: urn:ietf:params:xml:ns:carddav
-
- Purpose: CardDAV report used to retrieve specific address objects
- via their URIs.
-
- Description: See Section 8.7.
-
- Definition:
-
-
-
-
-
-
-
-Daboo Standards Track [Page 44]
-
-RFC 6352 CardDAV August 2011
-
-
-11. Service Discovery via SRV Records
-
- [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 RRs.
-
- This specification adds two service types for use with SRV records:
-
- carddav: Identifies a CardDAV server that uses HTTP without TLS
- [RFC2818].
-
- carddavs: Identifies a CardDAV server that uses HTTP with TLS
- [RFC2818].
-
- Example: non-TLS service record
-
- _carddav._tcp SRV 0 1 80 addressbook.example.com.
-
- Example: TLS service
-
- _carddavs._tcp SRV 0 1 443 addressbook.example.com.
-
-12. Internationalization Considerations
-
- CardDAV allows internationalized strings to be stored and retrieved
- for the description of address book collections (see Section 6.2.1).
-
- The CARDDAV:addressbook-query REPORT (Section 8.6) includes a text
- searching option controlled by the CARDDAV:text-match element and
- details of character handling are covered in the description of that
- element (see Section 10.5.4).
-
-13. Security Considerations
-
- HTTP protocol transactions are sent in the clear over the network
- unless protection from snooping is negotiated. This can be
- accomplished by use of TLS as defined in [RFC2818]. In particular,
- if HTTP Basic authentication [RFC2617] is available, the server MUST
- allow TLS to be used at the same time, and it SHOULD prevent use of
- Basic authentication when TLS is not in use. Clients SHOULD use TLS
- whenever possible.
-
- With the ACL extension [RFC3744] present, WebDAV allows control over
- who can access (read or write) any resource on the WebDAV server. In
- addition, WebDAV ACL provides for an "inheritance" mechanism, whereby
- resources may inherit access privileges from other resources. Often,
- the "other" resource is a parent collection of the resource itself.
- Servers are able to support address books that are "private"
-
-
-
-Daboo Standards Track [Page 45]
-
-RFC 6352 CardDAV August 2011
-
-
- (accessible only to the "owner"), "shared" (accessible to the owner
- and other specified authenticated users), and "public" (accessible to
- any authenticated or unauthenticated users). When provisioning
- address books of a particular type, servers MUST ensure that the
- correct privileges are applied on creation. In particular, private
- and shared address books MUST NOT be accessible by unauthenticated
- users (to prevent data from being automatically searched or indexed
- by web "crawlers").
-
- Clients SHOULD warn users in an appropriate fashion when they copy or
- move address data from a private address book to a shared address
- book or public address book. Clients SHOULD provide a clear
- indication as to which address books are private, shared, or public.
- Clients SHOULD provide an appropriate warning when changing access
- privileges for a private or shared address book with data so as to
- allow unauthenticated users access.
-
- This specification currently relies on standard HTTP authentication
- mechanisms for identifying users. These comprise Basic and Digest
- authentication [RFC2617] as well as TLS [RFC2818] using client-side
- certificates.
-
-14. IANA Consideration
-
- This document uses a URN to describe a new XML namespace conforming
- to the registry mechanism described in [RFC3688].
-
-14.1. Namespace Registration
-
- Registration request for the carddav namespace:
-
- URI: urn:ietf:params:xml:ns:carddav
-
- Registrant Contact: The IESG
-
- XML: None - not applicable for namespace registrations.
-
-15. Acknowledgments
-
- Thanks go to Lisa Dusseault and Bernard Desruisseaux for their work
- on CalDAV, on which CardDAV is heavily based. The following
- individuals contributed their ideas and support for writing this
- specification: Mike Douglass, Stefan Eissing, Helge Hess, Arnaud
- Quillaud, Julian Reschke, Elias Sinderson, Greg Stein, Wilfredo
- Sanchez, and Simon Vaillancourt.
-
-
-
-
-
-
-Daboo Standards Track [Page 46]
-
-RFC 6352 CardDAV August 2011
-
-
-16. References
-
-16.1. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC2426] Dawson, F. and T. Howes, "vCard MIME Directory Profile",
- RFC 2426, September 1998.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
- 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 services (DNS SRV)", RFC 2782,
- February 2000.
-
- [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
-
- [RFC3253] Clemm, G., Amsden, J., Ellison, T., Kaler, C., and J.
- Whitehead, "Versioning Extensions to WebDAV
- (Web Distributed Authoring and Versioning)", RFC 3253,
- March 2002.
-
- [RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
- January 2004.
-
- [RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
- Distributed Authoring and Versioning (WebDAV)
- Access Control Protocol", RFC 3744, May 2004.
-
- [RFC4790] Newman, C., Duerst, M., and A. Gulbrandsen, "Internet
- Application Protocol Collation Registry", RFC 4790,
- March 2007.
-
- [RFC4918] Dusseault, L., "HTTP Extensions for Web Distributed
- Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
-
- [RFC5051] Crispin, M., "i;unicode-casemap - Simple Unicode Collation
- Algorithm", RFC 5051, October 2007.
-
-
-
-
-
-Daboo Standards Track [Page 47]
-
-RFC 6352 CardDAV August 2011
-
-
- [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
- (TLS) Protocol Version 1.2", RFC 5246, August 2008.
-
- [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
- Housley, R., and W. Polk, "Internet X.509 Public Key
- Infrastructure Certificate and Certificate Revocation List
- (CRL) Profile", RFC 5280, May 2008.
-
- [RFC5397] Sanchez, W. and C. Daboo, "WebDAV Current Principal
- Extension", RFC 5397, December 2008.
-
- [RFC5689] Daboo, C., "Extended MKCOL for Web Distributed Authoring
- and Versioning (WebDAV)", RFC 5689, September 2009.
-
- [RFC6350] Perreault, S., "vCard Format Specification", RFC 6350,
- August 2011.
-
- [W3C.REC-xml-20081126]
- Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., and
- F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth
- Edition)", World Wide Web Consortium Recommendation REC-
- xml-20081126, November 2008,
- .
-
-16.2. Informative References
-
- [IMSP] Myers, J., "IMSP - Internet Message Support Protocol",
- Work in Progress, June 1995.
-
- [RFC2244] Newman, C. and J. Myers, "ACAP -- Application
- Configuration Access Protocol", RFC 2244, November 1997.
-
- [RFC4510] Zeilenga, K., "Lightweight Directory Access Protocol
- (LDAP): Technical Specification Road Map", RFC 4510,
- June 2006.
-
-Author's Address
-
- Cyrus Daboo
- Apple, Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
-
-
-
-Daboo Standards Track [Page 48]
-
diff --git a/doc/rfc6638-scheduling-extensions-to-caldav.txt b/doc/rfc6638-scheduling-extensions-to-caldav.txt
deleted file mode 100644
index 39154d8a..00000000
--- a/doc/rfc6638-scheduling-extensions-to-caldav.txt
+++ /dev/null
@@ -1,4371 +0,0 @@
-
-
-
-
-
-
-Internet Engineering Task Force (IETF) C. Daboo
-Request for Comments: 6638 Apple Inc.
-Updates: 4791, 5546 B. Desruisseaux
-Category: Standards Track Oracle
-ISSN: 2070-1721 June 2012
-
-
- Scheduling Extensions to CalDAV
-
-Abstract
-
- This document defines extensions to the Calendaring Extensions to
- WebDAV (CalDAV) "calendar-access" feature to specify a standard way
- of performing scheduling operations with iCalendar-based calendar
- components. This document defines the "calendar-auto-schedule"
- feature of CalDAV.
-
-Status of This Memo
-
- This is an Internet Standards Track document.
-
- This document is a product of the Internet Engineering Task Force
- (IETF). It represents the consensus of the IETF community. It has
- received public review and has been approved for publication by the
- Internet Engineering Steering Group (IESG). Further information on
- Internet Standards is available in Section 2 of RFC 5741.
-
- Information about the current status of this document, any errata,
- and how to provide feedback on it may be obtained at
- http://www.rfc-editor.org/info/rfc6638.
-
-Copyright Notice
-
- Copyright (c) 2012 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 Simplified BSD License.
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 1]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- This document may contain material from IETF Documents or IETF
- Contributions published or made publicly available before November
- 10, 2008. The person(s) controlling the copyright in some of this
- material may not have granted the IETF Trust the right to allow
- modifications of such material outside the IETF Standards Process.
- Without obtaining an adequate license from the person(s) controlling
- the copyright in such materials, this document may not be modified
- outside the IETF Standards Process, and derivative works of it may
- not be created outside the IETF Standards Process, except to format
- it for publication as an RFC or to translate it into languages other
- than English.
-
-Table of Contents
-
- 1. Introduction ....................................................5
- 1.1. Terminology ................................................6
- 1.2. Notational Conventions .....................................7
- 1.3. XML Namespaces and Processing ..............................7
- 2. Scheduling Support ..............................................8
- 2.1. Scheduling Outbox Collection ...............................9
- 2.1.1. CALDAV:schedule-outbox-URL Property ................10
- 2.2. Scheduling Inbox Collection ...............................10
- 2.2.1. CALDAV:schedule-inbox-URL Property .................11
- 2.3. Calendaring Reports Extensions ............................12
- 2.4. Additional Principal Properties ...........................12
- 2.4.1. CALDAV:calendar-user-address-set Property ..........12
- 2.4.2. CALDAV:calendar-user-type Property .................13
- 3. Scheduling Operations ..........................................14
- 3.1. Identifying Scheduling Object Resources ...................14
- 3.2. Handling Scheduling Object Resources ......................15
- 3.2.1. Organizer Scheduling Object Resources ..............15
- 3.2.1.1. Create ....................................16
- 3.2.1.2. Modify ....................................17
- 3.2.1.3. Remove ....................................18
- 3.2.2. Attendee Scheduling Object Resources ...............18
- 3.2.2.1. Allowed "Attendee" Changes ................18
- 3.2.2.2. Create ....................................19
- 3.2.2.3. Modify ....................................20
- 3.2.2.4. Remove ....................................21
- 3.2.3. HTTP Methods .......................................21
- 3.2.3.1. PUT .......................................22
- 3.2.3.2. DELETE ....................................22
- 3.2.3.3. COPY ......................................23
- 3.2.3.4. MOVE ......................................24
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 2]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- 3.2.4. Additional Method Preconditions ....................24
- 3.2.4.1. CALDAV:unique-scheduling-object-resource
- Precondition ..............................24
- 3.2.4.2. CALDAV:same-organizer-in-all-components
- Precondition ..............................25
- 3.2.4.3. CALDAV:allowed-organizer-scheduling-
- object-change Precondition .............25
- 3.2.4.4. CALDAV:allowed-attendee-scheduling-
- object-change Precondition .............26
- 3.2.5. DTSTAMP and SEQUENCE Properties ....................26
- 3.2.6. Restrict Recurrence Instances Sent to "Attendees" ..27
- 3.2.7. Forcing the Server to Send a Scheduling Message ....27
- 3.2.8. "Attendee" Participation Status ....................28
- 3.2.9. Schedule Status Values .............................29
- 3.2.10. Avoiding Conflicts when Updating Scheduling Object
- Resources .........................................31
- 3.2.10.1. PUT .....................................33
- 3.2.10.2. DELETE, COPY, or MOVE ...................33
- 4. Processing Incoming Scheduling Messages ........................34
- 4.1. Processing "Organizer" Requests, Additions, and
- Cancellations .............................................34
- 4.2. Processing "Attendee" Replies .............................35
- 4.3. Default Calendar Collection ...............................35
- 4.3.1. Additional Method Preconditions ....................36
- 4.3.1.1. CALDAV:default-calendar-needed
- Precondition ..............................36
- 4.3.1.2. CALDAV:valid-schedule-default-calendar-URL
- Precondition ..............................36
- 5. Request for Busy Time Information ..............................37
- 5.1. Status Codes ..............................................38
- 5.2. Additional Method Preconditions ...........................38
- 5.2.1. CALDAV:valid-scheduling-message Precondition .......38
- 5.2.2. CALDAV:valid-organizer Precondition ................39
- 6. Scheduling Privileges ..........................................39
- 6.1. Privileges on Scheduling Inbox Collections ................39
- 6.1.1. CALDAV:schedule-deliver Privilege ..................40
- 6.1.2. CALDAV:schedule-deliver-invite Privilege ...........40
- 6.1.3. CALDAV:schedule-deliver-reply Privilege ............40
- 6.1.4. CALDAV:schedule-query-freebusy Privilege ...........40
- 6.2. Privileges on Scheduling Outbox Collections ...............40
- 6.2.1. CALDAV:schedule-send Privilege .....................41
- 6.2.2. CALDAV:schedule-send-invite Privilege ..............41
- 6.2.3. CALDAV:schedule-send-reply Privilege ...............41
- 6.2.4. CALDAV:schedule-send-freebusy Privilege ............41
- 6.3. Aggregation of Scheduling Privileges ......................42
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 3]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- 7. Additional iCalendar Property Parameters .......................42
- 7.1. Schedule Agent Parameter ..................................42
- 7.2. Schedule Force Send Parameter .............................44
- 7.3. Schedule Status Parameter .................................45
- 8. Additional Message Header Fields ...............................46
- 8.1. Schedule-Reply Request Header .............................46
- 8.2. Schedule-Tag Response Header ..............................46
- 8.3. If-Schedule-Tag-Match Request Header ......................47
- 9. Additional WebDAV Properties ...................................47
- 9.1. CALDAV:schedule-calendar-transp Property ..................47
- 9.2. CALDAV:schedule-default-calendar-URL Property .............48
- 9.3. CALDAV:schedule-tag Property ..............................49
- 10. XML Element Definitions .......................................50
- 10.1. CALDAV:schedule-response XML Element .....................50
- 10.2. CALDAV:response XML Element ..............................50
- 10.3. CALDAV:recipient XML Element .............................50
- 10.4. CALDAV:request-status XML Element ........................51
- 11. Security Considerations .......................................51
- 11.1. Preventing Denial-of-Service Attacks .....................51
- 11.2. Verifying Scheduling Operations ..........................52
- 11.3. Verifying Busy Time Information Requests .................52
- 11.4. Privacy Issues ...........................................53
- 11.5. Mitigation of iTIP Threats ...............................53
- 12. IANA Considerations ...........................................54
- 12.1. Message Header Field Registrations .......................54
- 12.1.1. Schedule-Reply ....................................54
- 12.1.2. Schedule-Tag ......................................54
- 12.1.3. If-Schedule-Tag-Match .............................54
- 12.2. iCalendar Property Parameter Registrations ...............55
- 12.3. iCalendar REQUEST-STATUS Value Registrations .............55
- 12.4. Additional iCalendar Elements Registries .................55
- 12.4.1. Schedule Agent Values Registry ....................56
- 12.4.2. Schedule Force Send Values Registry ...............56
- 13. Acknowledgements ..............................................56
- 14. References ....................................................57
- 14.1. Normative References .....................................57
- 14.2. Informative References ...................................58
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 4]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Appendix A. Scheduling Privileges Summary .........................59
- A.1. Scheduling Inbox Privileges ................................59
- A.2. Scheduling Outbox Privileges ...............................60
- Appendix B. Example Scheduling Operations .........................60
- B.1. Example: "Organizer" Inviting Multiple "Attendees" .........61
- B.2. Example: "Attendee" Receiving an Invitation ................63
- B.3. Example: "Attendee" Replying to an Invitation ..............64
- B.4. Example: "Organizer" Receiving a Reply to an Invitation ....66
- B.5. Example: "Organizer" Requesting Busy Time Information ......69
- B.6. Example: User Attempting to Invite "Attendee" on
- Behalf of "Organizer" ......................................71
- B.7. Example: "Attendee" Declining an Instance of a
- Recurring Event ............................................72
- B.8. Example: "Attendee" Removing an Instance of a
- Recurring Event ............................................75
-
-1. Introduction
-
- This document specifies extensions to the CalDAV "calendar-access"
- [RFC4791] feature to enable scheduling of iCalendar-based [RFC5545]
- calendar components between calendar users.
-
- This extension leverages the scheduling methods defined in the
- iCalendar Transport-independent Interoperability Protocol (iTIP)
- [RFC5546] to permit calendar users to perform scheduling operations
- such as schedule, reschedule, respond to scheduling request, or
- cancel calendar components, as well as search for busy time
- information. However, the following iTIP [RFC5546] features are not
- covered: publishing, countering, delegating, refreshing, and
- forwarding calendar components, as well as replacing the "Organizer"
- of a calendar component. It is expected that future extensions will
- be developed to address these.
-
- This specification defines a client/server scheduling protocol, where
- the server is made responsible for sending scheduling messages and
- processing incoming scheduling messages. The client operations of
- creating, modifying, or deleting a calendar component in a calendar
- are enough to trigger the server to deliver the necessary scheduling
- messages to the appropriate calendar users. This approach is
- sometimes referred to as "implicit scheduling".
-
- This specification only addresses how scheduling occurs with users on
- a single system (i.e., scheduling between CalDAV servers, or some
- other calendaring and scheduling system, is not defined). However,
- this specification is compatible with servers being able to send or
- receive scheduling messages with "external" users (e.g., using the
- iCalendar Message-Based Interoperability Protocol (iMIP) [RFC6047]).
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 5]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Section 3 defines the automated "Scheduling Operations" that allow a
- client to store iCalendar data on a CalDAV server, with the server
- taking specific actions in response. One of three scheduling
- operations can take place -- "create", "modify", or "remove", based
- on the HTTP method used for the request -- in addition to a
- comparison between any existing and any new iCalendar data.
-
- Section 4 defines how the server processes scheduling messages sent
- as the result of a scheduling operation.
-
- Section 5 defines how freebusy requests with an immediate response
- are accomplished.
-
- Section 6 defines access control privileges for the scheduling
- operations defined in this specification.
-
- For the majority of the following discussion, scheduling of events
- will be discussed. However, scheduling of to-dos is also fully
- supported by this specification.
-
- This specification has been under development for a number of years,
- and most current implementations of CalDAV support it. With the
- publication of this document, it is expected that all new CalDAV
- implementations will support it by default. Interoperability tests
- have been performed regularly. Significant issues with incompatible
- CalDAV implementations are not anticipated.
-
-1.1. Terminology
-
- This specification reuses much of the same terminology as iCalendar
- [RFC5545], iTIP [RFC5546], WebDAV [RFC4918], and CalDAV [RFC4791].
- Additional terms used by this specification are as follows:
-
- Scheduling object resource: A calendar object resource contained in
- a calendar collection for which the server will take care of
- sending scheduling messages on behalf of the owner of the calendar
- collection.
-
- Organizer scheduling object resource: A scheduling object resource
- owned by the "Organizer".
-
- Attendee scheduling object resource: A scheduling object resource
- owned by an "Attendee".
-
- Scheduling operation: Add, change, or remove operations on a
- scheduling object resource for which the server will deliver
- scheduling messages to other calendar users.
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 6]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Scheduling message: A calendar object that describes a scheduling
- operation such as schedule, reschedule, reply, or cancel.
-
- Scheduling Outbox collection: A resource at which busy time
- information requests are targeted.
-
- Scheduling Inbox collection: A collection in which incoming
- scheduling messages are delivered.
-
-1.2. Notational Conventions
-
- 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].
-
- The Augmented BNF (ABNF) syntax used by this document to specify the
- format definition of new iCalendar elements is defined in [RFC5234].
-
- The ABNF syntax used by this document to specify the format
- definition of new message header fields to be used with the HTTP/1.1
- protocol is described in Section 2.1 of [RFC2616]. Since this
- Augmented BNF uses the basic production rules provided in Section 2.2
- of [RFC2616], these rules apply to this document as well.
-
- The term "protected" is used in the Conformance field of WebDAV
- property definitions as defined in Section 15 of [RFC4918].
-
- Calendaring and scheduling roles are referred to in quoted-strings of
- text with the first character of each word in uppercase. For
- example, "Organizer" refers to a role of a calendar user within the
- scheduling protocol defined by [RFC5546].
-
-1.3. XML Namespaces and Processing
-
- This document uses XML DTD fragments ([W3C.REC-xml-20081126],
- Section 3.2) as a purely notational convention. WebDAV request and
- response bodies cannot be validated by a DTD due to the specific
- extensibility rules defined in Section 17 of [RFC4918] and due to the
- fact that all XML elements defined by that specification use the XML
- namespace name "DAV:". In particular,
-
- 1. element names use the "DAV:" namespace,
-
- 2. element ordering is irrelevant unless explicitly stated,
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 7]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- 3. extension elements (elements not already defined as valid child
- elements) can be added anywhere, except when explicitly stated
- otherwise, and
-
- 4. extension attributes (attributes not already defined as valid for
- this element) can be added anywhere, except when explicitly
- stated otherwise.
-
- The XML elements specified in this document are defined in the
- "urn:ietf:params:xml:ns:caldav" XML namespace registered by CalDAV
- [RFC4791].
-
- 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 strings "DAV:" and
- "CALDAV:" will be prefixed to the element types, respectively.
-
- This document inherits, and sometimes extends, DTD productions from
- Section 14 of [RFC4918].
-
- Also note that some CalDAV XML element names are identical to WebDAV
- XML element names, though their namespace differs. Care needs to be
- taken not to confuse the two sets of names.
-
-2. Scheduling Support
-
- A server that supports the features described in this document is
- REQUIRED to support the CalDAV "calendar-access" [RFC4791] feature.
- Servers include "calendar-auto-schedule" as a field in the DAV
- response header from an OPTIONS request on any resource that supports
- any scheduling operations, properties, privileges, or methods.
-
- This specification introduces new collection resource types that are
- used to manage scheduling object resources, and scheduling privileges
- (as per Section 6), as well as provide scheduling functionality. It
- is the server's responsibility to create these collection resources,
- and clients have no way to create or delete them.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 8]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-2.1. Scheduling Outbox Collection
-
- A scheduling Outbox collection is used as the target for busy time
- information requests, and to manage privileges that apply to outgoing
- scheduling requests.
-
- A scheduling Outbox collection MUST report the DAV:collection and
- CALDAV:schedule-outbox XML elements in the value of the DAV:
- resourcetype property. The element type declaration for CALDAV:
- schedule-outbox is
-
-
-
- Example:
-
-
-
-
-
-
- A scheduling Outbox collection MUST NOT be a child (at any depth) of
- a calendar collection resource.
-
- The following WebDAV properties specified in CalDAV "calendar-access"
- [RFC4791] MAY also be defined on scheduling Outbox collections and
- apply to scheduling messages submitted to the scheduling Outbox
- collection with the POST method:
-
- o CALDAV:supported-calendar-component-set
-
- o CALDAV:supported-calendar-data
-
- o CALDAV:max-resource-size
-
- o CALDAV:min-date-time
-
- o CALDAV:max-date-time
-
- o CALDAV:max-attendees-per-instance
-
- The use of child resources in a scheduling Outbox collection is
- reserved for future revisions or extensions of this specification.
-
- The following WebDAV property is defined on principal resources and
- used to locate the corresponding Outbox collection for the associated
- principal.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 9]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-2.1.1. CALDAV:schedule-outbox-URL Property
-
- Name: schedule-outbox-URL
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identify the URL of the scheduling Outbox collection owned
- by the associated principal resource.
-
- Protected: This property MAY be protected.
-
- PROPFIND behavior: This property SHOULD NOT be returned by a
- PROPFIND DAV: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 scheduling Outbox collection of the current user is located so
- that sending of scheduling messages can occur. If not present,
- then the associated calendar user is not enabled for the sending
- of scheduling messages on the server.
-
- Definition:
-
-
-
-2.2. Scheduling Inbox Collection
-
- A scheduling Inbox collection contains copies of incoming scheduling
- messages. These can be requests sent by an "Organizer", or replies
- sent by an "Attendee" in response to a request. The scheduling Inbox
- collection is also used to manage scheduling privileges.
-
- A scheduling Inbox collection MUST report the DAV:collection and
- CALDAV:schedule-inbox XML elements in the value of the DAV:
- resourcetype property. The element type declaration for CALDAV:
- schedule-inbox is
-
-
-
- Example:
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 10]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Scheduling Inbox collections MUST only contain calendar object
- resources that obey the restrictions specified in iTIP [RFC5546].
- Consequently, scheduling Inbox collections MUST NOT contain any types
- of collection resources. Restrictions defined in Section 4.1 of
- CalDAV "calendar-access" [RFC4791] on calendar object resources
- contained in calendar collections (e.g., Unique Identifier ("UID")
- uniqueness) do not apply to calendar object resources contained in a
- scheduling Inbox collection. Thus, multiple calendar object
- resources contained in a scheduling Inbox collection can have the
- same "UID" property value (i.e., multiple scheduling messages for the
- same calendar component).
-
- A scheduling Inbox collection MUST NOT be a child (at any depth) of a
- calendar collection resource.
-
- The following WebDAV properties specified in CalDAV "calendar-access"
- [RFC4791] MAY also be defined on scheduling Inbox collections and
- apply to scheduling messages delivered to the collection:
-
- o CALDAV:supported-calendar-component-set
-
- o CALDAV:supported-calendar-data
-
- o CALDAV:max-resource-size
-
- o CALDAV:min-date-time
-
- o CALDAV:max-date-time
-
- o CALDAV:max-instances
-
- o CALDAV:max-attendees-per-instance
-
- o CALDAV:calendar-timezone
-
- The following WebDAV property is defined on principal resources and
- used to locate the corresponding Inbox collection for the associated
- principal.
-
-2.2.1. CALDAV:schedule-inbox-URL Property
-
- Name: schedule-inbox-URL
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identify the URL of the scheduling Inbox collection owned
- by the associated principal resource.
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 11]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Protected: This property MAY be protected.
-
- PROPFIND behavior: This property SHOULD NOT be returned by a
- PROPFIND DAV: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 allows a client to determine where the
- scheduling Inbox collection of the current user is located so that
- processing of scheduling messages can occur. If not present, then
- the associated calendar user is not enabled for reception of
- scheduling messages on the server.
-
- Definition:
-
-
-
-2.3. Calendaring Reports Extensions
-
- This specification extends the CALDAV:calendar-query and CALDAV:
- calendar-multiget REPORTs to return results for calendar object
- resources in scheduling Inbox collections.
-
- When a CALDAV:calendar-query REPORT includes a time-range query and
- targets a scheduling Inbox collection, if any calendar object
- resources contain "VEVENT" calendar components that do not include a
- "DTSTART" iCalendar property (as allowed by iTIP [RFC5546]) then such
- components MUST always match the time-range query test.
-
- Note that the CALDAV:free-busy-query REPORT is not supported on
- scheduling Inbox collections.
-
-2.4. Additional Principal Properties
-
- This section defines new properties for WebDAV principal resources as
- defined in [RFC3744]. These properties are likely to be protected,
- but the server MAY allow them to be written by appropriate users.
-
-2.4.1. CALDAV:calendar-user-address-set Property
-
- Name: calendar-user-address-set
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identify the calendar addresses of the associated principal
- resource.
-
-
-
-Daboo & Desruisseaux Standards Track [Page 12]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Protected: This property MAY be protected.
-
- PROPFIND behavior: This property SHOULD NOT be returned by a
- PROPFIND DAV: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: Support for this property is REQUIRED. This property
- is needed to map calendar user addresses in iCalendar data to
- principal resources and their associated scheduling Inbox and
- Outbox collections. In the event that a user has no well-defined
- identifier for his calendar user address, the URI of his principal
- resource can be used. This property SHOULD be searchable using
- the DAV:principal-property-search REPORT. The DAV:principal-
- search-property-set REPORT SHOULD identify this property as such.
- If not present, then the associated calendar user is not enabled
- for scheduling on the server.
-
- Definition:
-
-
-
- Example:
-
-
- mailto:bernard@example.com
- mailto:bernard.desruisseaux@example.com
-
-
-2.4.2. CALDAV:calendar-user-type Property
-
- Name: calendar-user-type
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Identifies the calendar user type of the associated
- principal resource.
-
- Value: Same values allowed for the iCalendar "CUTYPE" property
- parameter defined in Section 3.2.3 of [RFC5545].
-
- Protected: This property MAY be protected.
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 13]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- PROPFIND behavior: This property SHOULD NOT be returned by a
- PROPFIND DAV: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: Clients can query principal resources in order to look
- up "Attendees" available on the server. When doing this, it is
- useful to know, or restrict the query to, certain types of
- calendar users (e.g., only search for "people", or only search for
- "rooms"). This property MAY be defined on principal resources to
- indicate the type of calendar user associated with the principal
- resource. Its value is the same as the iCalendar "CUTYPE"
- property parameter that can be used on "ATTENDEE" properties.
- This property SHOULD be searchable using the DAV:principal-
- property-search REPORT. The DAV:principal-search-property-set
- REPORT SHOULD identify this property as such.
-
- Definition:
-
-
-
- Example:
-
- INDIVIDUAL<
- /C:calendar-user-type>
-
-3. Scheduling Operations
-
- When a calendar object resource is created, modified, or removed from
- a calendar collection, the server examines the calendar data and
- checks to see whether the data represents a scheduling object
- resource. If it does, the server will automatically attempt to
- deliver a scheduling message to the appropriate calendar users.
- Several types of scheduling operations can occur in this case,
- equivalent to iTIP "REQUEST", "REPLY", "CANCEL", and "ADD"
- operations.
-
-3.1. Identifying Scheduling Object Resources
-
- Calendar object resources on which the server performs scheduling
- operations are referred to as scheduling object resources. There are
- two types of scheduling object resources: organizer scheduling object
- resources, and attendee scheduling object resources.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 14]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- A calendar object resource is considered to be a valid organizer
- scheduling object resource if the "ORGANIZER" iCalendar property is
- present and set in all the calendar components to a value that
- matches one of the calendar user addresses of the owner of the
- calendar collection.
-
- A calendar object resource is considered to be a valid attendee
- scheduling object resource if the "ORGANIZER" iCalendar property is
- present and set in all the calendar components to the same value and
- doesn't match one of the calendar user addresses of the owner of the
- calendar collection, and if at least one of the "ATTENDEE" iCalendar
- property values matches one of the calendar user addresses of the
- owner of the calendar collection.
-
- The creation of attendee scheduling object resources is typically
- done by the server, with the resource being created in an appropriate
- calendar collection (see Section 4.3).
-
-3.2. Handling Scheduling Object Resources
-
- The server's behavior when processing a scheduling object resource
- depends on whether it is owned by the "Organizer" or an "Attendee"
- specified in the calendar data.
-
-3.2.1. Organizer Scheduling Object Resources
-
- An "Organizer" can create, modify, or remove a scheduling object
- resource, subject to access privileges, preconditions, and the
- restrictions defined in Section 4.1 of [RFC4791]. These operations
- are each described next, and how they are invoked via HTTP requests
- is described in Section 3.2.3.
-
- The "Organizer" of a calendar component can also be an "Attendee" of
- that calendar component. In such cases, the server MUST NOT send a
- scheduling message to the "Attendee" that matches the "Organizer".
-
- The server SHOULD reject any attempt to set the "PARTSTAT" iCalendar
- property parameter value of the "ATTENDEE" iCalendar property of
- other users in the calendar object resource to a value other than
- "NEEDS-ACTION" if the "SCHEDULE-AGENT" property parameter value is
- not present or set to the value "SERVER".
-
- The server MAY reject attempts to create a scheduling object resource
- that specifies a "UID" property value already specified in a
- scheduling object resource contained in another calendar collection
- of the "Organizer".
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 15]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.1.1. Create
-
- When an "Organizer" creates a scheduling object resource, the server
- MUST inspect each "ATTENDEE" property to determine whether to send a
- scheduling message. The table below indicates the appropriate iTIP
- method used by the server, taking into account any "SCHEDULE-AGENT"
- property parameter (see Section 7.1) specified on each "ATTENDEE"
- property.
-
- +------------------+-------------+
- | SCHEDULE-AGENT | iTIP METHOD |
- +------------------+-------------+
- | SERVER (default) | REQUEST |
- | | |
- | CLIENT | -- |
- | | |
- | NONE | -- |
- +------------------+-------------+
-
- "SCHEDULE-STATUS" iCalendar property parameters are added or changed
- on "ATTENDEE" iCalendar properties in the scheduling object resource
- being created as described in Section 7.3, with the value set as
- described in Section 3.2.9. This will result in the created calendar
- object resource differing from the calendar data sent in the HTTP
- request. As a result, clients MAY reload the calendar data from the
- server in order to update to the new server-generated state
- information.
-
- The server MUST add a "SCHEDULE-STATUS" iCalendar property parameter
- (see Section 7.3) to the "ATTENDEE" iCalendar property in the
- scheduling object resource being created, and set its value as
- described in Section 3.2.9. This will result in the created calendar
- object resource differing from the calendar data sent in the HTTP
- request. As a result, clients MAY reload the calendar data from the
- server in order to update to the new server-generated state
- information. Servers MUST NOT set the "SCHEDULE-STATUS" property
- parameter on the "ATTENDEE" property of "Attendees" for which it did
- not attempt to deliver a scheduling message.
-
- The server MUST return an error with the CALDAV:allowed-organizer-
- scheduling-object-change precondition code (Section 3.2.4.3) when the
- "Organizer" attempts to change the iCalendar data in a manner that is
- forbidden.
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 16]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.1.2. Modify
-
- When an "Organizer" modifies a scheduling object resource, the server
- MUST inspect each "ATTENDEE" property in both the original and
- modified iCalendar data on a per-instance basis to determine whether
- to send a scheduling message. The table below indicates the
- appropriate iTIP method used by the server, taking into account any
- "SCHEDULE-AGENT" property parameter (see Section 7.1) specified on
- each "ATTENDEE" property. The values "SERVER", "CLIENT", and "NONE"
- in the top and left titles of the table refer to the "SCHEDULE-AGENT"
- parameter value of the "ATTENDEE" property, and the values ""
- and "" are used to cover the cases where the "ATTENDEE"
- property is not present (Original) or is being removed (Modified).
-
- +---------------+-----------------------------------------------+
- | | Modified |
- | +-----------+-----------+-----------+-----------+
- | | | SERVER | CLIENT | NONE |
- | | | (default) | | |
- +===+===========+===========+===========+===========+===========+
- | | | -- | REQUEST / | -- | -- |
- | O | | | ADD | | |
- | r +-----------+-----------+-----------+-----------+-----------+
- | i | SERVER | CANCEL | REQUEST | CANCEL | CANCEL |
- | g | (default) | | | | |
- | i +-----------+-----------+-----------+-----------+-----------+
- | n | CLIENT | -- | REQUEST / | -- | -- |
- | a | | | ADD | | |
- | l +-----------+-----------+-----------+-----------+-----------+
- | | NONE | -- | REQUEST / | -- | -- |
- | | | | ADD | | |
- +---+-----------+-----------+-----------+-----------+-----------+
-
- "SCHEDULE-STATUS" iCalendar property parameters are added or changed
- on "ATTENDEE" iCalendar properties in the scheduling object resource
- being modified as described in Section 7.3, with the value set as
- described in Section 3.2.9. This will result in the created calendar
- object resource differing from the calendar data sent in the HTTP
- request. As a result, clients MAY reload the calendar data from the
- server in order to update to the new server-generated state
- information.
-
- The server MUST return an error with the CALDAV:allowed-organizer-
- scheduling-object-change precondition code (Section 3.2.4.3) when the
- "Organizer" attempts to change the iCalendar data in a manner that is
- forbidden.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 17]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.1.3. Remove
-
- When an "Organizer" removes a scheduling object resource, the server
- MUST inspect each "ATTENDEE" property to determine whether to send a
- scheduling message. The table below indicates the appropriate iTIP
- method used by the server, taking into account any "SCHEDULE-AGENT"
- property parameter (see Section 7.1) specified on each "ATTENDEE"
- property.
-
- +------------------+-------------+
- | SCHEDULE-AGENT | iTIP METHOD |
- +------------------+-------------+
- | SERVER (default) | CANCEL |
- | | |
- | CLIENT | -- |
- | | |
- | NONE | -- |
- +------------------+-------------+
-
-3.2.2. Attendee Scheduling Object Resources
-
- An "Attendee" can create, modify, or remove a scheduling object
- resource. These operations are each described next, and how they are
- invoked via HTTP requests is described in Section 3.2.3.
-
-3.2.2.1. Allowed "Attendee" Changes
-
- "Attendees" are allowed to make some changes to a scheduling object
- resource, though key properties such as start time, end time,
- location, and summary are typically under the control of the
- "Organizer".
-
- Servers MUST allow "Attendees" to make the following iCalendar data
- changes, subject to other restrictions, such as access privileges and
- preconditions:
-
- 1. change their own "PARTSTAT" iCalendar property parameter value.
-
- 2. add, modify, or remove any "TRANSP" iCalendar properties.
-
- 3. add, modify, or remove any "PERCENT-COMPLETE" iCalendar
- properties.
-
- 4. add, modify, or remove any "COMPLETED" iCalendar properties.
-
- 5. add, modify, or remove any "VALARM" iCalendar components.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 18]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- 6. add, modify, or remove the "CALSCALE" iCalendar property within
- the top-level "VCALENDAR" component.
-
- 7. modify the "PRODID" iCalendar property within the top-level
- "VCALENDAR" component.
-
- 8. add "EXDATE" iCalendar properties and possibly remove components
- for overridden recurrence instances.
-
- 9. add, modify, or remove any "CREATED", "DTSTAMP", and
- "LAST-MODIFIED" iCalendar properties.
-
- 10. add, modify, or remove "SCHEDULE-STATUS" iCalendar property
- parameters on "ATTENDEE" properties that have a "SCHEDULE-AGENT"
- parameter set to "CLIENT".
-
- 11. add new components to represent overridden recurrence instances,
- provided the only changes to the recurrence instance follow the
- rules above.
-
- The server MUST return an error with the CALDAV:allowed-attendee-
- scheduling-object-change precondition code (Section 3.2.4.4) when the
- "Attendee" attempts to change the iCalendar data in a manner
- forbidden by the server.
-
-3.2.2.2. Create
-
- Typically, an "Attendee" does not create scheduling object resources,
- as scheduling messages delivered to him on the server are
- automatically processed by the server and placed on one of his
- calendars (see Section 4). However, in some cases, a scheduling
- message can get delivered directly to the client (e.g., via email
- [RFC6047]), and the "Attendee" might wish to store that on the
- server. In that case, the client creates a scheduling object
- resource in a calendar belonging to the "Attendee". It can then set
- the "SCHEDULE-AGENT" iCalendar property parameter on all "ORGANIZER"
- iCalendar properties in the resource to determine how the server
- treats the resource. The value of the "SCHEDULE-AGENT" iCalendar
- property parameter on all "ORGANIZER" iCalendar properties MUST be
- the same.
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 19]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- +----------------+--------------------------------------------------+
- | SCHEDULE-AGENT | Action |
- +----------------+--------------------------------------------------+
- | SERVER | The server will attempt to process changes to |
- | (default) | the resource using the normal rules for attendee |
- | | scheduling object resources. |
- | | |
- | CLIENT | The server does no special processing of the |
- | | resource. The client is assumed to be handling |
- | | "Attendee" replies, etc. |
- | | |
- | NONE | The server does no special processing of the |
- | | resource. |
- +----------------+--------------------------------------------------+
-
- "SCHEDULE-STATUS" iCalendar property parameters are added or changed
- on "ORGANIZER" iCalendar properties in the scheduling object resource
- being created as described in Section 7.3, with the value set as
- described in Section 3.2.9.
-
-3.2.2.3. Modify
-
- When a scheduling object resource is modified by an "Attendee", the
- server's behavior depends on the value of the "SCHEDULE-AGENT"
- iCalendar property parameter on the "ORGANIZER" iCalendar properties:
-
- +----------------+--------------------------------------------------+
- | SCHEDULE-AGENT | Action |
- +----------------+--------------------------------------------------+
- | SERVER | The server will attempt to process the update |
- | (default) | using the behavior listed below. |
- | | |
- | CLIENT | The server does no special processing of the |
- | | resource. The client is assumed to be handling |
- | | any "Attendee" replies, etc. |
- | | |
- | NONE | The server does no special processing of the |
- | | resource. |
- +----------------+--------------------------------------------------+
-
- The server will inspect the changes by comparing the new scheduling
- object resource with the existing scheduling object resource.
-
- If the "Attendee" changes one or more "PARTSTAT" iCalendar property
- values on any component, or adds an overridden component with a
- changed "PARTSTAT" property, then the server MUST deliver an iTIP
- "REPLY" scheduling message to the "Organizer" to indicate the new
- participation status of the "Attendee".
-
-
-
-Daboo & Desruisseaux Standards Track [Page 20]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- If the "Attendee" adds an "EXDATE" property value to effectively
- remove a recurrence instance, the server MUST deliver an iTIP "REPLY"
- scheduling message to the "Organizer" to indicate that the "Attendee"
- has declined the instance.
-
- "SCHEDULE-STATUS" iCalendar property parameters are added or changed
- on "ORGANIZER" iCalendar properties in the scheduling object resource
- being modified as described in Section 7.3, with the value set as
- described in Section 3.2.9. This will result in the updated calendar
- object resource differing from the calendar data sent in the HTTP
- request. As a result, clients MAY reload the calendar data from the
- server in order to update to the new server-generated state
- information.
-
-3.2.2.4. Remove
-
- When a scheduling object resource is removed by an "Attendee", the
- server's behavior depends on the value of the "SCHEDULE-AGENT"
- iCalendar property parameter on the "ORGANIZER" iCalendar properties:
-
- +----------------+--------------------------------------------------+
- | SCHEDULE-AGENT | Action |
- +----------------+--------------------------------------------------+
- | SERVER | The server will attempt to process the removal, |
- | (default) | taking into account any "Schedule-Reply" request |
- | | header as per Section 8.1. |
- | | |
- | CLIENT | The server does no special processing of the |
- | | resource. The client is assumed to be handling |
- | | any "Attendee" replies, etc. |
- | | |
- | NONE | The server does no special processing of the |
- | | resource. |
- +----------------+--------------------------------------------------+
-
-3.2.3. HTTP Methods
-
- This section describes how the use of various HTTP [RFC2616] and
- WebDAV [RFC4918] methods on a scheduling object resource will cause a
- create, modify, or remove operation on that resource as described
- above. The use of these methods is subject to the restrictions in
- [RFC4791], in addition to what is described below.
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 21]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.3.1. PUT
-
- When the server receives a PUT method request, it MUST execute the
- following operations, provided all appropriate preconditions are met:
-
- +------------------------+--------------------------+---------------+
- | Existing Destination | Resulting Destination | Server |
- | Resource | Resource | Operation |
- +------------------------+--------------------------+---------------+
- | None | Calendar object resource | None |
- | | | |
- | None | Scheduling object | Create |
- | | resource | |
- | | | |
- | Calendar object | Calendar object resource | None |
- | resource | | |
- | | | |
- | Calendar object | Scheduling object | Create |
- | resource | resource | |
- | Scheduling object | Calendar object resource | Remove |
- | resource | | |
- | | | |
- | Scheduling object | Scheduling object | Modify |
- | resource | resource | |
- +------------------------+--------------------------+---------------+
-
-3.2.3.2. DELETE
-
- When the server receives a DELETE method request targeted at a
- scheduling object resource, it MUST execute the Remove operation.
-
- When the server receives a DELETE method request targeted at a
- calendar collection, it MUST execute the Remove operation on all
- scheduling object resources contained in the calendar collection.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 22]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.3.3. COPY
-
- When the server receives a COPY method request, it MUST execute the
- following operations based on the source and destination collections
- in the request:
-
- +-----------------------+------------------------+------------------+
- | Source Collection | Destination Collection | Server Operation |
- +-----------------------+------------------------+------------------+
- | Non-calendar | Non-calendar | None |
- | collection | collection | |
- | | | |
- | Non-calendar | Calendar collection | (1) |
- | collection | | |
- | | | |
- | Calendar collection | Non-calendar | None |
- | | collection | |
- | | | |
- | Calendar collection | Calendar collection | (2) |
- +-----------------------+------------------------+------------------+
-
- Note (1): The rules in Section 3.2.3.1 are applied for the
- destination of the COPY request.
-
- Note (2): The server MAY reject this as per Section 3.2.4.1;
- otherwise, None.
-
- The behavior of a COPY method request on a calendar collection is
- undefined.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 23]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.3.4. MOVE
-
- When the server receives a MOVE method request, it MUST execute the
- following operations based on the source and destination collections
- in the request:
-
- +-----------------------+------------------------+------------------+
- | Source Collection | Destination Collection | Server Operation |
- +-----------------------+------------------------+------------------+
- | Non-calendar | Non-calendar | None |
- | collection | collection | |
- | | | |
- | Non-calendar | Calendar collection | (1) |
- | collection | | |
- | | | |
- | Calendar collection | Non-calendar | (2) |
- | | collection | |
- | | | |
- | Calendar collection | Calendar collection | None |
- +-----------------------+------------------------+------------------+
-
- Note (1): The rules in Section 3.2.3.1 are applied for the
- destination of the MOVE request.
-
- Note (2): The rules in Section 3.2.3.2 are applied for the source of
- the MOVE request.
-
- The behavior of a MOVE method request on a calendar collection is
- undefined.
-
-3.2.4. Additional Method Preconditions
-
- This specification defines method preconditions (see Section 16 of
- WebDAV [RFC4918]), in addition to those in [RFC4791], to provide
- machine-parseable information in error responses.
-
-3.2.4.1. CALDAV:unique-scheduling-object-resource Precondition
-
- Name: unique-scheduling-object-resource
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: PUT, COPY, and MOVE
-
- Use with: 403 Forbidden
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 24]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Purpose: (precondition) -- Servers MAY reject requests to create a
- scheduling object resource with an iCalendar "UID" property value
- already in use by another scheduling object resource owned by the
- same user in other calendar collections. Servers SHOULD report
- the URL of the scheduling object resource that is already making
- use of the same "UID" property value in the DAV:href element.
-
- Definition:
-
-
-
- Example:
-
-
- /home/bernard/calendars/personal/abc123.ics
-
-
-3.2.4.2. CALDAV:same-organizer-in-all-components Precondition
-
- Name: same-organizer-in-all-components
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: PUT, COPY, and MOVE
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- All the calendar components in a
- scheduling object resource MUST contain the same "ORGANIZER"
- property value when present.
-
- Definition:
-
-
-
-3.2.4.3. CALDAV:allowed-organizer-scheduling-object-change Precondition
-
- Name: allowed-organizer-scheduling-object-change
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: PUT, COPY, and MOVE
-
- Use with: 403 Forbidden
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 25]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Purpose: (precondition) -- Servers MAY impose restrictions on
- modifications allowed by an "Organizer". For instance, servers
- MAY prevent the "Organizer" from setting the "PARTSTAT" property
- parameter to a value other than "NEEDS-ACTION" if the
- corresponding "ATTENDEE" property has the "SCHEDULE-AGENT"
- property parameter set to "SERVER", or does not have the
- "SCHEDULE-AGENT" property parameter. See Section 3.2.1.
-
- Definition:
-
-
-
-3.2.4.4. CALDAV:allowed-attendee-scheduling-object-change Precondition
-
- Name: allowed-attendee-scheduling-object-change
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: PUT, COPY, and MOVE
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- Servers MAY impose restrictions on
- modifications allowed by an "Attendee", subject to the allowed
- changes specified in Section 3.2.2.1.
-
- Definition:
-
-
-
-3.2.5. DTSTAMP and SEQUENCE Properties
-
- The server MUST ensure that a "DTSTAMP" iCalendar property is present
- and set the value to the UTC time that the scheduling message was
- generated (as required by iCalendar).
-
- The server MUST ensure that for each type of scheduling operation,
- the "SEQUENCE" iCalendar property value is updated as per iTIP
- [RFC5546].
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 26]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.6. Restrict Recurrence Instances Sent to "Attendees"
-
- Servers MUST ensure that "Attendees" only get information about
- recurrence instances that explicitly include them as an "Attendee",
- when delivering scheduling messages for recurring calendar
- components.
-
- For example, if an "Attendee" is invited to only a single instance of
- a recurring event, the organizer scheduling object resource will
- contain an overridden instance in the form of a separate calendar
- component. That separate calendar component will include the
- "ATTENDEE" property referencing the "one-off" "Attendee". That
- "Attendee" will not be listed in any other calendar components in the
- scheduling object resource. Any scheduling messages delivered to the
- "Attendee" will only contain information about this overridden
- instance.
-
- As another example, an "Attendee" could be excluded from one instance
- of a recurring event. In that case, the organizer scheduling object
- resource will include an overridden instance with an "ATTENDEE" list
- that does not include the "Attendee" being excluded. Any scheduling
- messages delivered to the "Attendee" will not specify the overridden
- instance but rather will include an "EXDATE" property in the "master"
- component that defines the recurrence set.
-
-3.2.7. Forcing the Server to Send a Scheduling Message
-
- The iCalendar property parameter "SCHEDULE-FORCE-SEND", defined in
- Section 7.2, can be used by a calendar user to force the server to
- send a scheduling message to an "Attendee" or the "Organizer" in a
- situation where the server would not normally send a scheduling
- message. For instance, an "Organizer" could use this property
- parameter to request an "Attendee" that previously declined an
- invitation to reconsider his participation status without being
- forced to modify the event.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 27]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.8. "Attendee" Participation Status
-
- This section specifies additional requirements on the handling of the
- "PARTSTAT" property parameter when the "SCHEDULE-AGENT" property
- parameter on the corresponding "ATTENDEE" property is set to the
- value "SERVER" or is not present.
-
- A reschedule occurs when any "DTSTART", "DTEND", "DURATION", "DUE",
- "RRULE", "RDATE", or "EXDATE" property changes in a calendar
- component such that existing recurrence instances are impacted by the
- changes, as shown in the table below. Servers MUST reset the
- "PARTSTAT" property parameter value of all "ATTENDEE" properties,
- except the one that corresponds to the "Organizer", to "NEEDS-ACTION"
- for each calendar component change that causes any instance to be
- rescheduled.
-
- +-----------+-------------------------------------------------------+
- | Property | Server Action |
- +-----------+-------------------------------------------------------+
- | DTSTART, | Any change to these properties results in "PARTSTAT" |
- | DTEND, | being set to "NEEDS-ACTION". |
- | DURATION, | |
- | DUE | |
- | | |
- | RRULE | A change to or addition of this property that results |
- | | in the addition of new recurring instances or a |
- | | change in time for existing recurring instances |
- | | results in "PARTSTAT" being reset to "NEEDS-ACTION" |
- | | on each affected component. |
- | | |
- | RDATE | A change to or addition of this property that results |
- | | in the addition of new recurring instances or a |
- | | change in time for existing recurring instances |
- | | results in "PARTSTAT" being reset to "NEEDS-ACTION" |
- | | on each affected component. |
- | | |
- | EXDATE | A change to or removal of this property that results |
- | | in the reinstatement of recurring instances results |
- | | in "PARTSTAT" being set to "NEEDS-ACTION" on each |
- | | affected component. |
- +-----------+-------------------------------------------------------+
-
- The server MAY allow the "Organizer's" client to change an
- "Attendee's" "PARTSTAT" property parameter value to "NEEDS-ACTION" at
- any other time (e.g., when the "LOCATION" property value changes, an
- "Organizer" might wish to re-invite "Attendees" who might be impacted
- by the change).
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 28]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-3.2.9. Schedule Status Values
-
- When scheduling with an "Attendee", there are two types of status
- information that can be returned during the operation. The first
- type of status information is a "delivery" status that indicates
- whether the scheduling message from the "Organizer" to the "Attendee"
- was delivered or not, or what the current status of delivery is. The
- second type of status information is a "reply" status corresponding
- to the "Attendee's" own "REQUEST-STATUS" information from the
- scheduling message reply that is sent back to the "Organizer".
-
- Similarly, when an "Attendee" sends a reply back to the "Organizer",
- there will be "delivery" status information for the scheduling
- message sent to the "Organizer". However, there is no
- "REQUEST-STATUS" sent back by the "Organizer", so there is no
- equivalent of the "reply" status as per scheduling messages to
- "Attendees".
-
- The "delivery" status information on an "ORGANIZER" or "ATTENDEE"
- iCalendar property is conveyed in the "SCHEDULE-STATUS" property
- parameter value (Section 7.3). The status code value for "delivery"
- status can be one of the following:
-
- +----------+--------------------------------------------------------+
- | Delivery | Description |
- | Status | |
- | Code | |
- +----------+--------------------------------------------------------+
- | 1.0 | The scheduling message is pending. That is, the |
- | | server is still in the process of sending the message. |
- | | The status code value can be expected to change once |
- | | the server has completed its sending and delivery |
- | | attempts. |
- | | |
- | 1.1 | The scheduling message has been successfully sent. |
- | | However, the server does not have explicit information |
- | | about whether the scheduling message was successfully |
- | | delivered to the recipient. This state can occur with |
- | | "store and forward" style scheduling protocols such as |
- | | iMIP [RFC6047] (iTIP using email). |
- | | |
- | 1.2 | The scheduling message has been successfully |
- | | delivered. |
- | | |
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 29]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- | 3.7 | The scheduling message was not delivered because the |
- | | server did not recognize the calendar user address as |
- | | a valid calendar user. Note that this code applies to |
- | | both "Organizer" and "Attendee" calendar user |
- | | addresses. |
- | | |
- | 3.8 | The scheduling message was not delivered due to |
- | | insufficient privileges. Note that this code applies |
- | | to privileges granted by both the "Organizer" and |
- | | "Attendee" calendar users. |
- | | |
- | 5.1 | The scheduling message was not delivered because the |
- | | server could not complete delivery of the message. |
- | | This is likely due to a temporary failure, and the |
- | | originator can try to send the message again at a |
- | | later time. |
- | | |
- | 5.2 | The scheduling message was not delivered because the |
- | | server was not able to find a way to deliver the |
- | | message. This is likely a permanent failure, and the |
- | | originator ought not try to send the message again, at |
- | | least without verifying/correcting the calendar user |
- | | address of the recipient. |
- | | |
- | 5.3 | The scheduling message was not delivered and was |
- | | rejected because scheduling with that recipient is not |
- | | allowed. This is likely a permanent failure, and the |
- | | originator ought not try to send the message again. |
- +----------+--------------------------------------------------------+
-
- The status code for "reply" status can be any of the valid iTIP
- [RFC5546] "REQUEST-STATUS" values.
-
- The 1.xx "REQUEST-STATUS" codes are new. This specification modifies
- item (2) of Section 3.6 of [RFC5546] by adding the following
- restriction:
-
- For a 1.xx code, all components MUST have exactly the same code.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 30]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Definition of the new 1.xx codes is as follows:
-
-3.2.9.1. Status Code 1.0
-
- Status Code: 1.0
-
- Status Description: Pending.
-
- Status Exception Data: None.
-
- Description: Delivery of the iTIP message is pending.
-
-3.2.9.2. Status Code 1.1
-
- Status Code: 1.1
-
- Status Description: Sent.
-
- Status Exception Data: None.
-
- Description: The iTIP message has been sent, though no information
- about successful delivery is known.
-
-3.2.9.3. Status Code 1.2
-
- Status Code: 1.2
-
- Status Description: Delivered.
-
- Status Exception Data: None.
-
- Description: The iTIP message has been sent and delivered.
-
-3.2.10. Avoiding Conflicts when Updating Scheduling Object Resources
-
- Scheduling object resources on the server might change frequently as
- "Attendees" change their participation status, triggering updates to
- the "Organizer", and refreshes of other "Attendees'" copies of the
- scheduling object resource. This can lead to an "inconsequential"
- change to a calendar user's data -- one that does not directly impact
- the user's own participation status. When this occurs, clients have
- to reload calendar data and reconcile with changes being made by
- calendar users. To avoid the need for this, the server can instead
- merge calendar data changes from a client with changes made as a
- result of a scheduling operation carried out by some other calendar
- user.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 31]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- This specification introduces a new WebDAV resource property CALDAV:
- schedule-tag with a corresponding response header "Schedule-Tag", and
- a new "If-Schedule-Tag-Match" request header to allow client changes
- to be appropriately merged with server changes in the case where the
- changes on the server were the result of an "inconsequential"
- scheduling message update (one that simply updates the status
- information of "Attendees" due to a reply from another "Attendee").
-
- Servers MUST automatically resolve conflicts with "inconsequential"
- changes done to scheduling object resources when the "If-Schedule-
- Tag-Match" request header is specified. The If-Schedule-Tag-Match
- request header applies only to the Request-URI, and not to the
- destination of a COPY or MOVE.
-
- A response to any successful GET or PUT request targeting a
- scheduling object resource MUST include a Schedule-Tag response
- header with the value set to the same value as the CALDAV:schedule-
- tag WebDAV property of the resource.
-
- A response to any successful COPY or MOVE request that specifies a
- Destination request header targeting a scheduling object resource
- MUST include a Schedule-Tag response header with the value set to the
- same value as the CALDAV:schedule-tag WebDAV property of the
- destination resource.
-
- Clients SHOULD use the If-Schedule-Tag-Match header on requests that
- update scheduling object resources, instead of HTTP ETag-based
- precondition tests (e.g., If-Match). Normal ETag-based precondition
- tests are used in all other cases, e.g., for synchronization.
-
- The value of the CALDAV:schedule-tag property changes according to
- these rules:
-
- o For an "Organizer's" copy of a scheduling object resource:
-
- 1. The server MUST NOT change the CALDAV:schedule-tag property
- value when the scheduling object resource is updated as the
- result of automatically processing a scheduling message reply
- from an "Attendee". For instance, when an "Attendee" replies
- to the "Organizer", the CALDAV:schedule-tag property is
- unchanged after the "Organizer's" scheduling object resource
- has been automatically updated by the server with the
- "Attendee's" new participation status.
-
- 2. The server MUST change the CALDAV:schedule-tag property value
- when the scheduling object resource is changed directly via an
- HTTP request (e.g., PUT, COPY, or MOVE).
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 32]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- o For an "Attendee's" copy of a scheduling object resource:
-
- 1. The server MUST change the CALDAV:schedule-tag property value
- when the scheduling object resource is changed as the result
- of processing a scheduling message update from an "Organizer"
- that contains changes other than just the participation status
- of "Attendees".
-
- 2. The server MUST NOT change the CALDAV:schedule-tag property
- value when the scheduling object resource is changed as the
- result of processing a scheduling message update from an
- "Organizer" that only specifies changes in the participation
- status of "Attendees". For instance, when "Attendee" "A"
- replies to "Organizer" "O", and "Attendee" "B" receives a
- scheduling message update from "Organizer" "O" with the new
- participation status of "Attendee" "A", the CALDAV:schedule-
- tag property of "Attendee" "B"'s scheduling object resource
- would remain the same.
-
- 3. The server MUST change the CALDAV:schedule-tag property value
- when the scheduling object resource is changed directly via an
- HTTP request (e.g., PUT, COPY, or MOVE).
-
-3.2.10.1. PUT
-
- Clients MAY use the If-Schedule-Tag-Match request header to do a PUT
- request that ensures that "inconsequential" changes on the server do
- not result in a precondition error. The value of the request header
- is set to the last Schedule-Tag value received for the resource being
- modified. If the value of the If-Schedule-Tag-Match header matches
- the current value of the CALDAV:schedule-tag property, the server
- MUST take any "ATTENDEE" property changes for all "Attendees" other
- than the owner of the scheduling object resource and apply those to
- the new resource being stored. Otherwise, the server MUST fail the
- request with a 412 Precondition Failed status code.
-
-3.2.10.2. DELETE, COPY, or MOVE
-
- Clients MAY use the If-Schedule-Tag-Match request header to do a
- DELETE, COPY, or MOVE request that ensures that "inconsequential"
- changes on the server do not result in a precondition error. The
- value of the request header is set to the last Schedule-Tag value
- received for the resource being deleted. If the value of the
- If-Schedule-Tag-Match header matches the current value of the CALDAV:
- schedule-tag property, the server performs the normal DELETE, COPY,
- or MOVE request processing for the resource. Otherwise, the server
- MUST fail the request with a 412 Precondition Failed status code.
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 33]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-4. Processing Incoming Scheduling Messages
-
- Scheduling operations can cause the delivery of a scheduling message
- into an "Organizer's" or "Attendee's" scheduling Inbox collection.
- Servers MUST automatically process incoming scheduling messages using
- the rules defined by [RFC5546], by creating or updating the
- corresponding scheduling object resources on calendars owned by the
- owner of the scheduling Inbox collection. In addition, the
- scheduling message is stored in the scheduling Inbox collection as an
- indicator to the client that a scheduling operation has taken place.
- Scheduling messages are typically removed from the scheduling Inbox
- collection by the client once the calendar user has acknowledged the
- change.
-
- The server MUST take into account privileges on the scheduling Inbox
- collection when processing incoming scheduling messages, to determine
- whether delivery of the scheduling message is allowed. Privileges on
- calendars containing any matching scheduling object resource are not
- considered in this case (i.e., a schedule message from another user
- can cause modifications to resources in calendar collections that the
- other user would not normally have read or write access to).
- Additionally, servers MUST take into account any scheduling Inbox
- collection preconditions (see Section 2.2) when delivering the
- scheduling message, and MUST take into account the similar
- preconditions on any calendar collection that contains, or would
- contain, the corresponding scheduling object resource.
-
-4.1. Processing "Organizer" Requests, Additions, and Cancellations
-
- For a scheduling message sent by an "Organizer", the server first
- tries to locate a corresponding scheduling object resource belonging
- to the "Attendee". If no matching scheduling object resource exists,
- the server treats the scheduling message as a new message; otherwise,
- it is treated as an update.
-
- In the case of a new message, the server processes the scheduling
- message and creates a new scheduling object resource as per
- Section 4.3.
-
- In the case of an update, the server processes the scheduling message
- and updates the matching scheduling object resource belonging to the
- "Attendee" to reflect the changes sent by the "Organizer".
-
- In each case, the scheduling message MUST only appear in the
- "Attendee's" scheduling Inbox collection once all automatic
- processing has been done.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 34]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-4.2. Processing "Attendee" Replies
-
- For a scheduling message reply sent by an "Attendee", the server
- first locates the corresponding scheduling object resource belonging
- to the "Organizer". If the corresponding scheduling object resource
- cannot be found, the server SHOULD ignore the scheduling message.
-
- The server MUST then update the "PARTSTAT" iCalendar property
- parameter value of each "ATTENDEE" iCalendar property in the
- scheduling object resource to match the changes indicated in the
- reply (taking into account the fact that an "Attendee" could have
- created a new overridden iCalendar component to indicate different
- participation status on one or more instances of a recurring event).
-
- The server MUST also update or add the "SCHEDULE-STATUS" property
- parameter on each matching "ATTENDEE" iCalendar property and set its
- value to that of the "REQUEST-STATUS" property in the reply, or to
- "2.0" if "REQUEST-STATUS" is not present (also taking into account
- recurrence instances). If there are multiple "REQUEST-STATUS"
- properties in the reply, the "SCHEDULE-STATUS" property parameter
- value is set to a comma-separated list of status codes, one from each
- "REQUEST-STATUS" property.
-
- The server SHOULD send scheduling messages to all the other
- "Attendees" indicating the change in participation status of the
- "Attendee" replying, subject to the recurrence requirements of
- Section 3.2.6.
-
- The scheduling message MUST only appear in the "Organizer's"
- scheduling Inbox collection once all automatic processing has been
- done.
-
-4.3. Default Calendar Collection
-
- The server processes scheduling messages received for an "Attendee"
- by creating a new scheduling object resource in a calendar collection
- belonging to the "Attendee", when one does not already exist. A
- calendar user that is an "Attendee" in a scheduling operation MUST
- have at least one valid calendar collection available. If there is
- no valid calendar collection, then the server MUST reject the attempt
- to deliver the scheduling message to the "Attendee".
-
- Servers MAY provide support for a default calendar collection -- that
- is, the calendar collection in which new scheduling object resources
- will be created. The CALDAV:schedule-default-calendar-URL WebDAV
- property, which can be present on the scheduling Inbox collection of
- a calendar user, specifies whether this calendar user has a default
- calendar collection. See Section 9.2.
-
-
-
-Daboo & Desruisseaux Standards Track [Page 35]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Servers SHOULD create new scheduling object resources in the default
- calendar collection, if the CALDAV:schedule-default-calendar-URL
- WebDAV property is set.
-
- Servers MAY allow clients to change the default calendar collection
- by changing the value of the CALDAV:schedule-default-calendar-URL
- WebDAV property on the scheduling Inbox collection. However, the
- server MUST ensure that any new value for that property refers to a
- valid calendar collection belonging to the owner of the scheduling
- Inbox collection.
-
- Servers MUST reject any attempt to delete the default calendar
- collection.
-
-4.3.1. Additional Method Preconditions
-
- This specification defines additional method preconditions (see
- Section 16 of WebDAV [RFC4918]) to provide machine-parseable
- information in error responses.
-
-4.3.1.1. CALDAV:default-calendar-needed Precondition
-
- Name: default-calendar-needed
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: DELETE
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- The client attempted to delete the
- calendar collection currently referenced by the CALDAV:schedule-
- default-calendar-URL property, or attempted to remove the CALDAV:
- schedule-default-calendar-URL property on the scheduling Inbox
- collection on a server that doesn't allow such operations.
-
- Definition:
-
-
-
-4.3.1.2. CALDAV:valid-schedule-default-calendar-URL Precondition
-
- Name: valid-schedule-default-calendar-URL
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: PROPPATCH
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 36]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- The client attempted to set the CALDAV:
- schedule-default-calendar-URL property to a DAV:href element that
- doesn't reference a valid calendar collection. Note: Servers that
- do not allow clients to change the CALDAV:schedule-default-
- calendar-URL property would simply return the DAV:cannot-modify-
- protected-property precondition defined in Section 16 of WebDAV
- [RFC4918].
-
- Definition:
-
-
-
-5. Request for Busy Time Information
-
- Busy time information of one or more calendar users can be determined
- by submitting a POST request targeted at the scheduling Outbox
- collection of the calendar user requesting the information (the
- "Organizer"). To accomplish this, the request body MUST contain a
- "VFREEBUSY" calendar component with the "METHOD" iCalendar property
- set to the value "REQUEST" as specified in Section 3.3.2 of iTIP
- [RFC5546]. The resource identified by the Request-URI MUST be a
- resource collection of type CALDAV:schedule-outbox (Section 2.1).
- The "ORGANIZER" property value in the "VFREEBUSY" component MUST
- match one of the calendar user addresses of the owner of the Outbox
- collection.
-
- A response to a busy time request that indicates status for one or
- more calendar users MUST be an XML document with a CALDAV:schedule-
- response XML element as its root element. This element MUST contain
- one CALDAV:response element for each calendar user, with each such
- element in turn containing elements that indicate which calendar user
- they correspond to, the scheduling status for that calendar user, any
- error codes, and an optional description. For a successful busy time
- request, a CALDAV:calendar-data element is also present for each
- calendar user, containing the actual busy time information (i.e., an
- iCalendar "VFREEBUSY" component). See Section 10 for details on the
- child elements. See Appendix B.5 for an example busy time request
- and response.
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 37]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-5.1. Status Codes
-
- The list below summarizes the most common status codes used for this
- method. However, clients need to be prepared to handle other
- 2/3/4/5xx series status codes as well.
-
- 200 (OK) - The command succeeded.
-
- 204 (No Content) - The command succeeded.
-
- 400 (Bad Request) - The client has provided an invalid scheduling
- message.
-
- 403 (Forbidden) - The client cannot submit a scheduling message to
- the specified Request-URI.
-
- 404 (Not Found) - The URL in the Request-URI was not present.
-
- 423 (Locked) - The specified resource is locked, and the client
- either is not a lock owner or the lock type requires a lock token
- to be submitted and the client did not submit it.
-
-5.2. Additional Method Preconditions
-
- The following are existing preconditions that are reused for the POST
- method on an Outbox collection.
-
- o DAV:need-privileges [RFC3744]
-
- o CALDAV:supported-calendar-data [RFC4791]
-
- o CALDAV:valid-calendar-data [RFC4791]
-
- o CALDAV:max-resource-size [RFC4791]
-
- The following are new method preconditions for the POST method on an
- Outbox collection.
-
-5.2.1. CALDAV:valid-scheduling-message Precondition
-
- Name: valid-scheduling-message
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: POST
-
- Use with: 400 Bad Request
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 38]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Purpose: (precondition) -- The resource submitted in the POST
- request MUST obey all the restrictions specified in Section 3.3.2
- of iTIP [RFC5546].
-
- Definition:
-
-
-
-5.2.2. CALDAV:valid-organizer Precondition
-
- Name: valid-organizer
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Apply to: POST
-
- Use with: 403 Forbidden
-
- Purpose: (precondition) -- The "ORGANIZER" property value in the
- POST request's scheduling message MUST match one of the calendar
- user addresses of the owner of the scheduling Outbox collection
- being targeted by the request.
-
- Definition:
-
-
-
-6. Scheduling Privileges
-
- New scheduling privileges are defined in this section. All the
- scheduling privileges MUST be non-abstract and MUST appear in the
- DAV:supported-privilege-set property of scheduling Outbox and Inbox
- collections on which they are defined.
-
- The tables specified in Appendix A clarify which scheduling methods
- (e.g., "REQUEST", "REPLY", etc.) are controlled by each scheduling
- privilege defined in this section.
-
-6.1. Privileges on Scheduling Inbox Collections
-
- This section defines new WebDAV Access Control List (ACL) [RFC3744]
- privileges that are defined for use on scheduling Inbox collections.
- These privileges determine whether delivery of scheduling messages
- from a calendar user is allowed by the calendar user who "owns" the
- scheduling Inbox collection. This allows calendar users to choose
- which other calendar users can schedule with them.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 39]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Note that when a scheduling message is delivered to a calendar user,
- in addition to a scheduling object resource being created in the
- calendar user's scheduling Inbox collection, a new scheduling object
- resource might be created or an existing one updated in a calendar
- belonging to the calendar user. In that case, the ability to create
- or update the scheduling object resource in the calendar is
- controlled by the privileges assigned to the scheduling Inbox
- collection.
-
- The privileges defined in this section are ignored if applied to a
- resource other than a scheduling Inbox collection.
-
-6.1.1. CALDAV:schedule-deliver Privilege
-
- CALDAV:schedule-deliver is an aggregate privilege as per Section 6.3.
-
-
-
-6.1.2. CALDAV:schedule-deliver-invite Privilege
-
- The CALDAV:schedule-deliver-invite privilege controls the processing
- and delivery of scheduling messages coming from an "Organizer".
-
-
-
-6.1.3. CALDAV:schedule-deliver-reply Privilege
-
- The CALDAV:schedule-deliver-reply privilege controls the processing
- and delivery of scheduling messages coming from an "Attendee".
-
-
-
-6.1.4. CALDAV:schedule-query-freebusy Privilege
-
- The CALDAV:schedule-query-freebusy privilege controls freebusy
- requests targeted at the owner of the scheduling Inbox collection.
-
-
-
-6.2. Privileges on Scheduling Outbox Collections
-
- This section defines new WebDAV ACL [RFC3744] privileges that are
- defined for use on scheduling Outbox collections. These privileges
- determine which calendar users are allowed to send scheduling
- messages on behalf of the calendar user who "owns" the scheduling
- Outbox collection. This allows calendar users to choose other
- calendar users who can act on their behalf (e.g., assistants working
- on behalf of their boss).
-
-
-
-Daboo & Desruisseaux Standards Track [Page 40]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- The privileges defined in this section are ignored if applied to a
- resource other than a scheduling Outbox collection.
-
-6.2.1. CALDAV:schedule-send Privilege
-
- CALDAV:schedule-send is an aggregate privilege as per Section 6.3.
-
-
-
-6.2.2. CALDAV:schedule-send-invite Privilege
-
- The CALDAV:schedule-send-invite privilege controls the sending of
- scheduling messages by "Organizers".
-
- Users granted the DAV:bind privilege on a calendar collection, or the
- DAV:write privilege on scheduling object resources, will also need
- the CALDAV:schedule-send-invite privilege granted on the scheduling
- Outbox collection of the owner of the calendar collection or
- scheduling object resource in order to be allowed to create, modify,
- or delete scheduling object resources in a way that will trigger the
- CalDAV server to deliver scheduling messages to "Attendees".
-
-
-
-6.2.3. CALDAV:schedule-send-reply Privilege
-
- The CALDAV:schedule-send-reply privilege controls the sending of
- scheduling messages by "Attendees".
-
- Users granted the DAV:bind privilege on a calendar collection, or the
- DAV:write privilege on scheduling object resources, will also need
- the CALDAV:schedule-send-reply privilege granted on the scheduling
- Outbox collection of the owner of the calendar collection or
- scheduling object resource in order to be allowed to create, modify,
- or delete scheduling object resources in a way that will trigger the
- CalDAV server to deliver scheduling message replies to the
- "Organizer".
-
-
-
-6.2.4. CALDAV:schedule-send-freebusy Privilege
-
- The CALDAV:schedule-send-freebusy privilege controls the use of the
- POST method to submit scheduling messages that specify the scheduling
- method "REQUEST" with a "VFREEBUSY" calendar component.
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 41]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-6.3. Aggregation of Scheduling Privileges
-
- Server implementations MUST aggregate the scheduling privileges as
- follows:
-
- DAV:all contains CALDAV:schedule-deliver and CALDAV:schedule-send;
-
- CALDAV:schedule-deliver contains CALDAV:schedule-deliver-invite,
- CALDAV:schedule-deliver-reply, and CALDAV:schedule-query-freebusy;
-
- CALDAV:schedule-send contains CALDAV:schedule-send-invite, CALDAV:
- schedule-send-reply, and CALDAV:schedule-send-freebusy.
-
- The following diagram illustrates how scheduling privileges are
- aggregated according to the above requirements.
-
- [DAV:all] (aggregate)
- |
- +-- [CALDAV:schedule-deliver] (aggregate)
- | |
- | +-- [CALDAV:schedule-deliver-invite]
- | +-- [CALDAV:schedule-deliver-reply]
- | +-- [CALDAV:schedule-query-freebusy]
- |
- +-- [CALDAV:schedule-send] (aggregate)
- |
- +-- [CALDAV:schedule-send-invite]
- +-- [CALDAV:schedule-send-reply]
- +-- [CALDAV:schedule-send-freebusy]
-
-7. Additional iCalendar Property Parameters
-
- This specification defines additional iCalendar property parameters
- to support the CalDAV scheduling extensions.
-
-7.1. Schedule Agent Parameter
-
- Parameter Name: SCHEDULE-AGENT
-
- Purpose: To specify the agent expected to deliver scheduling
- messages to the corresponding "Organizer" or "Attendee".
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 42]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Format Definition: This property parameter is defined by the
- following notation:
-
- scheduleagentparam = "SCHEDULE-AGENT" "="
- ("SERVER" ; The server handles scheduling
- / "CLIENT" ; The client handles scheduling
- / "NONE" ; No scheduling
- / x-name ; Experimental type
- / iana-token) ; Other IANA-registered type
- ;
- ; If the parameter is not present, its value defaults to SERVER.
- ; "x-name" and "iana-token" are defined in Section 3.1 of
- ; [RFC5545].
-
- Description: This property parameter MAY be specified on "ORGANIZER"
- or "ATTENDEE" iCalendar properties. In the absence of this
- parameter, the value "SERVER" MUST be used for the default
- behavior. The value determines whether or not a scheduling
- operation on a server will cause a scheduling message to be sent
- to the corresponding calendar user identified by the "ORGANIZER"
- or "ATTENDEE" property value. When the value "SERVER" is
- specified, or the parameter is absent, then it is the server's
- responsibility to send a scheduling message as part of a
- scheduling operation. When the value "CLIENT" is specified, that
- indicates that the client is handling scheduling messages with the
- calendar user itself. When "NONE" is specified, no scheduling
- messages are being sent to the calendar user.
-
- Servers MUST NOT include this parameter in any scheduling messages
- sent as the result of a scheduling operation.
-
- Clients MUST NOT include this parameter in any scheduling messages
- that they themselves send.
-
- The parameter value MUST be the same on every "ORGANIZER" property
- in a scheduling object resource.
-
- The parameter value MUST be the same on each "ATTENDEE" property
- whose values match in a scheduling object resource.
-
- Servers and clients MUST treat x-name and iana-token values they
- do not recognize the same way as they would the "NONE" value.
-
- Example:
-
- ORGANIZER;SCHEDULE-AGENT=SERVER:mailto:bernard@example.com
- ATTENDEE;SCHEDULE-AGENT=NONE:mailto:cyrus@example.com
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 43]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-7.2. Schedule Force Send Parameter
-
- Parameter Name: SCHEDULE-FORCE-SEND
-
- Purpose: To force a scheduling message to be sent to the calendar
- user specified by the property.
-
- Format Definition: This property parameter is defined by the
- following notation:
-
- scheduleforcesendparam = "SCHEDULE-FORCE-SEND" "="
- ("REQUEST" ; Force a "REQUEST"
- / "REPLY" ; Force a "REPLY"
- / iana-token)
- ;
- ; "iana-token" is defined in Section 3.1 of [RFC5545]. Its value
- ; MUST be an IANA-registered iCalendar "METHOD" property value.
-
- Description: This property parameter MAY be specified on "ATTENDEE"
- and "ORGANIZER" properties on which the "SCHEDULE-AGENT" property
- parameter is set to the value "SERVER" or is not specified. This
- property parameter is used to force a server to send a scheduling
- message to a specific calendar user in situations where the server
- would not send a scheduling message otherwise (e.g., when no
- change that warrants the delivery of a new scheduling message was
- performed on the scheduling object resource). An "Organizer" MAY
- specify this parameter on an "ATTENDEE" property with the value
- "REQUEST" to force a "REQUEST" scheduling message to be sent to
- this "Attendee". An "Attendee" MAY specify this parameter on the
- "ORGANIZER" with the value "REPLY" to force a "REPLY" scheduling
- message to be sent to the "Organizer".
-
- Servers MUST NOT preserve this property parameter in scheduling
- object resources, nor include it in any scheduling messages sent
- as the result of a scheduling operation.
-
- Clients MUST NOT include this parameter in any scheduling messages
- that they themselves send.
-
- Servers MUST set the "SCHEDULE-STATUS" parameter of the "ATTENDEE"
- or "ORGANIZER" to 2.3 (i.e., "Success; invalid property parameter
- ignored"; see Section 3.6 of [RFC5546]) when the "SCHEDULE-FORCE-
- SEND" parameter is set to an iana-token value they do not
- recognize.
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 44]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Example:
-
- ORGANIZER;SCHEDULE-FORCE-SEND=REPLY:mailto:cyrus@example.com
- ATTENDEE;SCHEDULE-FORCE-SEND=REQUEST:mailto:bernard@example.com
-
-7.3. Schedule Status Parameter
-
- Parameter Name: SCHEDULE-STATUS
-
- Purpose: To specify the status codes returned from processing of the
- most recent scheduling message sent to the corresponding
- "Attendee", or received from the corresponding "Organizer".
-
- Format Definition: This property parameter is defined by the
- following notation:
-
- schedulestatusparam = "SCHEDULE-STATUS" "="
- ( statcode
- / DQUOTE statcode *("," statcode) DQUOTE)
- ;
- ; "statcode" is defined in Section 3.8.8.3 of [RFC5545]. The
- ; value is a single "statcode" or a comma-separated list of
- ; "statcode" values.
-
- Description: This property parameter MAY be specified on the
- "ATTENDEE" and "ORGANIZER" properties.
-
- Servers MUST only add or change this property parameter on any
- "ATTENDEE" properties corresponding to calendar users who were
- sent a scheduling message via a scheduling operation. Clients
- SHOULD NOT change or remove this parameter if it was provided by
- the server. In the case where the client is handling the
- scheduling, the client MAY add, change, or remove this parameter
- to indicate the last scheduling message status it received.
-
- Servers MUST add this parameter to any "ORGANIZER" properties
- corresponding to calendar users who were sent a scheduling message
- reply by an "Attendee" via a scheduling operation. Clients SHOULD
- NOT change or remove this parameter if it was provided by the
- server. In the case where the client is handling the scheduling,
- the client MAY add, change, or remove this parameter to indicate
- the last scheduling message status it received.
-
- Servers MUST NOT include this parameter in any scheduling messages
- sent as the result of a scheduling operation.
-
- Clients MUST NOT include this parameter in any scheduling messages
- that they themselves send.
-
-
-
-Daboo & Desruisseaux Standards Track [Page 45]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Values for this property parameter are described in Section 3.2.9.
-
- Example:
-
- ATTENDEE;SCHEDULE-STATUS="2.0":mailto:bernard@example.com
- ATTENDEE;SCHEDULE-STATUS="2.0,2.4":mailto:cyrus@example.com
-
-8. Additional Message Header Fields
-
- This specification defines additional HTTP request and response
- headers for use with CalDAV.
-
-8.1. Schedule-Reply Request Header
-
- Schedule-Reply = "Schedule-Reply" ":" ("T" | "F")
-
- Example:
-
- Schedule-Reply: F
-
- When an "Attendee" removes a scheduling object resource as per
- Section 3.2.2.4, and the Schedule-Reply header is set to the value
- "T" (true) or is not present, the server MUST send an appropriate
- reply scheduling message with the "Attendee's" "PARTSTAT" iCalendar
- property parameter value set to "DECLINED" as part of its normal
- scheduling operation processing.
-
- When the Schedule-Reply header is set to the value "F" (false), the
- server MUST NOT send a scheduling message as part of its normal
- scheduling operation processing.
-
- The Schedule-Reply request header is used by a client to indicate to
- a server whether or not a scheduling operation ought to occur when an
- "Attendee" deletes a scheduling object resource. In particular, it
- controls whether a reply scheduling message is sent to the
- "Organizer" as a result of the removal. There are situations in
- which unsolicited scheduling messages need to be silently removed (or
- ignored) for security or privacy reasons. This request header allows
- the scheduling object resource to be removed if such a need arises.
-
-8.2. Schedule-Tag Response Header
-
- The Schedule-Tag response header provides the current value of the
- CALDAV:schedule-tag property value. The behavior of this response
- header is described in Section 3.2.10.
-
- All scheduling object resources MUST support the Schedule-Tag header.
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 46]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Schedule-Tag = "Schedule-Tag" ":" opaque-tag
- ; "opaque-tag" is defined in Section 3.11 of [RFC2616].
-
- Example:
-
- Schedule-Tag: "12ab34-cd56ef"
-
-8.3. If-Schedule-Tag-Match Request Header
-
- The If-Schedule-Tag-Match request header field is used with a method
- to make it conditional. Clients can set this header to the value
- returned in the Schedule-Tag response header, or the CALDAV:schedule-
- tag property, of a scheduling object resource previously retrieved
- from the server to avoid overwriting "consequential" changes to the
- scheduling object resource.
-
- All scheduling object resources MUST support the If-Schedule-Tag-
- Match header.
-
- If-Schedule-Tag-Match = "If-Schedule-Tag-Match" ":" opaque-tag
- ; "opaque-tag" is defined in Section 3.11 of [RFC2616].
-
- Example:
-
- If-Schedule-Tag-Match: "12ab34-cd56ef"
-
-9. Additional WebDAV Properties
-
- This specification defines the following new WebDAV properties for
- use with CalDAV.
-
-9.1. CALDAV:schedule-calendar-transp Property
-
- Name: schedule-calendar-transp
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Determines whether the calendar object resources in a
- calendar collection will affect the owner's busy time information.
-
- Protected: This property MAY be protected and SHOULD NOT be returned
- by a PROPFIND DAV:allprop request (as defined in Section 14.2 of
- [RFC4918]).
-
- COPY/MOVE behavior: This property value SHOULD be kept during a MOVE
- operation, and SHOULD be copied and preserved in a COPY.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 47]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Description: This property SHOULD be defined on all calendar
- collections. If present, it contains one of two XML elements that
- indicate whether the calendar object resources in the calendar
- collection ought to contribute to the owner's busy time. When the
- CALDAV:opaque element is used, all calendar object resources in
- the corresponding calendar collection MUST contribute to busy
- time, assuming that access privileges and other iCalendar
- properties allow it to. When the CALDAV:transparent XML element
- is used, the calendar object resources in the corresponding
- calendar collection MUST NOT contribute to busy time.
-
- If this property is not present on a calendar collection, then the
- default value CALDAV:opaque MUST be assumed.
-
- Definition:
-
-
-
-
-
-
-
-
-
- Example:
-
-
-
-
-
-9.2. CALDAV:schedule-default-calendar-URL Property
-
- Name: schedule-default-calendar-URL
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Specifies a default calendar for an "Attendee" where new
- scheduling object resources are created.
-
- Protected: This property MAY be protected in the case where a server
- does not support changing the default calendar, or does not
- support a default calendar.
-
- COPY/MOVE behavior: This property is only defined on a scheduling
- Inbox collection that cannot be moved or copied.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 48]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Description: This property MAY be defined on a scheduling Inbox
- collection. If present, it contains zero or one DAV:href XML
- elements. When a DAV:href element is present, its value indicates
- a URL to a calendar collection that is used as the default
- calendar. When no DAV:href element is present, it indicates that
- there is no default calendar. In the absence of this property,
- there is no default calendar. When there is no default calendar,
- the server is free to choose the calendar in which a new
- scheduling object resource is created. See Section 4.3.
-
- Definition:
-
-
-
- Example:
-
-
- /home/cyrus/calendars/work/
-
-
-9.3. CALDAV:schedule-tag Property
-
- Name: schedule-tag
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Indicates whether a scheduling object resource has had a
- "consequential" change made to it.
-
- Value: opaque-tag (defined in Section 3.11 of [RFC2616])
-
- Protected: This property MUST be protected, as only the server can
- update the value.
-
- COPY/MOVE behavior: This property value is determined by the server
- and MAY be different from the value on the source resource.
-
- Description: The CALDAV:schedule-tag property MUST be defined on all
- scheduling object resources. This property is described in
- Section 3.2.10.
-
- Definition:
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 49]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Example:
-
- "12345-67890"
-
-10. XML Element Definitions
-
-10.1. CALDAV:schedule-response XML Element
-
- Name: schedule-response
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Contains the set of responses for a POST method request.
-
- Description: See Section 5.
-
- Definition:
-
-
-
-10.2. CALDAV:response XML Element
-
- Name: response
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: Contains a single response for a POST method request.
-
- Description: See Section 5.
-
- Definition:
-
-
-
-
-
-10.3. CALDAV:recipient XML Element
-
- Name: recipient
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
-
-
-Daboo & Desruisseaux Standards Track [Page 50]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Purpose: The calendar user address that the enclosing response for a
- POST method request is for.
-
- Description: See Section 5.
-
- Definition:
-
-
-
-10.4. CALDAV:request-status XML Element
-
- Name: request-status
-
- Namespace: urn:ietf:params:xml:ns:caldav
-
- Purpose: The iTIP "REQUEST-STATUS" property value for this response.
-
- Description: See Section 5.
-
- Definition:
-
-
-
-11. Security Considerations
-
- The process of scheduling involves the sending and receiving of
- scheduling messages. As a result, the security problems related to
- messaging in general are relevant here. In particular, the
- authenticity of the scheduling messages needs to be verified.
- Servers and clients MUST use an HTTP connection protected with
- Transport Layer Security (TLS) as defined in [RFC2818] for all
- scheduling operations. Clients MUST use the procedures detailed in
- Section 6 of [RFC6125] to verify the authenticity of the server.
- Servers MUST make use of HTTP authentication [RFC2617] to verify the
- authenticity of the calendar user for whom the client is sending
- requests.
-
-11.1. Preventing Denial-of-Service Attacks
-
- Servers MUST ensure that clients cannot consume excessive server
- resources by carrying out "large" scheduling operations. In
- particular, servers SHOULD enforce CALDAV:max-resource-size, CALDAV:
- max-instances, and CALDAV:max-attendees-per-instance preconditions as
- applicable for scheduling Inbox and Outbox collections.
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 51]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-11.2. Verifying Scheduling Operations
-
- When handling a scheduling operation:
-
- 1. Servers MUST verify that the principal associated with the DAV:
- owner of the calendar collection in which a scheduling object
- resource is being manipulated contains a CALDAV:schedule-outbox-
- URL property value.
-
- 2. Servers MUST verify that the currently authenticated user has the
- CALDAV:schedule-send privilege, or a sub-privilege aggregated
- under this privilege, on the scheduling Outbox collection of the
- DAV:owner of the calendar collection in which a scheduling object
- resource is being manipulated.
-
- 3. Servers MUST only deliver scheduling messages to recipients when
- the CALDAV:schedule-deliver privilege, or a sub-privilege
- aggregated under this privilege, is granted on the recipient's
- scheduling Inbox collection for the principal associated with the
- DAV:owner of the calendar collection in which a scheduling object
- resource is being manipulated.
-
- 4. To prevent impersonation of calendar users, the server MUST
- verify that the "ORGANIZER" property in an organizer scheduling
- object resource matches one of the calendar user addresses of the
- DAV:owner of the calendar collection in which the resource is
- stored.
-
- 5. To prevent spoofing of an existing scheduling object resource,
- servers MUST verify that the "UID" iCalendar property value in a
- new scheduling object resource does not match that of an existing
- scheduling object resource with a different "ORGANIZER" property
- value.
-
-11.3. Verifying Busy Time Information Requests
-
- When handling a POST request on a scheduling Outbox collection:
-
- 1. Servers MUST verify that the principal associated with the
- calendar user address specified in the "ORGANIZER" property of
- the scheduling message data in the request contains a CALDAV:
- schedule-outbox-URL property value that matches the scheduling
- Outbox collection targeted by the request.
-
- 2. Servers MUST verify that the currently authenticated user has the
- CALDAV:schedule-send privilege, or a sub-privilege aggregated
- under this privilege, on the scheduling Outbox collection
- targeted by the request.
-
-
-
-Daboo & Desruisseaux Standards Track [Page 52]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- 3. Servers MUST only return valid freebusy information for
- recipients when the CALDAV:schedule-deliver privilege, or a
- sub-privilege aggregated under this privilege, is granted on the
- recipient's scheduling Inbox collection for the principal
- associated with the DAV:owner of the scheduling Outbox collection
- targeted by the request.
-
-11.4. Privacy Issues
-
- This specification only defines how calendar users on the same server
- are able to schedule with each other -- unauthenticated users have no
- way to carry out scheduling operations. Access control privileges
- (as per Section 6) can control which of those users can schedule with
- others. Calendar users not wishing to expose their calendar
- information to other users can do so by denying privileges to
- specific users, or all users, for all scheduling operations, or
- perhaps only freebusy.
-
- "Attendees" can also use the Schedule-Reply request header
- (Section 8.1) with the value set to "F" to prevent notification to an
- "Organizer" that a scheduling object resource was deleted. This
- allows "Attendees" to remove unwanted scheduling messages without any
- response to the "Organizer".
-
- Servers MUST NOT expose any private iCalendar data, or WebDAV
- resource state information (URLs, WebDAV properties, etc.) for one
- calendar user to another via scheduling messages or error responses
- to scheduling operations. In particular, as per Section 8.1 of
- [RFC4918], authorization errors MUST take preference over other
- errors.
-
-11.5. Mitigation of iTIP Threats
-
- Section 6.1 of iTIP [RFC5546] defines a set of potential threats in a
- scheduling system, and Section 6.2 of [RFC5546] defines
- recommendations on how those can be addressed in protocols using
- iTIP. This specification addresses the iTIP threats in the following
- manner:
-
- Spoofing the "Organizer": Addressed by item 4 in Section 11.2.
-
- Spoofing the "Attendee": Addressed by Section 3.2.2.1 and item 2 in
- Section 11.2.
-
- Unauthorized Replacement of the "Organizer": Addressed by item 5 in
- Section 11.2.
-
- Eavesdropping and Data Integrity: Addressed by requiring TLS.
-
-
-
-Daboo & Desruisseaux Standards Track [Page 53]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Flooding a Calendar: Addressed by requirements in Section 11.1.
-
- Unauthorized REFRESH Requests: This specification does not support
- the REFRESH method.
-
-12. IANA Considerations
-
-12.1. Message Header Field Registrations
-
- The message header fields below have been added to the Permanent
- Message Header Field Registry (see [RFC3864]).
-
-12.1.1. Schedule-Reply
-
- Header field name: Schedule-Reply
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document(s): this specification (Section 8.1)
-
- Related information: none
-
-12.1.2. Schedule-Tag
-
- Header field name: Schedule-Tag
-
- Applicable protocol: http
-
- Status: standard
-
- Author/Change controller: IETF
-
- Specification document(s): this specification (Section 8.2)
-
- Related information: none
-
-12.1.3. If-Schedule-Tag-Match
-
- Header field name: If-Schedule-Tag-Match
-
- Applicable protocol: http
-
- Status: standard
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 54]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Author/Change controller: IETF
-
- Specification document(s): this specification (Section 8.3)
-
- Related information: none
-
-12.2. iCalendar Property Parameter Registrations
-
- The following iCalendar property parameter names have been added to
- the iCalendar Parameters Registry defined in Section 8.3.3 of
- [RFC5545].
-
- +---------------------+---------+-----------------------+
- | Parameter | Status | Reference |
- +---------------------+---------+-----------------------+
- | SCHEDULE-AGENT | Current | RFC 6638, Section 7.1 |
- | | | |
- | SCHEDULE-STATUS | Current | RFC 6638, Section 7.3 |
- | | | |
- | SCHEDULE-FORCE-SEND | Current | RFC 6638, Section 7.2 |
- +---------------------+---------+-----------------------+
-
-12.3. iCalendar REQUEST-STATUS Value Registrations
-
- The following iCalendar "REQUEST-STATUS" values have been added to
- the iCalendar REQUEST-STATUS Value Registry defined in Section 7.3 of
- [RFC5546].
-
- +-------------+---------+---------------------------+
- | Status Code | Status | Reference |
- +-------------+---------+---------------------------+
- | 1.0 | Current | RFC 6638, Section 3.2.9.1 |
- | | | |
- | 1.1 | Current | RFC 6638, Section 3.2.9.2 |
- | | | |
- | 1.2 | Current | RFC 6638, Section 3.2.9.3 |
- +-------------+---------+---------------------------+
-
-12.4. Additional iCalendar Elements Registries
-
- Per this specification, two new IANA registries for iCalendar
- elements have been added. Additional codes MAY be used, provided the
- process described in Section 8.2.1 of [RFC5545] is used to register
- them.
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 55]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-12.4.1. Schedule Agent Values Registry
-
- The following table has been used to initialize the Schedule Agent
- Values Registry.
-
- +----------------+---------+-----------------------+
- | Schedule Agent | Status | Reference |
- +----------------+---------+-----------------------+
- | SERVER | Current | RFC 6638, Section 7.1 |
- | | | |
- | CLIENT | Current | RFC 6638, Section 7.1 |
- | | | |
- | NONE | Current | RFC 6638, Section 7.1 |
- +----------------+---------+-----------------------+
-
-12.4.2. Schedule Force Send Values Registry
-
- The following table has been used to initialize the Schedule Force
- Send Values Registry.
-
- +---------------------+---------+-----------------------+
- | Schedule Force Send | Status | Reference |
- +---------------------+---------+-----------------------+
- | REQUEST | Current | RFC 6638, Section 7.2 |
- | | | |
- | REPLY | Current | RFC 6638, Section 7.2 |
- +---------------------+---------+-----------------------+
-
-13. Acknowledgements
-
- The authors would like to thank the following individuals for
- contributing their ideas and support for writing this specification:
- Mike Douglass, Lisa Dusseault, Red Dutta, Jacob Farkas, Jeffrey
- Harris, Helge Hess, Eliot Lear, Andrew McMillan, Alexey Melnikov,
- Arnaud Quillaud, Julian F. Reschke, Wilfredo Sanchez Vega, and Simon
- Vaillancourt.
-
- The authors would also like to thank the Calendaring and Scheduling
- Consortium for advice with this specification, and for organizing
- interoperability testing events to help refine it.
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 56]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-14. References
-
-14.1. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
- 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.
-
- [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", RFC 3744, May 2004.
-
- [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration
- Procedures for Message Header Fields", BCP 90, RFC 3864,
- September 2004.
-
- [RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault,
- "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
- March 2007.
-
- [RFC4918] Dusseault, L., Ed., "HTTP Extensions for Web Distributed
- Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
-
- [RFC5234] Crocker, D., Ed., and P. Overell, "Augmented BNF for
- Syntax Specifications: ABNF", STD 68, RFC 5234,
- January 2008.
-
- [RFC5545] Desruisseaux, B., Ed., "Internet Calendaring and
- Scheduling Core Object Specification (iCalendar)",
- RFC 5545, September 2009.
-
- [RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent
- Interoperability Protocol (iTIP)", RFC 5546,
- December 2009.
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 57]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- [RFC6125] Saint-Andre, P. and J. Hodges, "Representation and
- Verification of Domain-Based Application Service Identity
- within Internet Public Key Infrastructure Using X.509
- (PKIX) Certificates in the Context of Transport Layer
- Security (TLS)", RFC 6125, March 2011.
-
- [W3C.REC-xml-20081126]
- Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E.,
- and F. Yergeau, "Extensible Markup Language (XML) 1.0
- (Fifth Edition)", World Wide Web Consortium
- Recommendation REC-xml-20081126, November 2008,
- .
-
-14.2. Informative References
-
- [RFC6047] Melnikov, A., Ed., "iCalendar Message-Based
- Interoperability Protocol (iMIP)", RFC 6047,
- December 2010.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 58]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-Appendix A. Scheduling Privileges Summary
-
-A.1. Scheduling Inbox Privileges
-
- The following tables specify which scheduling privileges grant the
- right to a calendar user to deliver a scheduling message to the
- scheduling Inbox collection of another calendar user. The
- appropriate behavior depends on the calendar component type as well
- as the scheduling "METHOD" specified in the scheduling message.
-
- +--------------------------------+
- | METHOD for VEVENT and VTODO |
- +-----------------------------+---------+-------+-----+--------+
- | Scheduling Inbox Privilege | REQUEST | REPLY | ADD | CANCEL |
- +-----------------------------+---------+-------+-----+--------+
- | schedule-deliver | * | * | * | * |
- | schedule-deliver-invite | * | | * | * |
- | schedule-deliver-reply | | * | | |
- | schedule-query-freebusy | | | | |
- +-----------------------------+---------+-------+-----+--------+
-
-
- +----------------------+
- | METHOD for VFREEBUSY |
- +-----------------------------+----------------------+
- | Scheduling Inbox Privilege | REQUEST |
- +-----------------------------+----------------------+
- | schedule-deliver | * |
- | schedule-deliver-invite | |
- | schedule-deliver-reply | |
- | schedule-query-freebusy | * |
- +-----------------------------+----------------------+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 59]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-A.2. Scheduling Outbox Privileges
-
- The following tables specify which scheduling privileges grant the
- right to a calendar user to perform busy time information requests
- and to submit scheduling messages to other calendar users as the
- result of a scheduling operation. The appropriate behavior depends
- on the calendar component type as well as the scheduling "METHOD"
- specified in the scheduling message.
-
- +--------------------------------+
- | METHOD for VEVENT and VTODO |
- +-----------------------------+---------+-------+-----+--------+
- | Scheduling Outbox Privilege | REQUEST | REPLY | ADD | CANCEL |
- +-----------------------------+---------+-------+-----+--------+
- | schedule-send | * | * | * | * |
- | schedule-send-invite | * | | * | * |
- | schedule-send-reply | | * | | |
- | schedule-send-freebusy | | | | |
- +-----------------------------+---------+-------+-----+--------+
-
-
- +----------------------+
- | METHOD for VFREEBUSY |
- +-----------------------------+----------------------+
- | Scheduling Outbox Privilege | REQUEST |
- +-----------------------------+----------------------+
- | schedule-send | * |
- | schedule-send-invite | |
- | schedule-send-reply | |
- | schedule-send-freebusy | * |
- +-----------------------------+----------------------+
-
-Appendix B. Example Scheduling Operations
-
- This section describes some example scheduling operations that give a
- general idea of how scheduling is carried out between CalDAV clients
- and servers from the perspective of meeting "Organizers" and
- "Attendees".
-
- The server is assumed to be hosted in the "example.com" domain, and
- users whose email addresses are at the "example.com" domain are
- assumed to be hosted by the server. In addition, the email addresses
- in the "example.net" domain are also valid email addresses for
- calendar users hosted by the server. Calendar users with an email
- address at the "example.org" domain are assumed to not be hosted by
- the server.
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 60]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- In the following examples, the requests and responses are incomplete
- and are only for illustrative purposes. In particular, HTTP
- authentication headers and behaviors are not shown, even though they
- are required in normal operation.
-
-B.1. Example: "Organizer" Inviting Multiple "Attendees"
-
- In the following example, Cyrus invites Wilfredo, Bernard, and Mike
- to a single instance event by simply creating a new scheduling object
- resource in one of his calendar collections by using the PUT method.
-
- >> Request <<
-
- PUT /home/cyrus/calendars/work/9263504FD3AD.ics HTTP/1.1
- Host: cal.example.com
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
- If-None-Match: *
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185254Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:wilfredo@
- example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@ex
- ample.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE:mailto:mike@example.org
- END:VEVENT
- END:VCALENDAR
-
- >> Response <<
-
- HTTP/1.1 201 Created
- Content-Length: 0
-
-
-
-Daboo & Desruisseaux Standards Track [Page 61]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Date: Tue, 02 Jun 2009 18:52:54 GMT
- Last-Modified: Tue, 02 Jun 2009 18:52:54 GMT
- ETag: "d85561cfe74a4e785eb4639451b434fb"
- Schedule-Tag: "488177c8-2ea7-4176-a6cb-fab8cfccdea2"
-
- Once the event creation has been completed, Cyrus's client will
- retrieve the event back from the server to get the schedule status of
- each "Attendee", as well as record the Schedule-Tag value for future
- use. In this example, the server reports that a scheduling message
- was delivered to Wilfredo, a scheduling message is still pending for
- Bernard, and the server was unable to deliver a scheduling message to
- Mike.
-
- >> Request <<
-
- GET /home/cyrus/calendars/work/9263504FD3AD.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 18:52:58 GMT
- Last-Modified: Tue, 02 Jun 2009 18:52:58 GMT
- ETag: "eb897deabc8939589da116714bc99265"
- Schedule-Tag: "488177c8-2ea7-4176-a6cb-fab8cfccdea2"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185300Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=
- 1.2:mailto:wilfredo@e
- xample.com
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 62]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=
- 1.0:mailto:bernard@example.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE;SCHEDULE-STATUS=3.7:mailto:mike@example.org
- END:VEVENT
- END:VCALENDAR
-
-B.2. Example: "Attendee" Receiving an Invitation
-
- In the following example, Wilfredo's client retrieves and deletes the
- new scheduling message that appeared in his scheduling Inbox
- collection after the server automatically processed it and created a
- new scheduling object resource in his default calendar collection.
-
- >> Request <<
-
- GET /home/wilfredo/calendars/inbox/27d93fc0a58c.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 18:59:58 GMT
- Last-Modified: Tue, 02 Jun 2009 18:59:58 GMT
- ETag: "da116714bc9926c89395895eb897deab"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- METHOD:REQUEST
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185254Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:wilfredo@
- example.com
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 63]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@ex
- ample.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE:mailto:mike@example.org
- END:VEVENT
- END:VCALENDAR
-
- >> Request <<
-
- DELETE /home/wilfredo/calendars/inbox/27d93fc0a58c.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 204 No Content
- Date: Tue, 02 Jun 2009 20:40:36 GMT
-
-B.3. Example: "Attendee" Replying to an Invitation
-
- In the following example, Wilfredo accepts Cyrus's invitation and
- sets an alarm reminder on the event. It uses the If-Schedule-Tag-
- Match precondition behavior to ensure it does not overwrite any
- significant changes from the "Organizer" that might have occurred
- after it retrieved the initial resource data.
-
- >> Request <<
-
- PUT /home/wilfredo/calendars/work/BB64861C2228.ics HTTP/1.1
- Host: cal.example.com
- If-Schedule-Tag-Match: "e78f23ed-0188-4bab-938d-2aeb3324c7e8"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185254Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
-
-
-
-Daboo & Desruisseaux Standards Track [Page 64]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:wilfredo@exam
- ple.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@ex
- ample.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE:mailto:mike@example.org
- BEGIN:VALARM
- TRIGGER:-PT15M
- ACTION:DISPLAY
- DESCRIPTION:Reminder
- END:VALARM
- END:VEVENT
- END:VCALENDAR
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Content-Length: 0
- Date: Tue, 02 Jun 2009 18:57:54 GMT
- Last-Modified: Tue, 02 Jun 2009 18:57:54 GMT
- ETag: "eb4639451b434fbd85561cfe74a4e785"
- Schedule-Tag: "8893ee45-eb9d-428f-b53c-c777daf19e41"
-
- Once the event modification has been completed, Wilfredo's client
- will retrieve the event back from the server to get the schedule
- status of the "Organizer".
-
- >> Request <<
-
- GET /home/wilfredo/calendars/work/BB64861C2228.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 19:03:03 GMT
- Last-Modified: Tue, 02 Jun 2009 19:02:21 GMT
- ETag: "5eb897deabda116714bc9926c8939589"
- Schedule-Tag: "8893ee45-eb9d-428f-b53c-c777daf19e41"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 65]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T190221Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo";SCHEDULE-STATUS=1.2:mailto:cyrus@ex
- ample.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:wilfredo@exam
- ple.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@ex
- ample.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE:mailto:mike@example.org
- BEGIN:VALARM
- TRIGGER:-PT15M
- ACTION:DISPLAY
- DESCRIPTION:Reminder
- END:VALARM
- END:VEVENT
- END:VCALENDAR
-
-B.4. Example: "Organizer" Receiving a Reply to an Invitation
-
- On reception of Wilfredo's reply, Cyrus's server will automatically
- update Cyrus's scheduling object resource, make Wilfredo's scheduling
- message available in Cyrus's scheduling Inbox collection, and deliver
- an updated scheduling message to Bernard to share Wilfredo's updated
- participation status. In this example, Cyrus's client retrieves and
- deletes this scheduling message in his scheduling Inbox collection.
-
- >> Request <<
-
- GET /home/cyrus/calendars/inbox/c0a58c27d93f.ics HTTP/1.1
- Host: cal.example.com
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 66]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 19:05:02 GMT
- Last-Modified: Tue, 02 Jun 2009 19:04:20 GMT
- ETag: "9265eb897deabc8939589da116714bc9"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- METHOD:REPLY
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185754Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";PARTSTAT=ACCEPTED:mailto:w
- ilfredo@example.com
- REQUEST-STATUS:2.0;Success
- END:VEVENT
- END:VCALENDAR
-
- >> Request <<
-
- DELETE /home/cyrus/calendars/inbox/c0a58c27d93f.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 204 No Content
- Date: Tue, 02 Jun 2009 19:05:05 GMT
-
- Cyrus's client then retrieves the event back from the server with
- Wilfredo's updated participation status.
-
- >> Request <<
-
- GET /home/cyrus/calendars/work/9263504FD3AD.ics HTTP/1.1
- Host: cal.example.com
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 67]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 19:05:02 GMT
- Last-Modified: Tue, 02 Jun 2009 19:04:20 GMT
- ETag: "eb897deabc8939589da116714bc99265"
- Schedule-Tag: "132cab27-1fe3-67ab-de13-abd348d1dee3"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T190420Z
- DTSTART:20090602T160000Z
- DTEND:20090602T170000Z
- TRANSP:OPAQUE
- SUMMARY:Lunch
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT
- =ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=2.0:
- mailto:wilfredo@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1
- .0:mailto:bernard@example.net
- ATTENDEE;CN="Mike Douglass";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-A
- CTION;RSVP=TRUE;SCHEDULE-STATUS=3.7:mailto:mike@example.org
- END:VEVENT
- END:VCALENDAR
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 68]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-B.5. Example: "Organizer" Requesting Busy Time Information
-
- In this example, Cyrus requests the busy time information of
- Wilfredo, Bernard, and Mike.
-
- >> Request <<
-
- POST /home/cyrus/calendars/outbox/ HTTP/1.1
- Host: cal.example.com
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- METHOD:REQUEST
- BEGIN:VFREEBUSY
- UID:4FD3AD926350
- DTSTAMP:20090602T190420Z
- DTSTART:20090602T000000Z
- DTEND:20090604T000000Z
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega":mailto:wilfredo@example.com
- ATTENDEE;CN="Bernard Desruisseaux":mailto:bernard@example.net
- ATTENDEE;CN="Mike Douglass":mailto:mike@example.org
- END:VFREEBUSY
- END:VCALENDAR
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 20:07:34 GMT
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
- mailto:wilfredo@example.com
-
- 2.0;Success
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- METHOD:REPLY
- BEGIN:VFREEBUSY
-
-
-
-Daboo & Desruisseaux Standards Track [Page 69]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- UID:4FD3AD926350
- DTSTAMP:20090602T200733Z
- DTSTART:20090602T000000Z
- DTEND:20090604T000000Z
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega":mailto:wilfredo@example.com
- FREEBUSY;FBTYPE=BUSY:20090602T110000Z/20090602T120000Z
- FREEBUSY;FBTYPE=BUSY:20090603T170000Z/20090603T180000Z
- END:VFREEBUSY
- END:VCALENDAR
-
-
-
-
- mailto:bernard@example.net
-
- 2.0;Success
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Server//EN
- METHOD:REPLY
- BEGIN:VFREEBUSY
- UID:4FD3AD926350
- DTSTAMP:20090602T200733Z
- DTSTART:20090602T000000Z
- DTEND:20090604T000000Z
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux":mailto:bernard@example.net
- FREEBUSY;FBTYPE=BUSY:20090602T150000Z/20090602T160000Z
- FREEBUSY;FBTYPE=BUSY:20090603T090000Z/20090603T100000Z
- FREEBUSY;FBTYPE=BUSY:20090603T180000Z/20090603T190000Z
- END:VFREEBUSY
- END:VCALENDAR
-
-
-
-
- mailto:mike@example.org
-
- 3.7;Invalid calendar user
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 70]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-B.6. Example: User Attempting to Invite "Attendee" on Behalf of
- "Organizer"
-
- In the following example, Cyrus attempts to create, on behalf of
- Wilfredo, an event with Bernard specified as an "Attendee". The
- request fails, since Wilfredo didn't grant Cyrus the right to invite
- other calendar users on his behalf.
-
- >> Request <<
-
- PUT /home/wilfredo/calendars/work/def456.ics HTTP/1.1
- Host: cal.example.com
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
- If-None-Match: *
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VEVENT
- UID:3504F926D3AD
- SEQUENCE:0
- DTSTAMP:20090602T190221Z
- DTSTART:20090602T230000Z
- DTEND:20090603T000000Z
- TRANSP:OPAQUE
- SUMMARY:Dinner
- ORGANIZER;CN="Wilfredo Sanchez Vega":mailto:wilfredo@example.com
- ATTENDEE;CN="Wilfredo Sanchez Vega";CUTYPE=INDIVIDUAL;PARTSTAT=A
- CCEPTED:mailto:wilfredo@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=NE
- EDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@exampl
- e.net
- END:VEVENT
- END:VCALENDAR
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 71]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- >> Response <<
-
- HTTP/1.1 403 Forbidden
- Content-Type: application/xml; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-
- /home/wilfredo/calendars/outbox/
-
-
-
-
-
-B.7. Example: "Attendee" Declining an Instance of a Recurring Event
-
- In the following example, Bernard declines the second recurrence
- instance of a daily recurring event he's been invited to by Cyrus.
-
- >> Request <<
-
- PUT /home/bernard/calendars/work/4FD3AD926350.ics HTTP/1.1
- Host: cal.example.com
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
- If-Schedule-Tag-Match: "7775FB30-7534-489E-A79A-0EA147B933EB"
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- TZID:America/Montreal
- BEGIN:STANDARD
- DTSTART:20071104T020000
- RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- BEGIN:DAYLIGHT
- DTSTART:20070311T020000
- RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
-
-
-
-Daboo & Desruisseaux Standards Track [Page 72]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- END:VTIMEZONE
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185254Z
- DTSTART;TZID=America/Montreal:20090601T150000
- DTEND;TZID=America/Montreal:20090601T160000
- RRULE:FREQ=DAILY;INTERVAL=1;COUNT=5
- TRANSP:OPAQUE
- SUMMARY:Review Internet-Draft
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@exampl
- e.net
- END:VEVENT
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090603T183823Z
- RECURRENCE-ID;TZID=America/Montreal:20090602T150000
- DTSTART;TZID=America/Montreal:20090602T150000
- DTEND;TZID=America/Montreal:20090602T160000
- TRANSP:TRANSPARENT
- SUMMARY:Review Internet-Draft
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- DECLINED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@exampl
- e.net
- END:VEVENT
- END:VCALENDAR
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Content-Length: 0
- Date: Tue, 02 Jun 2009 18:52:54 GMT
- Last-Modified: Tue, 02 Jun 2009 18:52:54 GMT
- ETag: "d85561cfe74a4e785eb4639451b434fb"
- Schedule-Tag: "488177c8-2ea7-4176-a6cb-fab8cfccdea2"
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 73]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- Bernard's participation status update will cause his server to
- deliver a scheduling message to Cyrus. Cyrus's client will find the
- following reply message from Bernard in Cyrus's scheduling Inbox
- collection:
-
- >> Request <<
-
- GET /home/cyrus/calendars/inbox/9263504FD3AD.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 18:52:58 GMT
- Last-Modified: Tue, 02 Jun 2009 18:52:58 GMT
- ETag: "eb897deabc8939589da116714bc99265"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- METHOD:REPLY
- BEGIN:VTIMEZONE
- TZID:America/Montreal
- BEGIN:STANDARD
- DTSTART:20071104T020000
- RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- BEGIN:DAYLIGHT
- DTSTART:20070311T020000
- RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- END:VTIMEZONE
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090603T183823Z
- RECURRENCE-ID;TZID=America/Montreal:20090602T150000
- DTSTART;TZID=America/Montreal:20090602T150000
- DTEND;TZID=America/Montreal:20090602T160000
- SUMMARY:Review Internet-Draft
-
-
-
-Daboo & Desruisseaux Standards Track [Page 74]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";PARTSTAT=DECLINED:
- mailto:bernard@example.net
- REQUEST-STATUS:2.0;Success
- END:VEVENT
- END:VCALENDAR
-
-B.8. Example: "Attendee" Removing an Instance of a Recurring Event
-
- In the following example, Bernard removes from his calendar the third
- recurrence instance of a daily recurring event he's been invited to
- by Cyrus. This is accomplished by the addition of an "EXDATE"
- property to the scheduling object resource stored by Bernard.
-
- >> Request <<
-
- PUT /home/bernard/calendars/work/4FD3AD926350.ics HTTP/1.1
- Host: cal.example.com
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
- If-Schedule-Tag-Match: "488177c8-2ea7-4176-a6cb-fab8cfccdea2"
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- BEGIN:VTIMEZONE
- TZID:America/Montreal
- BEGIN:STANDARD
- DTSTART:20071104T020000
- RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- BEGIN:DAYLIGHT
- DTSTART:20070311T020000
- RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- END:VTIMEZONE
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090602T185254Z
- DTSTART;TZID=America/Montreal:20090601T150000
- DTEND;TZID=America/Montreal:20090601T160000
-
-
-
-Daboo & Desruisseaux Standards Track [Page 75]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- RRULE:FREQ=DAILY;INTERVAL=1;COUNT=5
- EXDATE;TZID=America/Montreal:20090603T150000
- TRANSP:OPAQUE
- SUMMARY:Review Internet-Draft
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@exampl
- e.net
- END:VEVENT
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090603T183823Z
- RECURRENCE-ID;TZID=America/Montreal:20090602T150000
- DTSTART;TZID=America/Montreal:20090602T150000
- DTEND;TZID=America/Montreal:20090602T160000
- TRANSP:TRANSPARENT
- SUMMARY:Review Internet-Draft
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
- mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";CUTYPE=INDIVIDUAL;PARTSTAT=
- DECLINED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:bernard@exampl
- e.net
- END:VEVENT
- END:VCALENDAR
-
- Bernard's deletion of a recurrence instance will cause his server to
- deliver a scheduling message to Cyrus. Cyrus's client will find the
- following reply message from Bernard in Cyrus's scheduling Inbox
- collection:
-
- >> Request <<
-
- GET /home/cyrus/calendars/inbox/6504923FD3AD.ics HTTP/1.1
- Host: cal.example.com
-
- >> Response <<
-
- HTTP/1.1 200 OK
- Date: Tue, 02 Jun 2009 18:52:58 GMT
- Last-Modified: Tue, 02 Jun 2009 18:52:58 GMT
- ETag: "eb897deabc8939589da116714bc99265"
- Content-Type: text/calendar; charset="utf-8"
- Content-Length: xxxx
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 76]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
- BEGIN:VCALENDAR
- VERSION:2.0
- PRODID:-//Example Corp.//CalDAV Client//EN
- METHOD:REPLY
- BEGIN:VTIMEZONE
- TZID:America/Montreal
- BEGIN:STANDARD
- DTSTART:20071104T020000
- RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
- TZNAME:EST
- TZOFFSETFROM:-0400
- TZOFFSETTO:-0500
- END:STANDARD
- BEGIN:DAYLIGHT
- DTSTART:20070311T020000
- RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
- TZNAME:EDT
- TZOFFSETFROM:-0500
- TZOFFSETTO:-0400
- END:DAYLIGHT
- END:VTIMEZONE
- BEGIN:VEVENT
- UID:9263504FD3AD
- SEQUENCE:0
- DTSTAMP:20090603T183823Z
- RECURRENCE-ID;TZID=America/Montreal:20090603T150000
- DTSTART;TZID=America/Montreal:20090603T150000
- DTEND;TZID=America/Montreal:20090603T160000
- SUMMARY:Review Internet-Draft
- ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com
- ATTENDEE;CN="Bernard Desruisseaux";PARTSTAT=DECLINED:
- mailto:bernard@example.net
- REQUEST-STATUS:2.0;Success
- END:VEVENT
- END:VCALENDAR
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 77]
-
-RFC 6638 CalDAV Scheduling June 2012
-
-
-Authors' Addresses
-
- Cyrus Daboo
- Apple Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
- Bernard Desruisseaux
- Oracle Corporation
- 600 Blvd. de Maisonneuve West
- Suite 1900
- Montreal, QC H3A 3J2
- CANADA
-
- EMail: bernard.desruisseaux@oracle.com
- URI: http://www.oracle.com/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo & Desruisseaux Standards Track [Page 78]
-
diff --git a/doc/rfc6764-caldav-carddav-service-discovery.txt b/doc/rfc6764-caldav-carddav-service-discovery.txt
deleted file mode 100644
index aed17a83..00000000
--- a/doc/rfc6764-caldav-carddav-service-discovery.txt
+++ /dev/null
@@ -1,787 +0,0 @@
-
-
-
-
-
-
-Internet Engineering Task Force (IETF) C. Daboo
-Request for Comments: 6764 Apple Inc.
-Updates: 4791, 6352 February 2013
-Category: Standards Track
-ISSN: 2070-1721
-
-
- Locating Services for Calendaring Extensions to
- WebDAV (CalDAV) and vCard Extensions to WebDAV (CardDAV)
-
-Abstract
-
- This specification describes how DNS SRV records, DNS TXT records,
- and well-known URIs can be used together or separately to locate
- CalDAV (Calendaring Extensions to Web Distributed Authoring and
- Versioning (WebDAV)) or CardDAV (vCard Extensions to WebDAV)
- services.
-
-Status of This Memo
-
- This is an Internet Standards Track document.
-
- This document is a product of the Internet Engineering Task Force
- (IETF). It represents the consensus of the IETF community. It has
- received public review and has been approved for publication by the
- Internet Engineering Steering Group (IESG). Further information on
- Internet Standards is available in Section 2 of RFC 5741.
-
- Information about the current status of this document, any errata,
- and how to provide feedback on it may be obtained at
- http://www.rfc-editor.org/info/rfc6764.
-
-Copyright Notice
-
- Copyright (c) 2013 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 Simplified BSD License.
-
-
-
-
-
-Daboo Standards Track [Page 1]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-Table of Contents
-
- 1. Introduction ....................................................2
- 2. Conventions Used in This Document ...............................3
- 3. CalDAV SRV Service Labels .......................................3
- 4. CalDAV and CardDAV Service TXT Records ..........................4
- 5. CalDAV and CardDAV Service Well-Known URI .......................4
- 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. Well-Known URI Registrations ...............................9
- 9.1.1. caldav Well-Known URI Registration .................10
- 9.1.2. carddav Well-Known URI Registration ................10
- 9.2. Service Name Registrations ................................10
- 9.2.1. caldav Service Name Registration ...................10
- 9.2.2. caldavs Service Name Registration ..................11
- 9.2.3. carddav Service Name Registration ..................11
- 9.2.4. carddavs Service Name Registration .................12
- 10. Acknowledgments ...............................................12
- 11. References ....................................................12
- 11.1. Normative References .....................................12
- 11.2. Informative References ...................................14
-
-1. Introduction
-
- [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 the fully
- qualified domain name (FQDN) and port number for their servers.
-
- [RFC6352] 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 RRs as per [RFC6763].
-
-
-
-
-
-
-Daboo Standards Track [Page 2]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- 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.
- SRV service types for CardDAV are already defined in Section 11 of
- [RFC6352].
-
- Another issue with CalDAV or CardDAV service discovery is that the
- 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 RRs by themselves only provide an
- 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
- [RFC5785] of HTTP servers to provide a well-known URI for CalDAV or
- CardDAV services that clients can use. 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
- document are to be interpreted as described in [RFC2119].
-
-3. CalDAV SRV Service Labels
-
- This specification adds two SRV service labels for use with CalDAV:
-
- _caldav: Identifies a CalDAV server that uses HTTP without
- Transport Layer Security (TLS) [RFC2818].
-
- _caldavs: Identifies a CalDAV server that uses HTTP with TLS
- [RFC2818].
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 3]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- Clients MUST honor Priority and Weight values in the SRV RRs, as
- described by [RFC2782].
-
- Example: service record for server without TLS
-
- _caldav._tcp SRV 0 1 80 calendar.example.com.
-
- Example: service record for server with TLS
-
- _caldavs._tcp SRV 0 1 443 calendar.example.com.
-
-4. CalDAV and CardDAV Service TXT Records
-
- 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
- [RFC6763] 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.
-
- 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.
-
- Example: text record for service with TLS
-
- _caldavs._tcp TXT path=/caldav
-
-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, or 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
-
-
-
-
-Daboo Standards Track [Page 4]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- location of the redirect might change over time, then a "no-cache"
- value would be used.
-
- To facilitate "context paths" 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 FQDN and port
- number via an SRV lookup or via manual entry of information by the
- user, from which the client can parse suitable information. 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].
-
- 1. Processing user input:
-
- * For a CalDAV server:
-
- + 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 "bootstrapping" configuration can be done.
-
- + If the calendar user address is a "mailto:" [RFC6068] URI,
- the "mailbox" portion of the URI is examined, and the
- "local-part" and "domain" portions are extracted.
-
- + If the calendar user address is an "http:" [RFC2616] or
- "https:" [RFC2818] URI, the "userinfo" and "host" portion
- of the URI [RFC3986] is extracted.
-
-
-
-
-Daboo Standards Track [Page 5]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- * 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, and a password. The "mailbox" portion of the
- email address is examined, and the "local-part" and
- "domain" portions are extracted.
-
- 2. Determination of service FQDN and port number:
-
- * An SRV lookup for _caldavs._tcp (for CalDAV) or _carddavs._tcp
- (for CardDAV) is done with the extracted "domain" as the
- service domain.
-
- * If no result is found, the client can try _caldav._tcp (for
- CalDAV) or _carddav._tcp (for CardDAV) provided non-TLS
- connections are appropriate.
-
- * If an SRV record is returned, the client extracts the target
- FQDN and port number. If multiple SRV records are returned,
- the client MUST use the Priority and Weight fields in the
- record to determine which one to pick (as per [RFC2782]).
-
- * 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 TLS.
-
- 3. Determination of initial "context path":
-
- * 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".
-
- * 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).
-
- * If the initial "context path" derived from a TXT record
- generates HTTP errors when targeted by requests, the client
- SHOULD repeat its "bootstrapping" procedure using the
- appropriate ".well-known" URI instead.
-
-
-
-
-Daboo Standards Track [Page 6]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- 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 TLS negotiation is done immediately upon
- connection. The client MUST do certificate verification using
- the procedure outlined in Section 6 of [RFC6125] 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
- 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).
-
-
-
-
-
-
-Daboo Standards Track [Page 7]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- * 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 reuse
- those when connecting again at a later time.
-
- If a subsequent connection attempt fails, or authentication fails
- persistently, clients SHOULD retry 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 with "user identifiers" extracted from them. In
- the former case, the addresses MUST NOT conflict with other forms
- of a 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
- corresponds to the principal-URL of the user making the request.
-
- o If the service provider uses TLS, the service provider MUST ensure
- a certificate is installed that can be verified by clients using
- the procedure outlined in Section 6 of [RFC6125] in regard to
- verification with an SRV RR as the starting point. In particular,
- certificates SHOULD include SRV-ID and DNS-ID identifiers as
- appropriate, as described in Section 8.
-
- o Service providers should install the appropriate SRV records for
- the offered services and optionally include TXT records.
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 8]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-8. Security Considerations
-
- Clients that support TLS as defined by [RFC2818] 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 TLS, the client MUST NOT use any service
- information returned for the "_caldav" or "_carddav" services.
- Clients MUST follow the certificate-verification process specified in
- [RFC6125].
-
- A malicious attacker with access to the DNS server data, or that is
- 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 TLS is being used for the service,
- clients MUST use the procedure outlined in Section 6 of [RFC6125] to
- verify the service. When the target FQDN does not match the original
- service domain that was queried, clients MUST check the SRV-ID
- identifier in the server's certificate. If the FQDN does match,
- clients MUST check any SRV-ID identifiers in the server's certificate
- or, if no SRV-ID identifiers are present, MUST check the DNS-ID
- identifiers in the server's certificate.
-
- Implementations of TLS [RFC5246], used as the basis for TLS
- ([RFC2818]), typically support multiple versions of the protocol as
- well as the older SSL (Secure Sockets Layer) 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.
-
-9. IANA Considerations
-
-9.1. Well-Known URI Registrations
-
- This document defines two ".well-known" URIs using the registration
- procedure and template from Section 5.1 of [RFC5785].
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 9]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-9.1.1. caldav Well-Known URI Registration
-
- URI suffix: caldav
-
- Change controller: IETF
-
- Specification document(s): This RFC
-
- Related information: See also [RFC4791].
-
-9.1.2. carddav Well-Known URI Registration
-
- URI suffix: carddav
-
- Change controller: IETF
-
- Specification document(s): This RFC
-
- Related information: See also [RFC6352].
-
-9.2. Service Name Registrations
-
- This document registers four new service names as per [RFC6335]. Two
- are defined in this document, and two are defined in [RFC6352],
- Section 11.
-
-9.2.1. caldav Service Name Registration
-
- Service Name: caldav
-
- Transport Protocol(s): TCP
-
- Assignee: IESG
-
- Contact: IETF Chair
-
- Description: Calendaring Extensions to WebDAV (CalDAV) - non-TLS
-
- Reference: [RFC6764]
-
- Assignment Note: This is an extension of the http service. Defined
- TXT keys: path=
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 10]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-9.2.2. caldavs Service Name Registration
-
- Service Name: caldavs
-
- Transport Protocol(s): TCP
-
- Assignee: IESG
-
- Contact: IETF Chair
-
- Description: Calendaring Extensions to WebDAV (CalDAV) - over TLS
-
- Reference: [RFC6764]
-
- Assignment Note: This is an extension of the https service. Defined
- TXT keys: path=
-
-9.2.3. carddav Service Name Registration
-
- Service Name: carddav
-
- Transport Protocol(s): TCP
-
- Assignee: IESG
-
- Contact: IETF Chair
-
- Description: vCard Extensions to WebDAV (CardDAV) - non-TLS
-
- Reference: [RFC6352]
-
- Assignment Note: This is an extension of the http service. Defined
- TXT keys: path=
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 11]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-9.2.4. carddavs Service Name Registration
-
- Service Name: carddavs
-
- Transport Protocol(s): TCP
-
- Assignee: IESG
-
- Contact: IETF Chair
-
- Description: vCard Extensions to WebDAV (CardDAV) - over TLS
-
- Reference: [RFC6352]
-
- Assignment Note: This is an extension of the https service. Defined
- TXT keys: path=
-
-10. Acknowledgments
-
- This specification was suggested by discussion that took place within
- the Calendaring and Scheduling Consortium's CalDAV Technical
- 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.
-
-11. References
-
-11.1. Normative References
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
- Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
- 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 services (DNS SRV)", RFC 2782,
- February 2000.
-
- [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
-
-
-
-
-
-Daboo Standards Track [Page 12]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
- [RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
- Distributed Authoring and Versioning (WebDAV)
- Access Control Protocol", RFC 3744, May 2004.
-
- [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
- Resource Identifier (URI): Generic Syntax", STD 66,
- RFC 3986, January 2005.
-
- [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.
-
- [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.
-
- [RFC6068] Duerst, M., Masinter, L., and J. Zawinski, "The 'mailto'
- URI Scheme", RFC 6068, October 2010.
-
- [RFC6125] Saint-Andre, P. and J. Hodges, "Representation and
- Verification of Domain-Based Application Service Identity
- within Internet Public Key Infrastructure Using X.509
- (PKIX) Certificates in the Context of Transport Layer
- Security (TLS)", RFC 6125, March 2011.
-
- [RFC6335] Cotton, M., Eggert, L., Touch, J., Westerlund, M., and S.
- Cheshire, "Internet Assigned Numbers Authority (IANA)
- Procedures for the Management of the Service Name and
- Transport Protocol Port Number Registry", BCP 165,
- RFC 6335, August 2011.
-
- [RFC6352] Daboo, C., "CardDAV: vCard Extensions to Web Distributed
- Authoring and Versioning (WebDAV)", RFC 6352, August 2011.
-
- [RFC6763] Cheshire, S. and M. Krochmal, "DNS-Based Service
- Discovery", RFC 6763, February 2013.
-
-
-
-Daboo Standards Track [Page 13]
-
-RFC 6764 SRV for CalDAV & CardDAV February 2013
-
-
-11.2. Informative References
-
- [RFC5545] Desruisseaux, B., "Internet Calendaring and Scheduling
- Core Object Specification (iCalendar)", RFC 5545,
- September 2009.
-
-Author's Address
-
- Cyrus Daboo
- Apple Inc.
- 1 Infinite Loop
- Cupertino, CA 95014
- USA
-
- EMail: cyrus@daboo.name
- URI: http://www.apple.com/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Daboo Standards Track [Page 14]
-
diff --git a/gradle.properties b/gradle.properties
index 8bd86f68..b3c7a033 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-org.gradle.jvmargs=-Xmx1536M
+org.gradle.jvmargs=-Xmx2048M
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e6ffc1cc..37e706da 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/ical4android b/ical4android
index 70d40e72..9e6bc81c 160000
--- a/ical4android
+++ b/ical4android
@@ -1 +1 @@
-Subproject commit 70d40e726d6104e90aa0077db8fd5678328b0745
+Subproject commit 9e6bc81c1a4f953915f03bf02b2c173a58421c17
diff --git a/settings.gradle b/settings.gradle
index 6100cf62..0e8d35a9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -7,7 +7,6 @@
*/
include ':app'
-include ':dav4android'
include ':ical4android'
include ':vcard4android'
include ':cert4android'
diff --git a/vcard4android b/vcard4android
index 628ef73f..3250dc78 160000
--- a/vcard4android
+++ b/vcard4android
@@ -1 +1 @@
-Subproject commit 628ef73fa72bde2d8e4a3326b9683b58bbe11c8b
+Subproject commit 3250dc78fac3be16a14a9881a9526ac6ce0eaf58