Open8
Rails (というかRack::Request) で `X-Forwarded-Host` に空文字を指定してリクエストを行うとエラーになる場合があるっぽい?

ここで host が nil になってこんな例外になることがある。
#<NoMethodError: undefined method `start_with?' for nil:NilClass
if !host.start_with?('[') && host.count(':') > 1
^^^^^^^^^^^^>

x-forwarded-host
を 空文字でリクエストすると起きるっぽい。
使用するHTTPクライアントによっては空文字のヘッダはそもそもリクエストに含めなかったりするので、HTTPクライアントを確認する必要あり。
curl は 空ヘッダは自動で削除するっぽい
$ curl -v "http://localhost/test" --header "x-forwarded-host: "
JavaScriptのfetchはしないっぽい
let headers = new Headers
headers.set('x-forwarded-host', ``)
let res = await fetch('http://localhost/test', { method: 'GET', headers: headers})
res.status
let text = await res.text()

wrap_ipv6
は Request#forwarded_for
とRequest#forwarded_authority
で使われていて、nil が渡される可能性があるのは後者のみっぽい。
split_header(value).last
で、split_header(value)
が空配列を返すと nil になる

-
Request#forwarded_authority
はRequest#authority
にコールされる。 -
Request#authority
は 以下で呼ばれる可能性がある

ただし、Railsの場合は host
や host_with_port
は ActionDispatch::HTTP::URL
の方のが使われるのでRack::Request
のは使われないっぽい?(これ後で検証)

RailsとRackの最小構成アプリを作って、request.authority
をコールして再現させる
アプリケーションが request.authority
をコールしなくても、Datadog を使ってる場合、instrumentation の過程で上記のnilアクセスが発生するメソッド(Rack::Request#base_url
)を呼ぶっぽい

rackのバグっぽい気がするのでPR送ってみた

↑のPRで curl でも再現可能ということを教えてもらった。 comment
-H で :
をつかわずに ;
で終わると 空で送信できる。
$ curl -s -v -H 'x-forwarded-host;' localhost:8888
man にも書いてあった。
$ man curl
...
If you send the custom header with no-value then its header must
be terminated with a semicolon, such as -H "X-Custom-Header;" to send "X-Custom-Header:".
ログインするとコメントできます