2011年06月13日

HTTPClientのリダイレクトに関するメモ

今日使った時に調べたことを2つほどメモしておく。HTTPClientのバージョンは4.1.1。コードはScala2.9。



・自動リダイレクトの設定

HTTPClientは302などが返ってきた時に自動でリダイレクトしてくれる。勝手にリダイレクトをして欲しくない場合は、HttpClientParams.setRedirectingでfalseを設定する。
val client = new DefaultHttpClient()
HttpClientParams.setRedirecting(client.getParams, false)
new HttpRequest(client)

これで301や302が返ってきても、そこで止まる。後はヘッダからlocation取ってきて自分で遷移するなりなんなりで。



・自動リダイレクトでどう遷移したか知りたい時

リダイレクトした履歴はcontextのhttp.protocol.redirect-locationsに入ってるらしい。
executeする時にcontextを引数に入れて、そこから取り出してみたらリダイレクト情報が取れた。
import org.apache.http.protocol.BasicHttpContext
import org.apache.http.client.methods.HttpGet
import http.impl.client.{ DefaultHttpClient, RedirectLocations }

// executeする時にcontextを引数に入れる
val client = new DefaultHttpClient()
val get = new HttpGet(url)
val context = new BasicHttpContext()
val response = client.execute(get, context)

// RedirectLocationsクラスが取れる
val locations = context.getAttribute("http.protocol.redirect-locations").asInstanceOf[RedirectLocations]

// getAllでList[URI]形式のURL情報が取れる
val urls = locations.getAll


リダイレクトが発生していない場合は、getAttributeの結果がnullになる。なので上のコードだとgetAllした時にヌルポになったりする。

リダイレクトが発生していた場合は、遷移先のURLが順に入る。遷移元のURLは入らない。

ので、http://aaa.cc/ → http://bbb.cc/ → http://ccc.cc/ と遷移した場合は、[http;//bbb.cc/, http://ccc.cc]が結果として取れる。