canonicalheader

Table of Contents

  1. 解決する問題
  2. 設定
  3. オプション
  4. サンプル
    1. 検出例
    2. 修正例
  5. 注意点
  6. 参考リンク

canonicalheader は net/http.Header で非正規形式のヘッダーキーが使用されていないかをチェックするツールです。

解決する問題

Go の http.Header はキーを正規形式(Canonical Form)で管理します。正規形式とは、ハイフンで区切られた各単語の先頭を大文字にする形式(例: Content-Type)です。非正規形式のキーを直接使うと、SetGet が正規化するため動作はしますが、コードの一貫性が損なわれ、map として直接アクセスする際にバグを引き起こす可能性があります。

1
2
3
4
5
6
// Before: 非正規形式のヘッダーキー
func SetHeaders(h http.Header) {
h.Set("content-type", "application/json") // 正規形式: Content-Type
h.Set("X-REQUEST-ID", "abc123") // 正規形式: X-Request-Id
h.Set("accept-encoding", "gzip") // 正規形式: Accept-Encoding
}
1
2
3
4
5
6
// After: 正規形式のヘッダーキー
func SetHeaders(h http.Header) {
h.Set("Content-Type", "application/json")
h.Set("X-Request-Id", "abc123")
h.Set("Accept-Encoding", "gzip")
}

設定

公式ドキュメント

設定オプションはありません。有効化するだけで動作します。

1
2
3
4
5
6
# .golangci.yml
version: "2"

linters:
enable:
- canonicalheader

オプション

golangci-lint 経由では設定オプションはありません。

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
// canonicalheader が警告するパターン

func example(w http.ResponseWriter, r *http.Request) {
// 非正規形式のキー
w.Header().Set("content-type", "text/html") // non-canonical header "content-type", instead use: "Content-Type"
w.Header().Add("x-custom-header", "value") // non-canonical header "x-custom-header", instead use: "X-Custom-Header"
_ = r.Header.Get("accept-language") // non-canonical header "accept-language", instead use: "Accept-Language"

// map として直接アクセスする場合に特に危険
r.Header["content-type"] = []string{"text/plain"} // Set() と異なり正規化されない → 重複キーの原因
}

修正例

1
2
3
4
5
6
7
func example(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
w.Header().Add("X-Custom-Header", "value")
_ = r.Header.Get("Accept-Language")

r.Header.Set("Content-Type", "text/plain")
}

注意点

  • http.Header.Set()Get() は内部で http.CanonicalHeaderKey() を呼んで正規化するため動作上の問題は起きにくいが、コードの可読性と一貫性のために正規形式で記述すべき
  • http.Headermap[string][]string として直接操作する場合は正規化されないため、非正規形式のキーが残りバグの原因になる
  • 正規形式の変換ルール: ハイフン区切りの各単語の先頭を大文字、残りを小文字にする(例: accept-encodingAccept-Encoding

参考リンク