rfeedfinderを修正
Fastladderのオープンソース版を試していると、feedの登録&取得に失敗するケースがあります(例: http://www.ruby-lang.org/ja/ )。根本をたどってみると、feedを探索するライブラリ、rfeedfinder(ver.0.9.13)に問題があるようです。具体的には、下記のisAValidURL関数です。
def self.isAValidURL?(url_to_check) return false if url_to_check == nil # The protocols that we allow are the following protocol_whitelist = ["http", "https"] # I guess we could have included some more, but that doesn't really # make sense anyway as these are the ones that should be used. # We'll see if the need arises and then add more later if needed. re = Regexp.new("(#{protocol_whitelist.join('|')}):" + \ "\/\/([[:alpha:][:digit:].]{2,})([.]{1})([[:alpha:]]{2,4})(\/)") # For the sake of the regular expression check we add a back slash # at the end of the URL url_to_check += "/" return true unless (re =~ url_to_check) == nil false end
正規表現で https?://hogehoge.example.com/ などの正規なURLであることを判別しているようです。しかし、この正規表現ではハイフンやポート番号に対応していません。というわけで、URIモジュールを使って修正しました。makeFullURI関数も難ありだったので、適宜直しています。
Index: lib/rfeedfinder.rb =================================================================== --- lib/rfeedfinder.rb (revision 1) +++ lib/rfeedfinder.rb (working copy) @@ -314,11 +314,23 @@ protected def self.makeFullURI(uri) - uri = uri.strip.sub(/^feed(.*)/, 'http\1').downcase - if /^http|https/.match(uri) + begin + uri_parsed = URI.parse(uri) + rescue URI::Error return uri + end + + case uri_parsed.scheme + when "http", "https" + return uri + when "feed" + uri = uri.strip.sub(/^feed(.*)/, 'http\1').downcase + return uri + when nil + # when uri does not start with 'protocol-scheme://', add 'http://' + return "http://" << uri else - return "http://" << uri + return uri end end @@ -481,14 +493,16 @@ # make sense anyway as these are the ones that should be used. # We'll see if the need arises and then add more later if needed. - re = Regexp.new("(#{protocol_whitelist.join('|')}):" + \ - "\/\/([[:alpha:][:digit:].]{2,})([.]{1})([[:alpha:]]{2,4})(\/)") - - # For the sake of the regular expression check we add a back slash - # at the end of the URL - url_to_check += "/" - return true unless (re =~ url_to_check) == nil - false + begin + uri = URI.parse(url_to_check) + if protocol_whitelist.index(uri.scheme) + return true + else + return false + end + rescue URI::Error + return false + end end
makeFullURIのdowncaseについてはこのままだとまずいらしい(たとえば、URLがcase-sensitiveなとき)ですが、rfeedfinder作者の意図が分からないので判断は保留で。