https://lists.apache.org/thread/yqkd183xrw3wqvnpcg3osbcryq85fkzjjvn.jp
仕事していて話題にあがったので暇つぶしがてら見てみた
とりあえず素のtomcatで試す
conf/server.xml
を書き換える(関係ない箇所は省略)
<Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" errorReportValveClass="org.apache.catalina.valves.JsonErrorReportValve"> </Host> </Engine> </Service> </Server>
HostタグでerrorReportValveClassを指定することで切り替えできる(デフォルトは ErrorReportValve
が使用される)
10.1.2で修正されているらしいので、 その辺りの挙動を一応見る(Commit)
apache-tomcat-10.1.1
curl http://localhost:8080/\"\"/ -H 'accept:application/json'
そのまま出力しようとするせいでJSONが壊れる
{ "type": "Exception Report", "message": "Invalid character found in the request target [/""/ ]. The valid characters are defined in RFC 7230 and RFC 3986", "description": "The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." }
apache-tomcat-10.1.4
curl http://localhost:8080/\"\"/ -H 'accept:application/json'
10.1系の最新であればちゃんとエスケープされる
{ "type": "Exception Report", "message": "Invalid character found in the request target [/\u0022\u0022/ ]. The valid characters are defined in RFC 7230 and RFC 3986", "description": "The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." }
spring-bootの埋め込みtomcatで試す
spring-bootの埋め込みtomcatの errorReportValveClass
をどうやって書き換えるのか調べていたら、先にわかりやすく書いてくださっている方がいたのでそれをKotlinで書いて試した
参考にさせていただいたページ: Spring BootでTomcatのデフォルトエラーページが出るのを抑止する
package com.example.app.presentation.configuration import org.apache.catalina.Context import org.apache.catalina.core.StandardHost import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.apache.catalina.valves.JsonErrorReportValve @Configuration class TomcatConfig { @Bean fun errorReportValveCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> { return WebServerFactoryCustomizer { factory: TomcatServletWebServerFactory -> factory.addContextCustomizers(TomcatContextCustomizer { context: Context -> if (context.parent is StandardHost) { (context.parent as StandardHost).errorReportValveClass = JsonErrorReportValve::class.qualifiedName } }) } } }
spring-boot-starter-web-2.7.5 + tomcat-embed-core-9.0.68
ちょっと他のプロジェクトでそのまま試していたのでstarterとかが古いが気にしない
curl http://localhost:8080/\"\"/ -H 'accept:application/json'
そのまま出力しようとするせいでJSONが壊れる
{ "type": "Exception Report", "message": "Invalid character found in the request target [/""/ ]. The valid characters are defined in RFC 7230 and RFC 3986", "description": "The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." }
spring-boot-starter-web-2.7.5 + tomcat-embed-core-9.0.69
9系は9.0.69で修正されている
curl http://localhost:8080/\"\"/ -H 'accept: application/json'
{ "type": "Exception Report", "message": "Invalid character found in the request target [/\u0022\u0022/ ]. The valid characters are defined in RFC 7230 and RFC 3986", "description": "The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." }
まあデフォルトをそのまま使っていれば遭遇することはなさそうだし、バージョンあげれば修正されるしで気にしなくて良さそう感