情報が古い可能性がありますのでご注意ください。
OpenURIでhttpからhttpsのリダイレクトを一時的に許すgem作った
情報が古い可能性がありますのでご注意ください。
RubyではOpenURIを使うとウェブページを開くことができる。OpenURIでは引数に与えたURIのプロトコルがHTTPリダイレクト先がHTTPSの場合、エラーが発生するという作りになっている。
ところで、HTTPからHTTPSへのリダイレクトは意外とたくさんある。
例えばGoogleで短縮URL。
リダイレクト先はここ。
https://github.com/pi-chan/open_uri_allow_redirect
% irb irb(main):001:0> require "open-uri" => true irb(main):002:0> open "http://goo.gl/84556T" RuntimeError: redirection forbidden: http://goo.gl/84556T -> https://github.com/pi-chan/open_uri_allow_redirect from /Users/hiromasa/.rbenv/versions/2.1.0/lib/ruby/2.1.0/open-uri.rb:223:in `open_loop' from /Users/hiromasa/.rbenv/versions/2.1.0/lib/ruby/2.1.0/open-uri.rb:149:in `open_uri' from /Users/hiromasa/.rbenv/versions/2.1.0/lib/ruby/2.1.0/open-uri.rb:703:in `open' from /Users/hiromasa/.rbenv/versions/2.1.0/lib/ruby/2.1.0/open-uri.rb:34:in `open' from (irb):2 from /Users/hiromasa/.rbenv/versions/2.1.0/bin/irb:11:in `<main>' irb(main):003:0>
このようなケースでは、そのままのOpenURIは使えない。
open_uri_redirections
Rubyだから既存のクラスを拡張してしまえばよい。探してみるとOpenURIでHTTPSへのリダイレクトを許可するような拡張をしているgemがあった。
jaimeiniesta/open_uri_redirections
このgemにより、openメソッドでallow_redirections
というオプションを扱えるようになる。HTTPからHTTPSのリダイレクトやその逆のリダイレクトを許可するかどうかを呼び出し元が制御できるようになるというわけ。
require "open-uri" require "open_uri_redirections" open('http://github.com', :allow_redirections => :safe) open('http://github.com', :allow_redirections => :all)
open
の中で使われるredirectable?
というメソッドを置き換えることによってこれを実現している。
このgemの問題点
open
の呼び出しを自分で書くときはいいが、ライブラリなどの自分で手を加えにくいコードがopen
を呼んでいる場合にはこのgemでは対応しきれない。
open_uri_allow_redirect作った
その問題を解決するために、少しばかり改変したgemを作った。
pi-chan/open_uri_allow_redirect
このgemではopen
の引数を使わず、OpenURI.allow_redirect
に渡したブロック内のopen
呼び出しは全てのリダイレクトを許可するという作りになっている。
こんな感じで使える。
require "open_uri_allow_redirect" open("http://github.com") # => raises RuntimeError, redirected to https://github.com OpenURI.allow_redirect do open("http://github.com") # => no error end
ライブラリのコードがopen
を呼んでいるときにも対応できる。
# in other library module MyLibrary def use_open_method_internally(uri) open(uri) end end # main require "open_uri_allow_redirect" OpenURI.allow_redirect do MyLibrary.use_open_method_internally("http://github.com/") # => no error end
いえい。