[ruby]Net::HTTPで無限に302 Movedを繰り返すトラブルにあった

まとめ

 res= http.get( url.path )
って書いていると、30x系のリダイレクトでパラメータ付きのURLを指示された時にはまります。url.request_uriを使いましょう。


内容

Google Calendar APIなんかを使ってWEBサービスからデータをとってくる時、net/httpを使うことはよくあるかと思います。

とってきたデータが30x系のリダイレクトであった場合まで考慮に入れたとすると、こんなコードになりますよね?

 max_retry_count = 5
 max_retry_count.times {|retry_count|
  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true if (443==url.port)
  http.ca_file = '/var/hogehoge/www.google.com.cer'
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.verify_depth = 5
  res= http.get( url.path )
  
  case res
  when Net::HTTPSuccess
   break
  when Net::HTTPRedirection
   url = URI.parse(res['Location'])
   next
  else
   break
  end
 }
 resを使ってあれこれ。

 ところが、これでGoogleカレンダーのデータをとってこようとしたらひどい目に遭います。とりあえずとってくると...

Moved Temporarily
The document has moved https://www.google.com/xxxx?gsessionid=m6Kxxxx

想定の範囲内の302 Moved Temporarilyなので、プログラムはいわれたとおりにリトライして、データをとってきます。

Moved Temporarily
The document has moved https://www.google.com/xxxx?gsessionid=1rJxxxx

え?と思いつつ、プログラムはいわれたとおりにリトライして、データをとってきます。

Moved Temporarily
The document has moved https://www.google.com/xxxx?gsessionid=Cmvxxxx

....たらい回し状態です。いっこうに目的のデータに行き着きません。

やり方が間違っているのかなぁ、それともドキュメントに読み落としがあるかなぁ、とさんざん悩んだ末、やっと原因に気がつきました。

rubyのURIライブラリは、URIを渡すと部品に分解してくれます。host/port/path/query....

そこで、http.get( url.path )を使うと? queryとして指示されている「?gsessionid=Cmvxxxx」が吹っ飛んじゃいますよね。

Googleさんから見ると、
・"xxxx"にクライアントが来たので、"xxxx?gsessionid=...."にリダイレクトを指示しました。
・なぜかクライアントはgsessionidを外して、再び"xxxx"にアクセスしてきました
・仕方がない(というか、別クライアントに見えるので)、"xxxx?gsessionid=...."にリダイレクトを指示しました。
・なぜかクライアントはgsessionidを外して"xxxx"にアクセスしてきたので....
ということになっていたわけです。

....だって みんな"http.get( url.path )" って書くじゃーん!

 res= http.get( url.request_uri )
って書くのがいいみたいです。

カテゴリ:

トラックバック(0)

このブログ記事を参照しているブログ一覧: [ruby]Net::HTTPで無限に302 Movedを繰り返すトラブルにあった

このブログ記事に対するトラックバックURL: http://mogya.com/mt/mt-tb.cgi/637

コメントする


画像の中に見える文字を入力してください。

このブログ記事について

このページは、 もぎゃが 2008年9月18日 17:22に書いたブログ記事です。

ひとつ前のブログ記事は「 puttyの設定をiniファイルに変換する 」です。

次のブログ記事は「 [ruby]GoogleAuthSubを使う 」です。

最近のコンテンツは インデックスページ で見られます。過去に書かれたものは アーカイブのページ で見られます。

Powered by
Movable Type