go tool traceの-httpにポートのみ指定した場合、待ち受けアドレスがlocalhostに制限されるようになった
Trace
概要
go tool traceの-httpコマンドラインオプションにポートのみを指定した場合(例: -http=:6060)、
待ち受けアドレスがlocalhostに制限されるようになった。これにより、go tool pprofの-httpフラグの
挙動と一貫性が取れる。すべてのアドレスで待ち受けたい場合は、アドレスを明示的に指定する
(例: -http=0.0.0.0:6060)必要がある。
導入経緯
GitHub issueで、go tool trace -http :9092 .\traceを実行するとブラウザが自動的に開くものの、
URL(http://[::]:9092)が誤っておりアクセスに失敗する(手動でURLを修正すればアクセスできる)
という報告があった。
議論のハイライト
- メンテナーの分析によると、
cmd/traceは待ち受けアドレスから直接URLを組み立てている。ポートのみを
指定してアドレスを省略した場合、これは「すべてのアドレスで待ち受ける」ことを意味し、any/zero
アドレス([::]や0.0.0.0)として表現される。Linuxではこのアドレスへのconnectがループバック
アドレスへ変換されるため偶然動作するが、Windowsでは同様の挙動がないため接続に失敗する。 - 回避策として、アドレスを明示的に指定する(
-http localhost:9092)か、フラグ自体を省略する
(デフォルトはlocalhost)ことが提案された。 - 議論を受けて2件のCLが作成された。表示URLをlocalhostへ書き換えるCLと、実際の待ち受けアドレス
自体をlocalhostに制限するCLである。
移行時の注意
これまで-http=:6060のようにポートのみを指定してコンテナ外や別ホストからアクセスできるように
していた場合、今後は明示的に-http=0.0.0.0:6060のようにアドレスを指定する必要がある。
実装解説
cmd/traceのmain関数は-httpフラグの値をlistenAddr
に渡してからnet.Listenしている。listenAddrはホスト部分が空文字列の場合(ポートのみ指定)、
ホストを"localhost"に書き換えてからnet.JoinHostPortで結合する。
これとは別に、addrURL
はブラウザで開くURLの表示専用の関数で、実際に待ち受けているアドレスがunspecifiedアドレス
(0.0.0.0など)であっても、接続先URLとしてはlocalhostに書き換える。listenAddrによって
待ち受けアドレス自体が制限されるようになったため、通常はaddrURL側のこの書き換えが働く場面は
限定的になる。