連載
» 2003年10月23日 00時00分 UPDATE

現場に活かすJakarta Project(11):TomcatでWebDAVを実現

[横田健彦,(株)東芝]

 今回はいつものように開発ツールとしてのJakartaプロダクトの利用方法ではなく、アプリケーションとしてのJakartaプロダクトの利用方法をご紹介します。ご紹介するのはJakarta Tomcatに付属しているWebdavServletです。WebdavServletを用いるとWebDAVプロトコルを使ったファイル共有サーバを手軽に構築することができます。

WebDAVとは

 まず、WebDAVとは何かを簡単にご説明します。通常WebブラウザなどからWebサーバにアクセスする場合はHTTPプロトコルを用いて通信を行いますが、HTTPはWebページを取得したりファイルをダウンロードしたりすることを第一に考えて作成されたプロトコルですので、Webページを編集したりファイルをアップロードしたりすることは得意ではありません。その問題点を解決するためにWebDAVが考案されました。

 WebDAVとはWeb-based Distributed Authoring and Versioningの略で、Web上で分散オーサリングを行うためのHTTPの拡張プロトコルです。具体的にはRFC 2518「HTTP Extensions for Distributed Authoring -- WEBDAV」で定義されていますので詳しくはそちらを参照してください。また、WebDAVに関する日本語の情報がWebDAV Resources JPで公開されていますのでそちらも参照してみてください。

 WebDAVを用いるとWebページの編集が遠隔地から手軽に行えるようになるだけではありません。WebDAVサーバを構築してネットワークに接続しておけば、WebDAVクライアントを用いて遠隔地からネットワーク経由でファイルを置いたりダウンロードしたりができるファイルサーバにもなります。

 ファイルサーバを構築するためには通常FTPが用いられることが多いですが、WebDAVではFTPと異なり、Webを閲覧するためのポートだけを利用して通信を行います。そのため、例えば企業などでファイアウォールによって外部との通信が制限されている場合でも、Webを閲覧するためのポートさえ開いていればファイアウォールの設定を変更しなくても外部とファイル交換が行えるという利点があります。

 WebDAVサーバとして最も多く用いられているのはおそらくApacheとmod_davの組み合わせでしょう。特に日本では、これらに日本語ファイル名を扱うためのmod_encodingというモジュールを組み合わせたWebDAVサーバが最も多く用いられていると思います。筆者はWebDAV-jpメーリングリストに入っているのですが、実際メーリングリストに投稿される記事の大半がApacheとmod_davとmod_encodingに関するものです。

 そういう状況ですので、WebDAVサーバを構築したければApache+mod_davを使えばよいのかもしれませんが、それではJavaプログラマとしては面白くありませんし、Apacheを用いずにTomcatだけを用いてWebサイトを構築している場合にはわざわざApacheを導入するのは大変です。そこで、ここではTomcatを用いたWebDAVサーバの構築方法をご紹介したいと思います。

WebdavServletを用いたWebDAVサーバ構築

 Tomcat 4.1にはWebdavServletというWebDAVサーバを実現するためのServletが付属しています。これを用いることで手軽にWebDAVサーバを構築することができます。以下、Linux環境でTomcat 4.1.27を用いた場合について説明します。なおTomcatのインストールは完了しているものとします。また、以下の説明中ではTomcatのインストールディレクトリを$CATALINA_HOME、TomcatのトップページのURLをhttp://tomcat.server:8080/と書くことにします。

 それではWebDAVサーバを構築していきましょう。……といいたいところですが、実はTomcatのインストールアーカイブにはWebdavServletを用いたWebアプリケーション(以下、webdav Webアプリケーションと呼びます)が含まれており、Tomcatをインストールして起動すると自動的にhttp://tomcat.server:8080/webdavに配備され、WebDAVサーバとして利用できるようになっています。ですから特別な構築手順は必要ありません。

 次はWebDAVクライアントを用意します。ここではWindows 2000に付属のWebフォルダというWebDAVクライアントからwebdav Webアプリケーションにアクセスするための設定を行います。

 まずWebフォルダを作成します。「マイネットワーク」アイコンを開いて、「ネットワークプレースの追加」アイコンをダブルクリックします。図1のようなダイアログが表示されますので、「ネットワークプレースの場所を入力してください」と書かれているテキストボックスにwebdav WebアプリケーションのURLを入力して「次へ」ボタンを押します。

図1 ネットワークプレースの追加画面 図1 ネットワークプレースの追加画面

 webdav Webアプリケーションとの通信を正常に行うことができれば、図2のような完了画面が表示されますので、「完了」ボタンを押します。

図2 ネットワークプレースの追加の完了画面 図2 ネットワークプレースの追加の完了画面

 これで、図3のようなWebフォルダが開きます。Webフォルダのトップディレクトリはwebdav Webアプリケーションのトップディレクトリ、つまりサーバの$CATALINA_HOME/webapps/webdavディレクトリ(以下$WEBDAV_HOMEと書きます)と対応しており、開いたフォルダの中には、$WEBDAV_HOMEディレクトリにあるファイルが一覧表示されます()。

注:WEB-INFディレクトリとMETA-INFディレクトリは表示されません。

図3 Webフォルダを開いたところ 図3 Webフォルダを開いたところ

 ここで例えばディレクトリ中の「tomcat.gif」アイコンをダブルクリックすると、Webフォルダ経由でwebdav Webアプリケーションからファイルがダウンロードされ、見慣れたTomcatのイメージがWebブラウザで表示されます。さて、このまま使い続けてもよいのですが、実はwebdav Webアプリケーションは標準状態では読み出し専用モードになっていたりアクセス制限が設定されていなかったりと、そのままで利用するにはやや不便な設定になっています。そこで以下ではwebdav Webアプリケーションを活用するための次のようなTipsをご紹介したいと思います。

  • アクセス制限を行う
  • ファイルの書き込みを許可する
  • JSPファイルを扱えるようにする
  • 日本語ファイル名を扱えるようにする
  • シンボリックリンクをたどるようにする

(なお、以下の説明ではwebdav Webアプリケーション用のweb.xmlファイルを適宜修正していますが、修正後のweb.xmlをダウンロードできるようにしておきますので参考にして下さい。)

アクセス制限を行う

 インストール直後の状態ではアクセス制限がかけられていないため、だれでも自由にWebDAVサーバにアクセスできてしまいます。そこで指定したユーザーだけがアクセスできるようにアクセス制限をかけることにします。

 アクセス制限をかけるには、Servlet仕様に従ってweb.xmlにアクセス制御のためのエントリを追加すればよいのですが、webdav Webアプリケーションのweb.xmlはすでにBASIC認証による簡単なアクセス制御のためのエントリがコメントアウトされた形で用意されていますので、ここではそれを使うことにします。具体的には$WEBDAV_HOME/WEB-INF/web.xmlの中の「Security Constraints for Testing」と書いてある部分のコメントアウトを解除します。コメントアウトを解除する部分を以下に記します。

<security-constraint>
  <web-resource-collection>
    <web-resource-name>The Entire Web Application</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>tomcat</role-name>
  </auth-constraint>
</security-constraint>

<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>Tomcat Supported Realm</realm-name>
</login-config>

<security-role>
  <description>
    An example role defined in "conf/tomcat-users.xml"
  </description>
  <role-name>tomcat</role-name>
</security-role>

 デフォルトではアクセスを許可するロールが<role-name>タグで「tomcat」と指定されていますので、tomcatロールに属するユーザだけがアクセスできます。アクセスを許可するロールを例えば「webdav」に変更したければ、$CATALINA_HOME/conf/tomcat-users.xmlに次のようにwebdavロールのエントリを追加し、webdavロールのエントリを追加し、web.xmlの中の<role-name>タグで指定されているロール名を「webdav」に変更します(2カ所)。

<role rolename="webdav"/>

 webdavロールにユーザーを追加するには、tomcat-users.xmlの中に例えば次のようにユーザーのエントリを追加したりユーザーエントリにロールを追加したりします。

<user username="user" password="pass" roles="webdav"/>

 Tomcatを再起動すれば、指定したロールに属するユーザーからのアクセスだけを受け付けるようになります(図4)。

図4 アクセス制限がかけられたWebフォルダ 図4 アクセス制限がかけられたWebフォルダ

ファイルの書き込みを許可する

 webdav Webアプリケーションはインストール直後の状態では読み込み専用になっているため、ファイルのダウンロードはできてもファイルをアップロードすることはできません。ファイルのアップロードを許可するには、以下のコードの太字の部分のように$WEBDAV_HOME/WEB-INF/web.xmlの<servlet>タグの中のreadonlyパラメータに関する設定のコメントアウトを解除します。Webアプリケーションを再起動すると()、Webフォルダにファイルをドロップすることでそのファイルをアップロードすることができるようになります。

注:Webアプリケーションが修正された場合に自動的に再起動するようにTomcatが設定されていれば、明示的にWebアプリケーションを再起動する必要はありません。

<servlet>
  <servlet-name>webdav</servlet-name>
  <servlet-class>org.apache.catalina.servlets.WebdavServlet</servlet-class>
  <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
  </init-param>
  
<init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
  </init-param>
  <!-- Uncomment this to enable read and write access -->
  <init-param>
    <param-name>readonly</param-name>
    <param-value>false</param-value>
  </init-param>
  <!--load-on-startup>1</load-on-startup-->
</servlet>

JSPファイルを扱えるようにする

 WebフォルダにJSPファイル(拡張子が.jspであるようなファイル)をドロップしてみてください。アップロードに失敗すると思います。これは、拡張子が.jspであるファイルはwebdav Webアプリケーションが処理する前にTomcatのJSP Servletが処理しようとしてしまうためです。WebDAVサーバではJSPを実行する必要はありませんから、JSPファイルについてもほかのファイルと同様にファイルそのものをアップロードしたりダウンロードしたりできるようにしておきましょう。

 JSPファイルを通常のファイルと同様にwebdav Webアプリケーションに処理させるには、$WEBDAV_HOME/WEB-INF/web.xmlに次のような<servlet-mapping>エントリを追加します。

<servlet-mapping>
  <servlet-name>webdav</servlet-name>
  <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

 Webアプリケーションを再起動すると、JSPファイルを通常のファイルと同じように扱うことができるようになります。

 なお、webdav Webアプリケーションのインストール直後の設定でJSPファイルを扱えない問題についてはApache Bug DatabaseBug 11542として報告されていますので、将来のバージョンでは修正されるかもしれません。

日本語ファイル名を扱えるようにする

 お気付きの方もいらっしゃるかもしれませんが、webdav WebアプリケーションとWebフォルダの組み合わせでは日本語の名前を持つファイルを扱うことができません。例えば「議事録.txt」という名前のファイルをWebフォルダにドロップするとエラーが発生してうまくアップロードすることができません。これは、Windows 2000のWebフォルダが日本語のファイル名をWindowsの標準の文字エンコーディングであるシフトJISのままwebdav Webアプリケーションに送信しているためです。

 WebDAVはHTTPの拡張プロトコルですので、WebDAVクライアントからWebDAVサーバにリクエストが送信されるときには操作対象のファイルパスがURLとして送信されます。このとき日本語のようにURLにそのまま含めることができない文字については何らかの方式でエスケープする必要がありますが、Tomcatの場合にはUTF-8でエンコードしたうえで%XX形式にエスケープする必要があります。ところがWindows 2000のWebフォルダは日本語などの文字をシフトJISのまま送信するため、Tomcat側でURLの解析に失敗してファイル名が文字化けしてしまい、結果としてファイルの操作に失敗してしまうのです()。

注:逆に、URLに直接含めることのできない文字をUTF-8でエンコードして%XX形式にエスケープしたうえでWebDAVサーバに送信するようなクライアントを使えば、本稿で説明する方法を用いずにそのまま日本語ファイル名を扱うことができます。そのようなWebDAVクライアントとしては、例えばSouth River Technologies社から販売されているWebDriveがあります。

COLUMN

WebDAVにおけるファイル名のエンコーディングについて

WebDAVを定義しているRFC 2518ではファイル名のエンコーディング方法に関しては明確に定義していません。しかしながら、WebDAVプロトコルがデータのやりとりにXMLを用いていること、XMLではUTF-8が標準的に用いられていること、URLのスキームについて規定しているRFC 2718でもUTF-8が推奨されていることから、WebDAVクライアントやWebDAVサーバでは一般的にUTF-8を扱えるようになっていることが多いようです。そういう点で、URLに直接シフトJISコードを含めてしまうWindows 2000のWebフォルダは「お行儀の悪い」アプリケーションであるといえます。


 この問題を解決するには、何らかの方法でWebフォルダが送信するURLをTomcatが正しく解釈できる形式に変換してやる必要があります。ここでは、この変換を行うために拙作のServletフィルタであるwebdav-jp.jarを利用することにします。(なおこのServletフィルタを組み込み済みのwebdav Webアプリケーションを筆者のサイトにて公開していますので、よろしければ使ってみてください)。

 $WEBDAV_HOME/WEB-INF/libディレクトリを作成して、ダウンロードしたwebdav-jp-0.1.3.jarをlibディレクトリにコピーしておきます。そのうえで、以下のように$WEBDAV_HOME/WEB-INF/web.xmlの<web-app>タグの中の<servlet>タグの前に次のエントリを追加します。

<filter>
  <filter-name>requestURIDecodingFilter</filter-name>
  <filter-class>net.skirnir.catalina.servlets.
RequestURIDecodingFilter</filter-class>
  <init-param>
    <param-name>nativeEncoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>urlEncoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>nativeEncoding.
Microsoft Data Access Internet Publishing Provider DAV 1.1</param-name>
    <param-value>MS932</param-value>
  </init-param>
  <init-param>
    <param-name>urlEncoding.
Microsoft Data Access Internet Publishing Provider DAV 1.1</param-name>
    <param-value>MS932</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>requestURIDecodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

 これでwebdav Webアプリケーションがリクエストを処理する前にwebdav-jpのServletフィルタが呼び出され、日本語を含むURLが適切に変換されるようになります。なお上記の設定はWindows 2000のWebフォルダ用になっていますが、パラメータを追加することでほかのWebDAVクライアントにも対応させることができます。詳しくは筆者のサイトにて公開しているwebdav-jpに付属のREADMEを参照してください。

シンボリックリンクをたどるようにする

 Tomcat 4.1では、セキュリティ上の理由からデフォルトではWebアプリケーションのディレクトリにあるシンボリックリンクをたどらないようになっています()。webdav Webアプリケーションでシンボリックリンクをたどるようにするには、$CATALINA_HOME/conf/server.xmlに次のエントリを追加する必要があります。

注:正確にはWebアプリケーションのディレクトリの外にあるファイルやディレクトリへのシンボリックリンクをたどらないようになっています。

<Context path="/webdav" docBase="webdav" debug="0"
         reloadable="false" crossContext="true">
  <Resources className="org.apache.naming.resources.FileDirContext"
             allowLinking="true" />
</Context>

 server.xmlの中の<Context>タグは、Webアプリケーションを配備するためのタグです。$CATALINA_HOME/webapps以下に置いたWebアプリケーションについては明示的に<Context>タグを追加しなくても自動的に配備されますが、シンボリックリンクをたどるようにするには<Context>タグ中の<Resources>タグのallowLinking属性の値をtrueにする必要があるため、ここでは明示的にwebdav Webアプリケーション用の<Context>タグを追加します。

COLUMN

Tomcatのバージョンとシンボリックリンクの有効/無効について

Tomcat 4.1ではセキュリティ上の理由からWebアプリケーションの外へのシンボリックリンクをたどらないようになっていますが、Tomcat 4.1.10まではallowLinking属性がなかったため、シンボリックリンクを有効にすることができませんでした。その後、Tomcat 4.1.11からallowLinking属性が追加されましたが、Tomcat 4.1.12までは「/WEB-INF/libにJARファイルを持つようなWebアプリケーションを配備するように$CATALINA_HOME/conf/server.xmlに<Context>タグを書き、その中に<Resources>タグをネストするとそのWebアプリケーションをうまく配備できないことがある」というTomcatのバグのために、実際はallowLinking属性を指定できないことがありました。このバグはTomcat 4.1.13以降では修正されているため、Tomcat 4.1.13以降については本稿で説明したようにallowLinking属性を用いて問題なくシンボリックリンクを有効にすることができます。


おわりに

 これまでの連載とは違い、ツールやライブラリではなくアプリケーションとしてのJakartaプロダクトの活用方法をご紹介しましたが、いかがでしたでしょうか。今回はご紹介できませんでしたが、WebdavServletは単なるファイルサーバとしての利用方法だけでなく、ほかにも面白い使い方ができます。例えば(手前みそで恐縮ですが)筆者が公開しているJavaベースのCMS(コンテンツ管理システム)であるKvasir/SoraではWebDAV経由でコンテンツを操作する機能を提供していますが、この機能はWebdavServletを用いて実現されています。このように、WebdavServletは単なるファイルサーバ以上の応用ができるプロダクトですので、興味のある方はぜひソースコードを読んでいろいろな使い方を発見してみてください。

 最終回である次回は、Jakarta Projectが提供するフレームワーク「Struts」を紹介します。

筆者プロフィール

横田健彦(よこた たけひこ)

東京工業大学卒業後、(株)東芝に入社。現在、知識メディアラボラトリーにてコミュニティベース情報共有システムの研究に従事。小学校のころからコンピュータに触れ、主にゲームプログラミングを通してBASIC、アセンブラをはじめとする多数の言語を学ぶ。JavaではJakartaプロジェクトの成果物を利用していく中で主にWebアプリケーションプログラミングの面白さに引かれ、Ja-Jakartaプロジェクトの活動に貢献する一方でオープンソースのJavaベースのWebコンテンツ管理システムであるKvasir/Soraの開発を行っている。

Ja-Jakarta Projectについて

Ja-Jakartaプロジェクトでは、Jakartaプロジェクトのドキュメントの和訳やプロダクトの国際化/日本語化などを行っている。現在、プロジェクトのメンバーを募集中。Ja-Jakartaプロジェクトの活動に参加しようという方は、「Ja-Jakartaプロジェクトへの参加方法」(http://www.jajakarta.org/site/getinvolved.html)を参照。



Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。