Home > ruby

ruby Archive

Rubyのopen-uriでopenできないURI

  • 2007-07-05 (木)
  • ruby

RubyでHTTPに簡単にアクセスするopen-uriというライブラリが用意されています。

例えばこのようにします↓

require 'open-uri'
open("http://www.ruby-lang.org/") {|f|
f.each_line {|line| p line}
}

とても簡単にアクセスできるのですが、残念ながらアクセスできないURIがありました。

まず私の環境。

% ruby -v
> ruby 1.8.5 (2006-08-25) [i386-freebsd6]

例えばこのようなURI↓

require 'open-uri'
open("http://www.adamrocker.com/test?value=arg1|arg2") {|f|
f.each_line {|line| p line}
}

パラメータの中に「|」が含まれている場合です。
これを実行した結果はこうなります。

/usr/local/lib/ruby/1.8/uri/common.rb:432:in `split’: bad URI(is not URI?): http://www.adamrocker.com/test?value=arg1|arg2 (URI::InvalidURIError)
from /usr/local/lib/ruby/1.8/uri/common.rb:481:in `parse’
from /usr/local/lib/ruby/1.8/open-uri.rb:29:in `open’
from uri.rb:2

「bad URI」と言って怒られます。
ググって調べたら、どうやらopen-uriのURIのパースにはURIライブラリを利用しているとの事。

ということで、URIライブラリのソースを眺めてみました。

するとuri/common.rbの39行目に以下の記述がありました。

RESERVED = ";/?:@&=+$,??[??]"

これはURIをパースする時に予約語となる文字列集合なのですが、ここに「|」が含まれていない。
なるほど、これはパースできません。
ということで、この部分を以下のように変更してみました。

RESERVED = "|;/?:@&=+$,??[??]"

「|」を追加しています。

これで実行したらうまく動きました。

そんなURIあるのか?

例えば、アマゾンのWeb APIを使ってOR検索する場合。

Keywords=item1|item2|item3

こういったクエリーを発行します。
いや発行したいんです。

ご利用は計画的に

ちなみに、Rubyの「現時点での最新版スナップショット(2007/07/05 04:00:26)」においても上記の予約語が変更されていませんでした。

こういうバグっぽいのをどこに報告すれば良いのかを知らないので、ここでコッソリ報告しておきます。

とりあえず、この修正で副作用が起こらないかどうかは不明ですので、そこらへんに詳しい人は教えて頂ければ幸いです。

なお、副作用がないようなら、本家のソースが修正されればユーザとして嬉しい限りです。

ついでに

uri/common.rbの修正が他に副作用を起こす可能性もありますので、そこらへんが恐い場合はopen-uriを使わずNet::HTTPライブラリを使うと、パースエラーにならずにHTTPにアクセスできました。参考までに。

[CONTACT-FORM]

ホーム > ruby

Author
Search
Feeds
Meta

Return to page top