assaulter's diary

主にバイクについて

Play2.0.2にてresponseがRedirectだった場合の挙動

今回はちょっと長めです。Play2.0.1→2.0.2で気になる変更点があったのでメモ書きとして残します。

下記のようなコードがあった場合の話です。

def getResponse(url : String) = { 
    // url: redirect応答を返すようなapiのurl
    WS.url(url).get.map { response =>
      response.status match {
        case 301 =>
          response.header("Location")
        case _ => 
      }
    }
  }

要はリダイレクト応答を受けとってそのレスポンスを解析し、redirectならばそのロケーションに含まれるurlを使って別のお仕事に頑張ってもらう関数なのですが、play2.0.1から2.0.2にアップデートした際に、エラーを吐きました。

エラーの内容としては、response.statusが301ではなく200を返すというものです。で、原因について教えてもらったので記事にしました。まずは下記のurlをご覧ください。

Play WS APIhttps://github.com/garbagetown/playdocja/blob/master/documentation/2.0.2/manual/javaGuide/main/ws/JavaWS.md

こちらのページ下部のapplication.confをいじっている部分がありますが、そこでws.followRedirects = trueという設定を行なっています。これ、2.0.1の時には意識してなかったのですが、playのソースを漁ると2.0.1→2.0.2で大分設定項目が増えているみたいです。

play2.0.1のWS.scalaを抜粋

  
/**
 * The underlying HTTP client.
 */
 lazy val client = new AsyncHttpClient()

play2.0.2のWS.scalaを抜粋

  /**
   * The underlying HTTP client.
   */
  lazy val client = {
    import play.api.Play.current
    val config = new AsyncHttpClientConfig.Builder()
      .setConnectionTimeoutInMs(current.configuration.getMilliseconds("ws.timeout").getOrElse(120000L).toInt)
      .setRequestTimeoutInMs(current.configuration.getMilliseconds("ws.timeout").getOrElse(120000L).toInt)
      .setFollowRedirects(current.configuration.getBoolean("ws.followRedirects").getOrElse(true))
    current.configuration.getString("ws.useragent").map { useragent =>
      config.setUserAgent(useragent)
    }
    new AsyncHttpClient(config.build())
  }

WS.followRedirectsってなんぞや?

素直にググるとなぜかmicrosoftのページが出てきたのですが、意味的にはリダイレクトに従いますか?従いませんか?ということらしいので、試しにapplication.confに"WS.followRedirects = false"を追加してあげるとplay2.0.1の頃の挙動を示します。

逆に何も書かないとリダイレクトに従うので、リダイレクト先のレスポンスを返す。という仕組みらしいです。

まあ、用途に応じて使い分ける感じですかねぇ。