4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Boot 1.4以降でStatus Codeに 200 OK (Reason Phrase) を出力する。

Posted at

経緯

先日Spring BootでAPIを作成していた際に、呼び出し側から
「お前のところのAPIどうやって叩いても正常なレスポンスを返さない」
と連絡を受けました。
こちらではHttp Status に200を返しているログも残っているしネットワークの問題かしらん?と思い詳しい話を聞いてみると
「Http Status Codeの200 OKの"OK"が出力されていないから正常じゃない!」
とのことでした。

RFC的にはどうなっているか

RFC 7230
https://tools.ietf.org/html/rfc7230#section-3.1.2

A client SHOULD ignore the reason-phrase content.

クライアントはreason-phrase(OKの部分)を無視すべきと記載があるのですが。。。
でも、呼び出し側は社会的信用の高いところなので、こちらが折れるしかないですね!

原因調査

Spring Boot 1.4.0: HTTP Status Issue
https://github.com/spring-projects/spring-boot/issues/6548

SpringのIssueを見てみると、Spring Boot 1.4からTomcatを8.5系に上げたのが原因だけどTomcatの問題(?)だからSpring側ではどうしょもないよ。とのこと

missing reason phrase in tomcat 8.5.x
https://bz.apache.org/bugzilla/show_bug.cgi?id=60183

Tomcatの開発チームも、RFC7230でも無視してって書いてあるし無駄だから8.5でなくしたよ。
と修正するつもりは無さそうです。

対応

Tomcatのソースコードを読んで自分でなんとかする事にしました。

調査の結果org.apache.coyote.http11.ConstantsにStatus Codeの文字列が定義されいる事がわかりました。
Class loadingの順番を変えて定義されている内容を置き換える事も検討しましたが、
バージョンアップの事を考えると単純なclass置き換えは不安が残ります。
(この対応を忘れてバージョンアップして問題あるけど動くには動くみたいな状況は危険です。)

幸いStatus Codeは定数として定義されていたため、必要な箇所だけSpring起動時にリフレクションで書き換える事にしました。
ただし、対象がfinalなフィールドだったため、リフレクションでも簡単には変更する事はできませんでした。
そのあたりのナレッジは別記事として投稿しています。

サンプルコード

SpringBootApplication.java
@SpringBootApplication
public class SpringBootApplication {

    public static void main(String[] args) throws Exception {

        Field statusBytes200 = org.apache.coyote.http11.Constants.class.getDeclaredField("_200_BYTES");
        byte[] _200_OK = "200 OK".getBytes();

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(statusBytes200, statusBytes200.getModifiers() & ~Modifier.FINAL);
        statusBytes200.set(null, _200_OK);

        SpringApplication.run(SpringBootApplication.class, args);
    }
}
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?