言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

WebDAV プロトコルに挑戦

接続

nc (netcat) というプログラムを使うと簡単にプロトコルの実験を出来ます。
例えば ローカルの 8080 ポートに接続するには以下のようにします。

nc localhost 8080

ディレクトリに含まれるファイルの取得

PROPFIND /svn/ HTTP/1.0
Depth: 1
Content-Lengh: 0

大量に出てくるプロパティから、/multistatus/response/href の中にファイル名の参照が現れます。以下のように欲しいプロパティだけ書いた方がラクです。

PROPFIND /svn/ HTTP/1.0
Depth: 1
Content-Length: 96

<propfind xmlns="DAV:">
 <prop>
  <getlastmodified/>
  <getcontentlength/>
 </prop>
</propfind>

ファイルの保存

PUT /svn/test.txt HTTP/1.0
Content-Length: 11

Hello DAV!

ファイル内容の取得

GET /svn/text.txt HTTP/1.0

リネーム

MOVE /svn/test.txt HTTP/1.0
Destination: http://localhost:8080/svn/test2.txt

履歴

まずファイルのプロパティをから最新バージョン名 version-name を取得。

PROPFIND /svn/test2.txt HTTP/1.0
Content-Length: 66

<propfind xmlns="DAV:">
 <prop><version-name/></prop>
</propfind>

例えばこれで 21 と出た場合、その数字を元に履歴を求める。残念ながら、ここはちょっと醜悪で、Subversion に特化したプロトコルになってるみたいです。

REPORT /svn/test2.txt HTTP/1.0
Content-Length: 139

<S:log-report xmlns:S="svn:">
<S:start-revision>21</S:start-revision>
<S:end-revision>1</S:end-revision>
<S:path></S:path>
</S:log-report>

過去のバージョンのファイルを取得

さて、例えばバージョン 19 のドキュメントが欲しいとする。version-controlled-configuration と baseline-relative-path というプロパティを取得する。

PROPFIND /svn/test2.txt HTTP/1.0
Content-Length: 167

<propfind xmlns="DAV:">
 <prop>
  <version-controlled-configuration/>
  <baseline-relative-path xmlns="http://subversion.tigris.org/xmlns/dav/"/>
 </prop>
</propfind>

version-controlled-configuration(/svn/!svn/vcc/default) を使って、バージョン 19 の baseline-collection を求める。

PROPFIND /svn/!svn/vcc/default HTTP/1.0
Label: 19
Content-Length: 78

<propfind xmlns="DAV:">
 <prop>
  <baseline-collection/>
 </prop>
</propfind>

得た baseline-collection (/svn/!svn/bc/19/) と baseline-relative-path (test2.txt) を組み合わせてドキュメントを取得する

GET /svn/!svn/bc/19/test2.txt HTTP/1.0

ブラウザでざくっと過去を確認する。

例えば http://localhost:8080/svn/!svn/bc/17/ のようなURLにアクセスすると、とあるバージョン(この場合 17) のスナップショットへアクセス出来ます。

便利ツール

nc (netcat)

telnet の代わりに使う。便利。cygwin の setup.exe でインストールできます。

$ nc localhost 8080 | tee log.txt  
cadavar

コマンドラインの DAV クライアント。これも cygwin。残念ながらバージョン機能は svn と互換性がありません。

$ cadaver http://localhost:8080/svn/ 
dav:/svn/> set namespace DAV:
dav:/svn/> propget . getlastmodified
tcpflow

パケットキャプチャ Ethereal の補助として使う。Ethereal より手軽で使いやすい。

$ sudo tcpflow -C port 80 and host
cygwin で文字化け

日本語は諦める

export LC_MESSAGES=C