Contact Importing

The first rule of CardDAV is…

Why is it so hard to find information about CardDav? We attempt to demystify some of the more obscure aspects of the standard.

Share:

The is no getting around it. CardDAV is complicated. CardDAV is confusing. But CardDAV is not impossible. I know. I built a CardDAV client for CloudSponge to power our integrations for iCloud, AOL and others.

Building a CardDAV client does take some tenacity because there are very few readable resources out there. You end up reading the RFC many times over until the ideas take shape and it becomes possible to implement. Either that or it puts you to sleep and you try again tomorrow.

Tired of reading CardDAV RFCs? We can help. Our Contacts API abstracts the hard stuff.

So what are the hardest parts about CardDAV? In this article, I’m going to address one of the more complicated challenges: Reading multiple contacts at once.


Get the VCards in a single request

As long as you have a list of the VCard URIs, you can request many of them at once using the REPORT method and the addressbook-multiget payload.

There’s an HTTP verb for this: REPORT. CardDAV calls this an addressbook-multiget request. Inside this request, you’ll send an array of all the URIs you want to retrieve as hrefs.

I’ll assume that you already have your VCard URIs and show you an example of such a request and response.

With a request like:

REPORT /home/username/contacts/
<c:addressbook-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
  <d:prop>            <--- tell the server which properties you want...
    <d:getetag />
    <c:address-data>
      <c:allprop />   <--- I want all the address book data
    </c:address-data>
  </d:prop>
  <d:href>/home/username/contacts/vcard001.vcf</d:href>
  <d:href>/home/username/contacts/vcard002.vcf</d:href>
</c:addressbook-multiget>

You may get a response like:

HTTP/1.1 207 Multi-Status
<?xml version="1.0" encoding="utf-8" ?>
<d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
  <d:response>
    <d:href>/home/username/contacts/vcard001.vcf</d:href>
    <d:propstat>
      <d:prop>
        <d:getetag>"dd49fe-7a1265"</D:getetag>
        <c:address-data>BEGIN:VCARD
VERSION:4.0
NICKNAME:Admiral Ackbar
FN:Gial Ackbar
EMAIL:gialackbar@example.com
END:VCARD
        </c:address-data>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/home/username/contacts/vcard002.vcf</d:href>
    <d:status>HTTP/1.1 404 Resource not found</d:status>
  </d:response>
</d:multistatus>

Notice, I’ve bolded a few lines to draw attention to them. Firstly, the response code is an unusual 207 which indicates that the overall request was successful, but that individual responses should be inspected.

The payload contains an array of response nodes. Each one contains its own status. I’ve highlighted the two responses in the sample payload. The first is a friendly 200. The second, a 404.

This is the trick with the multiget request: each requested entity has its own status.

Now that you’ve retrieved the VCards, you can inspect each one that has a successful response and pull out the VCard from the address-data node.

Here’s where you’ll find the addressbook-multiget description and some examples in RFC6352.

Tired of reading CardDAV RFCs? We can help. Our Contacts API abstracts the hard stuff.

Graeme Rouse, CTO at CloudSponge

Follow @thunderouse

Comments

Try CloudSponge for free in your
testing environment

Get Started

Have a questions or prefer a guided tour?
Schedule a consultation with our Founder.