2008年11月13日木曜日

CalDAVクライアントの実装2

CalDAVのプロトコルの解析をする前に、基本的なところをRFCを見ておさえておく。

CalDAVは、WebDAV上に実装さえているので、WebDAVの機能を含んでいる必要があるらしい。また、WebDAVは、HTTP上に実装されるべきものなので、当然それも含む。

というころなので、CalDAVは、HTTPの機能がわかっていれば、大体実装できそうである。RFCによると、CalDAVで使用するコマンドは、大体次のようになる。


  OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
 PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL

この中で、今回実装しようと思っている、スケジュールの参照、登録、修正、削除に関するものは、REPORT(参照)、PUT(登録、編集)、DELETE(削除)ということがわかった。


他の命令は、サーバーが決まっていないと色々やることがあるが、今回のCalDAVサーバーは、Chandlerということにするとこれで十分だろう。あとは、個人認証とHTTPの基本的な動作とXMLのパージング、iCalendar形式の対応部分をを実装すればよいことになる。
さて次に、CalDAVクライアントを実装する言語なのだが、GUIの実装は面倒なので、ブラウザを利用することにする。ちょうど以前グループウェアを実装したものがあるので、ほとんどは、これを流用する。
てなわけで、PHPで実装することに決定。

PHPは、サーバーでCGI風に使うことがほとんどだが、今回は、CalDAVクライアントつまりHTTPクライアントとして実装する。PHPには、cURLやHTTPの拡張モジュールがあるので、これらを利用することにした。

また、XMLのパージングなのだが、PHPのDOMを使うほうがよい気がするが、とりあえずフリーで公開されているxml2array.phpというライブラリを使わせていただく。

とりあえずツールの準備はできたので、実装開始。
まずは、個人認証。

個人認証は、大したことはない。http_request関数の option変数で


option["httpauth"] = $username.":".$password
option["httpauthtype"] = HTTP_AUTH_BASIC または HTTP_AUTH_DIGEST


ChandlerServer のときはBASIC認証なので、HTTP_AUTH_BASIC で大丈夫。
次に、CalDAVにおける基本的なリクエストは、option変数のheaderで、

 "Content-Type" => "text/xml"
"User-Agent" => "エージェント名"
"Accept" => "text/xml"
"Connection" => "keep-alive"
"Depth" => "1"
"Keep-Alive" => "300"


を設定する。さらに、新規のイベント作成時は、

"Content-Type" => "text/calendar
"If-None-Match" => "*"

イベントの編集、削除時は、

  "Content-Type" => "text/calendar
"If-Match" => 編集、削除するイベントのEtag

とすればよい。
あとは、それぞれのアクションに応じて、XML 形式のデータを一緒に送ってあげれば、サーバーから、それに応じて XML形式のレスポンスがあるので、解析して、出力にまわせば完成です。

参考までに、期間を指定して、イベントを取得する場合には、下記のようにすればよい。


function RequestEvent($start=null, $end=null){
$this->body =<<<_XML
<?xml version="1.0" encoding="UTF-8">
<calendar-query xmlns="urn:ietf:params:xml:ns:caldav" d="DAV:">
<D:prop>
<D:getetag/>
</d:prop>
<filter>
<comp-filter name="VCALENDAR">
<comp-filter name="VEVENT">
_XML;
if($start){
if($end){
$this->body .= "<time-range end=\"".$end."\" start=\"".$start."\">";
}else{
$this->body .= "<time-range end=\"".$end."\" start=\"".$start."\">";
}
}
$this->body .=<<<_XML
</COMP-FILTER>
</filter>
</CALENDAR-QUERY>
_XML;
}

これからもわかるように、のタグのところに条件を書けは、それに応じた結果(結果もどの情報が必要かを書けば、選択的に取得できるが、面倒なので全部返すようにしている。あとは、iCalendar形式のデータを解析すればよいので。)を取得できるようになっている。

0 件のコメント: