[インデックス 11788] ファイルの概要
このコミットは、Go言語の標準ライブラリである net/http
パッケージのドキュメント内の誤った参照を修正するものです。具体的には、http.HandleFunc
の使用例において、r.URL.RawPath
ではなく r.URL.Path
を参照するように変更されています。これにより、ドキュメントの正確性が向上し、ユーザーが net/http
パッケージを正しく理解し、利用できるようになります。
コミット
commit 0846e275a88b1b0b92a8cacab5b7e4cfc747e072
Author: Bjorn Tipling <bjorn.tipling@gmail.com>
Date: Fri Feb 10 22:39:57 2012 -0200
net/http: fix reference to URL.RawPath in docs
R=go.peter.90, n13m3y3r, gustavo
CC=golang-dev
https://golang.org/cl/5655053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0846e275a88b1b0b92a8cacab5b7e4cfc747e072
元コミット内容
net/http: fix reference to URL.RawPath in docs
このコミットは、net/http
パッケージのドキュメント内で URL.RawPath
への参照が誤っていたのを修正するものです。
変更の背景
Go言語の net/http
パッケージは、HTTPクライアントとサーバーの実装を提供します。このパッケージのドキュメントには、http.HandleFunc
を使用してHTTPリクエストを処理する例が含まれています。元々のドキュメントのコード例では、リクエストのURLパスを取得するために r.URL.RawPath
が使用されていました。
しかし、URL.RawPath
はURLのパス部分がエンコードされたままの形式(例: %2F
のようなパーセントエンコーディングを含む)を保持します。一方、URL.Path
はパーセントエンコーディングがデコードされた形式(例: /
)を提供します。通常、HTTPハンドラでユーザーに表示したり、内部処理で使用したりする際には、デコードされた URL.Path
の方が適切です。特に、html.EscapeString
のような関数でエスケープ処理を行う場合、デコードされたパスをエスケープする方が意図した動作になります。
このコミットは、ドキュメントのコード例が net/http
パッケージの一般的な使用パターンとベストプラクティスに沿うように、RawPath
から Path
への修正を行いました。これにより、ドキュメントを参照する開発者が誤ったパスの扱い方を学ぶことを防ぎ、より堅牢で安全なアプリケーション開発を促進します。
前提知識の解説
Go言語の net/http
パッケージ
net/http
パッケージは、Go言語でHTTPクライアントとサーバーを構築するための基本的な機能を提供します。ウェブアプリケーションやAPIサーバーを開発する際に中心的に使用されます。
http.Request
: HTTPリクエストを表す構造体です。クライアントからのリクエストに関する情報(メソッド、URL、ヘッダー、ボディなど)を含みます。http.ResponseWriter
: HTTPレスポンスを書き込むためのインターフェースです。サーバーがクライアントに返すデータ(ステータスコード、ヘッダー、ボディなど)を書き込みます。http.HandleFunc(pattern string, handler func(ResponseWriter, *Request))
: 指定されたパターン(URLパス)に対してHTTPハンドラ関数を登録します。http.ListenAndServe(addr string, handler Handler)
: 指定されたアドレスでHTTPサーバーを起動します。
url.URL
構造体
http.Request
構造体には URL
フィールドがあり、これは url.URL
型です。url.URL
構造体は、URLの各コンポーネント(スキーム、ホスト、パス、クエリ、フラグメントなど)を解析して保持します。
URL.Path
: URLのパス部分を表す文字列です。これは、パーセントエンコーディングがデコードされた後のパスです。例えば、/foo%2Fbar
は/foo/bar
となります。URL.RawPath
: URLのパス部分を表す文字列です。これは、パーセントエンコーディングがデコードされていない生のパスです。例えば、/foo%2Fbar
は/foo%2Fbar
のままです。
html.EscapeString
関数
html.EscapeString(s string)
は、HTMLドキュメントに安全に埋め込むために、文字列 s
内の特殊文字(<
, >
, &
, '
, "
)を対応するHTMLエンティティ(<
, >
, &
, '
, "
)に変換する関数です。これにより、クロスサイトスクリプティング(XSS)攻撃などのセキュリティ脆弱性を防ぐことができます。
技術的詳細
このコミットの技術的なポイントは、URL.Path
と URL.RawPath
の使い分けにあります。
-
URL.RawPath
の用途:RawPath
は、URLのパス部分がエンコードされた元の形式を保持しているため、URLをそのまま再構築する場合や、エンコードされたパス自体に意味がある場合(例えば、特定のルーティングロジックがエンコードされたパスに依存する場合)に利用されます。しかし、通常はユーザーに表示したり、ファイルシステムパスとして利用したりする際には、デコードされた形式が望ましいです。 -
URL.Path
の用途:Path
は、パーセントエンコーディングがデコードされた後のパスを提供します。これは、ほとんどのアプリケーションでURLパスを処理する際に期待される形式です。例えば、/users/%E3%83%86%E3%82%B9%E3%83%88
のようなURLの場合、RawPath
は/users/%E3%83%86%E3%82%B9%E3%83%88
のままですが、Path
は/users/テスト
となります。
ドキュメントの例では、fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath))
のように、取得したパスを html.EscapeString
でエスケープして出力しています。もし RawPath
を使用した場合、例えばURLが /foo%2Fbar
であったとすると、RawPath
は /foo%2Fbar
となり、これをエスケープすると Hello, "/foo%2Fbar"
のように表示されます。しかし、意図としては /foo/bar
のようなデコードされたパスを表示したい場合が多いでしょう。
URL.Path
を使用することで、URLが /foo%2Fbar
であっても Path
は /foo/bar
となり、これをエスケープして出力すると Hello, "/foo/bar"
となり、より自然で期待される表示になります。この修正は、ドキュメントのコード例が net/http
パッケージの一般的な利用シナリオとセキュリティプラクティスに合致するようにするための重要な変更です。
コアとなるコードの変更箇所
--- a/src/pkg/net/http/doc.go
+++ b/src/pkg/net/http/doc.go
@@ -60,7 +60,7 @@ Handle and HandleFunc add handlers to DefaultServeMux:
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath))
+ fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
コアとなるコードの解説
変更は src/pkg/net/http/doc.go
ファイル内の http.HandleFunc
の使用例にあります。
元のコード:
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath))
修正後のコード:
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
この変更は、r.URL.RawPath
を r.URL.Path
に置き換えることで、HTTPリクエストのURLパスを処理する際の動作を修正しています。
r.URL.RawPath
: リクエストURLのパス部分を、パーセントエンコーディングがデコードされていない「生」の形式で取得します。例えば、URLがhttp://example.com/path%2Fwith%2Fslash
の場合、RawPath
は/path%2Fwith%2Fslash
となります。r.URL.Path
: リクエストURLのパス部分を、パーセントエンコーディングがデコードされた形式で取得します。上記の例の場合、Path
は/path/with/slash
となります。
ドキュメントの例では、このパスを html.EscapeString
でエスケープしてから出力しています。ユーザーに表示する目的や、一般的なパス処理の文脈では、デコードされた Path
を使用する方が自然であり、意図した結果が得られます。この修正により、ドキュメントのコード例がより実用的で、Goの net/http
パッケージの推奨される使用方法を反映するようになりました。
関連リンク
- Go言語
net/http
パッケージ公式ドキュメント: https://pkg.go.dev/net/http - Go言語
net/url
パッケージ公式ドキュメント: https://pkg.go.dev/net/url - Go言語
html
パッケージ公式ドキュメント: https://pkg.go.dev/html
参考にした情報源リンク
- Go言語の公式ドキュメント (
pkg.go.dev
) - Go言語のソースコード (
github.com/golang/go
) - Go言語のコミット履歴 (
github.com/golang/go/commits
) - Go言語のコードレビューシステム (
golang.org/cl/5655053
)