CalDAV(Calendaring Extensions to WebDAV : RFC 4791)についてのまとめ
CalDAV(RFC 4791)とは、iCalendar(RFC 2445)をWebDAV(RFC 4918)上でやり取りするための仕様。
iCalendarは、スケジュールのカレンダー情報を記述するための仕様。
CalDAVはiCalendarをWebDAVプロトコルでやり取りするための仕組み。
iCalendarデータのMIMEタイプは「text/calendar」。
このMIMEタイプを持つカレンダー・スケジュールデータファイルには、拡張子「ics」が付けられる。(Mac OSではタイプコード「iCal」)
「free and busy time」(空いた時間と予定のある時間)を含むデータには拡張子「ftb」が付与される。(Mac OSではタイプコード「iFBf」)
iCalendarは概ね下記の階層で記述される。
- Calendar
- Component
- Property
- Component
Calendarは「BEGIN:VCALENDAR」で始まり「END:VCALENDAR」で終わる。
ComponentはCalendarの入れ子で
- イベント (VEVENT)
- カレンダー上で予定されたイベントについて記述された属性の集合体
- ToDo (VTODO)
- アクションアイテムや宿題事項のことが記述されるコンポーネント
- ジャーナル (VJOURNAL)
- 日誌のように特定の日付にコメントを付けたり、作業内容や進捗の実績を記録するために利用
- フリー・ビジータイム (VFREEBUSY)
- 空いた時間と予定のある時間を定義
- VTIMEZONE
- 時間帯を定義
- VALARM
- アラーム設定を定義
などがあり「BEGIN:[XXX]」で始まり「END:[XXX]」で終わる。
PropertyはCalendarやComponentの属性を定義する。
■iCalendarの例(1997年7月14日-15日のパリ祭)
BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT DTSTART:19970714T170000Z DTEND:19970715T035959Z SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR
カレンダーの参照
CalDAVで最も良く利用されるREPORTメソッドについて説明する。
REPORTメソッドは、CalDAV固有のメソッドで、iCalファイルを一度に取得するためのメソッド。
(ちなみに、CalDAV固有のメソッドはもうひとつMKCALENDARメソッドのみ。)
WebDAVでファイルを取得するためのメソッドはGETだが、
1月分のスケジュールを表示する場合には、複数のiCalファイルを一度に取得する必要がある。
通常、CalDAVで扱う1つのファイルにはVCALENDARが1つ入っており、VCALENDARには一つのVEVENTが入っている。
(繰り返しイベントのようにVCALENDARには複数のVEVENTが入る場合もある)
つまり、CalDAVサーバー上には、各イベントが1つのiCalファイルとして扱われる。
REPORTメソッドは、「2010年4月のイベントを取得する」や「未承認のイベントを取得する」、「繰り返しイベントをある期間展開して取得する」など条件に合ったiCalファイルを取得するためのメソッド。
以下は、2010年4月18日から4月24日のイベントGoogle Calendarから取得する電文。
REPORT /calendar/dav/test@gmail.com/events/ HTTP/1.1 Host: www.google.com Depth: 1 Content-Type: application/xml; charset="utf-8" Authorization: Basic XXXX Content-Length: 467 <?xml version="1.0" encoding="utf-8" ?> <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <D:getetag/> <C:calendar-data/> </D:prop> <C:filter> <C:comp-filter name="VCALENDAR"> <C:comp-filter name="VEVENT"> <C:time-range start="20060104T000000Z" end="20060105T000000Z"/> </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query>
検索条件はfilter要素に指定する。
filter要素には以下の3種類の条件が指定できる。
- comp-filter要素
- カレンダーのコンポーネントに対する条件文を指定
- comp-filter要素は、time-range要素または、comp-prop要素を指定可能
- 上記の例はcomp-filterにtime-range要素を指定している
- prop-filter要素
- カレンダーのコンポーネントに対する条件文を指定
- 子要素にパラメータを条件に指定するparam-filter要素を指定可能
- ただし、prop-filterが実装されているサーバーは多くは無い模様(Google CalendarとBedeworkはフィルターが効かない)
- param-filter要素
- カレンダーのコンポーネントのプロパティのパラメータに対する条件文を指定
上記のクエリーは以下の結果を返す。(ボディのみ記載)
<?xml version="1.0" encoding="UTF-8"?> <D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/calendar/dav/test%40gmail.com/events/test%40google.com.ics</D:href> <D:propstat> <D:status>HTTP/1.1 200 OK</D:status> <D:prop> <D:getetag>"63407192760"</D:getetag> <C:calendar-data xmlns:C="urn:ietf:params:xml:ns:caldav">BEGIN:VCALENDAR PRODID:-//Google Inc//Google Calendar 70.9054//EN VERSION:2.0 CALSCALE:GREGORIAN X-WR-CALNAME:Ichiro Suzuki X-WR-TIMEZONE:Asia/Tokyo BEGIN:VTIMEZONE TZID:Asia/Tokyo X-LIC-LOCATION:Asia/Tokyo BEGIN:STANDARD TZOFFSETFROM:+0900 TZOFFSETTO:+0900 TZNAME:JST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT DTSTART;VALUE=DATE:20100420 DTEND;VALUE=DATE:20100421 DTSTAMP:20100417T130600Z UID:test@google.com CREATED:20100417T130600Z DESCRIPTION: LAST-MODIFIED:20100417T130600Z LOCATION: SEQUENCE:0 STATUS:CONFIRMED SUMMARY:テスト TRANSP:TRANSPARENT BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:This is an event reminder TRIGGER:-P0DT0H10M0S END:VALARM END:VEVENT END:VCALENDAR</C:calendar-data> </D:prop> </D:propstat> </D:response> </D:multistatus>
上記の例では、カレンダーのプロパティをすべて取得する。
記の例では、カレンダーのプロパティをすべて取得します。
必要なプロパティのみを結果に含める場合には、calendar-data要素にcomp要素を指定します。
また、RRULEプロパティを含む繰り返しイベントは展開して取得することもできます。expand要素に展開する開始日(start属性)と終了日(end属性)を指定。
以下は、18日から3日間のみ繰り返しを展開するようにexpand要素を指定しています。また、結果が長くなるのでcomp要素により取得するプロパティも絞り込んでいる。
プロパティの指定と、繰り返しイベントの展開は、Google Calendarでは実装されていないので、以下はBedeworkに対して実行した結果。
<?xml version="1.0" encoding="UTF-8" ?> <multistatus xmlns="DAV:" xmlns:ns2="http://www.w3.org/2002/12/cal/ical#" xmlns:ns1="urn:ietf:params:xml:ns:caldav"> <response> <href>/ucaldav/user/test1/calendar/test.ics</href> <propstat> <prop> <ns1:calendar-data><![CDATA[BEGIN:VCALENDAR PRODID:BedeWork V3.5 VERSION:2.0 METHOD:REQUEST BEGIN:VEVENT DTSTAMP:20100417T143109Z SUMMARY:毎日 UID:test DTSTART:20100418T020000Z DTEND:20100418T030000Z RECURRENCE-ID:20100418T110000Z END:VEVENT END:VCALENDAR ]]></ns1:calendar-data> </prop> <status>HTTP/1.1 200 ok</status> </propstat> </response> <response> <href>/ucaldav/user/test1/calendar/test.ics</href> <propstat> <prop> <ns1:calendar-data><![CDATA[BEGIN:VCALENDAR PRODID:BedeWork V3.5 VERSION:2.0 METHOD:REQUEST BEGIN:VEVENT DTSTAMP:20100417T143109Z SUMMARY:毎日 UID:test DTSTART:20100419T020000Z DTEND:20100419T030000Z RECURRENCE-ID:20100419T110000Z END:VEVENT END:VCALENDAR ]]></ns1:calendar-data> </prop> <status>HTTP/1.1 200 ok</status> </propstat> </response> <response> <href>/ucaldav/user/test1/calendar/test.ics</href> <propstat> <prop> <ns1:calendar-data><![CDATA[BEGIN:VCALENDAR PRODID:BedeWork V3.5 VERSION:2.0 METHOD:REQUEST BEGIN:VEVENT DTSTAMP:20100417T143109Z SUMMARY:毎日 UID:test DTSTART:20100420T020000Z DTEND:20100420T030000Z RECURRENCE-ID:20100420T110000Z END:VEVENT END:VCALENDAR ]]></ns1:calendar-data> </prop> <status>HTTP/1.1 200 ok</status> </propstat> </response> </multistatus>
カレンダーの更新
イベントの追加と更新はPUTメソッドを使ってicsファイルをアップロードする。削除はDELETEメソッドを利用する。
リクエストボディには、追加するイベントVEVENTを含むカレンダーVCALENDARを指定する。
PUT https://www.google.com/calendar/dav/hrendoh@gmail.com/events/test@google.com.ics HTTP/1.1 Host: www.google.com Content-Type: text/calendar; charset="utf-8" Authorization: Basic xxx Content-Length: 258 BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Example Corp.//CalDAV Client//EN BEGIN:VEVENT UID:test@google.com DTSTAMP:20100426T160000Z DTSTART:20100426T170000Z DTEND:20100426T180000Z SUMMARY:Fiddlerから追加 END:VEVENT END:VCALENDAR
追加なのでレスポンスコードは201が返される。
HTTP/1.1 201 Created DAV: 1, calendar-access, calendar-schedule, calendar-proxy Content-Type: text/calendar; component=vevent; charset=UTF-8 Date: Sat, 24 Apr 2010 14:02:43 GMT Expires: Sat, 24 Apr 2010 14:02:43 GMT Cache-Control: private, max-age=0 X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block Content-Length: 0 Server: GSE
UIDとファイル名について
UIDは、コレクション(WebDAVのフォルダ)内でユニークな値を指定する。
また、PUTするカレンダーのファイル名は
(ただし、CalDAVでPUTする場合はUIDとファイル名があってなくても登録できる。)
イベントの編集
イベントの編集は、既存のURLに対してPUTを実行する。
追加のリクエストでSUMMARYのみ変更して実行する。
PUT https://www.google.com/calendar/dav/test@gmail.com/events/test@google.com.ics HTTP/1.1 Host: www.google.com Content-Type: text/calendar; charset="utf-8" Authorization: Basic xxx Content-Length: 258 BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Example Corp.//CalDAV Client//EN BEGIN:VEVENT UID:test@google.com DTSTAMP:20100426T160000Z DTSTART:20100426T170000Z DTEND:20100426T180000Z SUMMARY:Fiddlerから編集 END:VEVENT END:VCALENDAR
編集成功のレスポンスコードは204。
HTTP/1.1 204 No Content DAV: 1, calendar-access, calendar-schedule, calendar-proxy Date: Sat, 24 Apr 2010 15:24:09 GMT Server: GSE
イベントの削除
イベントの削除はDELETE。
DELETE https://www.google.com/calendar/dav/test@gmail.com/events/test@google.com.ics HTTP/1.1 Host: www.google.com Content-Type: text/calendar; charset="utf-8" Authorization: Basic xxx
削除成功のレスポンスコードは204。
HTTP/1.1 204 No Content DAV: 1, calendar-access, calendar-schedule, calendar-proxy Date: Sat, 24 Apr 2010 15:34:18 GMT Server: GSE
メモ
CalDAVで使用するHTTPメソッド
- ACL
- CONNECT
- COPY
- DELETE(DEL)
- eventやcollection(folder)をサーバから削除する
- DEL /user/calendar/myevent.ics
- eventやcollection(folder)をサーバから削除する
- GET
- eventを読取・検索する
- GET /user/calendar/myevent.ics
- ETAG(例えば"123124321524-1")も取得する
- ETAGはeventをバージョニングするために使われる文字
- myevent.icsが変更されたときにETAGは作成される
- eventを読取・検索する
- HEAD
- eventの存在を確認する
- evenのETAGのみを取得する
- LOCK
- MKCALENDAR
- サーバにcollection(foler)を作成する
- MKCOL
- MOVE
- OPTIONS
- Check which actions can be made on a resource
- POST
- PROPFIND
- PROPPATCH
- PUT
- eventをサーバに置く、あるいは更新する
- PUT /user/calendar/myevent.ics
- ETAGも返却される
- ETAGを変更することも可能
- eventをサーバに置く、あるいは更新する
- REPORT
- UID、LOCATION、SUMMARY等を使ってcollection(folder)にクエリを発行する
- REPORT /user/calendar/
- クエリはボディのXMLで表現する
- UID、LOCATION、SUMMARY等を使ってcollection(folder)にクエリを発行する
- TRACE
- UNLOCK
http://milton.io/reference/milton-api/apidocs/io/milton/http/Request.Method.html
ツール?
ライブラリ
- milton
- その他
- 日本語参考
- 誰かのGitHub
★RFC 4791原文
http://tools.ietf.org/html/rfc4791
★RFC 4791日本語1
http://webos-goodies.jp/attachments/caldav_spec/caldav_spec.html
★RFC 4791日本語2
http://pentan.info/doc/rfc/j4791.html