Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

RubyとURIと角括弧

タグ: Ruby

Redmine 0.8.4のリポジトリブラウザで角括弧を含む名前のファイルをダウンロードしようとしたところ

リポジトリに、エントリ/リビジョンが存在しません。

と表示されてダウンロードできない現象に見舞われた。
REDMINE_ROOT/log/mongrel.log を覗いてみると

svn: URL 'http://example.com/repos/trunk/[hoge].txt' は適切に URI エンコードされていません

とある。
「URI構文で角括弧を使えるのはIPリテラルの囲いとしてのみ(Uniform Resource Identifier (URI): Generic Syntax §3.2.2 Host)」なので、この文字列はたしかに正しいURIではない。

Redmineはsvnに渡すパスを REDMINE_ROOT/lib/redmine/scm/adapters/subversion_adapter.rb でエンコードしているが、Ruby 1.8.7の URI.escape はデフォルトではURIの予約文字である角括弧をエンコードしない

$ ruby -e "require 'uri'; p URI.escape('http://example.com/repos/trunk/[hoge].txt')"
"http://example.com/repos/trunk/[hoge].txt"
$ ruby -e "require 'uri'; p URI.escape('http://[::1]/repos/trunk/[hoge].txt')"
"http://[::1]/repos/trunk/[hoge].txt"

またsvn 1.6.3も、URLと思われる引数の「スペース」やら「非ASCII文字」やらはエンコードしてくれるのだが、これもまた角括弧はエンコードしない。

$ svn log 'http://example.com/repos/trunk/[ho ge].txt'
svn: URL 'http://example.com/repos/trunk/[ho%20ge].txt' は適切に URI エンコードされていません

結果、角括弧を含むURLはsvn自身のURI構文チェックに引っかかってエラーとなる。

さて、これはどのように対処するのが良いだろう。

前述のトラッカに添付されているパッチを RUBYLIB_ROOT/1.8/uri/common.rb に適用すれば、 URI.escape は期待通りのエンコードをしてくれるようになる。

$ ruby -e "require 'uri'; p URI.escape('http://example.com/repos/trunk/[hoge].txt')"
in 1
"http://example.com/repos/trunk/%5Bhoge%5D.txt"
$ ruby -e "require 'uri'; p URI.escape('http://[::1]/repos/trunk/[hoge].txt')"
in 1
"http://[::1]/repos/trunk/%5Bhoge%5D.txt"
$ ruby -e "require 'uri'; p URI.escape('[hoge].txt')"
in 2
"%5Bhoge%5D.txt"

「どうせホスト副構成要素で角括弧なんか使わないよ」というのであれば、 escape の第2引数で角括弧を含めてエンコードするよう指定するという手もある。

$ ruby -e "require 'uri'
> p URI.escape('http://example.com/repos/trunk/[hoge].txt',  /[^-_.\!~*'()a-zA-Z\d;\/?:@&=+$,]/n)"
"http://example.com/repos/trunk/%5Bhoge%5D.txt"
$ ruby -e "require 'uri'
> p URI.escape('http://[::1]/repos/trunk/[hoge].txt',  /[^-_.\!~*'()a-zA-Z\d;\/?:@&=+$,]/n)"
"http://%5B::1%5D/repos/trunk/%5Bhoge%5D.txt"

影響範囲や問題点を踏まえ、適切な方法を選ぼう。

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/217-3c33f7b8
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。