[インデックス 14780] ファイルの概要
このコミットは、Go言語の標準ライブラリである net/http
パッケージ内の Request
構造体の URL
フィールドに関するドキュメントを追加するものです。これにより、Request.URL
がどのように生成され、どのフィールドが通常設定されるかについての誤解を解消し、開発者がより正確にこのフィールドを扱えるようにすることを目的としています。
コミット
commit 948f0b7a0bf2030bd927ccab7446324ed684d43f
Author: Rick Arnold <rickarnoldjr@gmail.com>
Date: Wed Jan 2 17:37:27 2013 -0500
net/http: document Request.URL
Request.URL had no documentation before and some people were expecting all fields to be populated.
Fixes #3805.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7008046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/948f0b7a0bf2030bd927ccab7446324ed684d43f
元コミット内容
net/http
: Request.URL のドキュメント化
Request.URL
には以前ドキュメントがなく、一部の開発者はすべてのフィールドが設定されていると期待していました。
Fixes #3805.
変更の背景
このコミットの背景には、Go言語の net/http
パッケージを使用する開発者からの http.Request
構造体内の URL
フィールドに関する混乱がありました。具体的には、Request.URL
フィールドが *url.URL
型であるにもかかわらず、HTTPリクエストの「Request-Line」から生成されるURLの特性上、Scheme
や Host
といった一部のフィールドが空になることが一般的でした。しかし、この挙動が明示的にドキュメント化されていなかったため、開発者は URL
オブジェクトのすべてのフィールドが常に完全にパースされ、設定されていると誤解し、予期せぬバグや混乱を招く可能性がありました。
この問題は、GoのIssueトラッカーで #3805 として報告されており、このコミットはその問題を解決するために Request.URL
フィールドに明確なドキュメントを追加することを目的としています。ドキュメントを追加することで、開発者が Request.URL
の実際の挙動を理解し、適切にコードを記述できるようになります。
前提知識の解説
このコミットを理解するためには、以下の概念について基本的な知識が必要です。
-
Go言語の
net/http
パッケージ: Go言語の標準ライブラリであり、HTTPクライアントとサーバーの実装を提供します。WebアプリケーションやAPIサーバーを構築する際に中心的に使用されます。http.Request
構造体: HTTPリクエストを表す構造体です。リクエストメソッド、URL、ヘッダー、ボディなどの情報を含みます。http.ResponseWriter
インターフェース: HTTPレスポンスを書き込むためのインターフェースです。
-
Go言語の
net/url
パッケージ: URLのパースと生成を扱うためのパッケージです。url.URL
構造体: URLの各コンポーネント(スキーム、ホスト、パス、クエリなど)を保持する構造体です。
-
HTTP/1.1 の Request-Line (RFC 2616, Section 5.1): HTTPリクエストの最初の行は「Request-Line」と呼ばれ、以下の形式を持ちます。
Method SP Request-URI SP HTTP-Version CRLF
ここで重要なのはRequest-URI
です。Request-URI
は、リクエストのターゲットを識別するものであり、その形式はリクエストの種類によって異なります。absoluteURI
: 完全なURI(例:http://www.example.com/path?query
)。プロキシリクエストなどで使用されます。abs_path
: パスとオプションのクエリ文字列(例:/path/to/resource?query=value
)。最も一般的な形式で、オリジンサーバーへのリクエストで使用されます。authority
: ホストとポート(例:www.example.com:80
)。CONNECT
メソッドで使用されます。*
: オプションリクエスト(例:OPTIONS * HTTP/1.1
)。
このコミットで特に言及されているのは、
abs_path
形式のRequest-URI
が使用される場合です。この場合、Request-URI
にはスキームやホストの情報が含まれないため、http.Request.URL
がパースされた際に、Scheme
やHost
フィールドが空になるのが自然な挙動となります。 -
Go言語のドキュメンテーション規約: Goでは、エクスポートされた(大文字で始まる)識別子(変数、関数、構造体、フィールドなど)の直前に書かれたコメントが、その識別子のドキュメントとして扱われます。
godoc
ツールやGoの公式ドキュメントサイトでこれらのドキュメントが参照されます。
技術的詳細
このコミットの技術的な核心は、http.Request
構造体の URL
フィールドの挙動に関する明確な説明をコードコメントとして追加することです。
http.Request
構造体は、受信したHTTPリクエストを表現するために使用されます。その中の URL
フィールドは *url.URL
型であり、リクエストされたURIをパースした結果を保持します。しかし、HTTP/1.1の仕様(RFC 2616)では、クライアントがオリジンサーバーに直接リクエストを送信する場合、Request-Lineの Request-URI
は通常 abs_path
形式(例: /path/to/resource?query=value
)を使用します。この形式にはスキーム(http://
や https://
)やホスト名が含まれません。
Goの net/http
パッケージは、この Request-URI
を基に Request.URL
フィールドを生成します。そのため、abs_path
形式のリクエストの場合、Request.URL
の Scheme
や Host
フィールドは空になります。これは仕様に準拠した正しい挙動ですが、url.URL
構造体が完全なURLのすべてのコンポーネントを持つことができるため、開発者は Request.URL
のすべてのフィールドが常に設定されていると誤解しがちでした。
このコミットでは、以下のコメントを追加することで、この誤解を解消します。
// URL is created from the URI supplied on the Request-Line
// as stored in RequestURI.
//
// For most requests, fields other than Path and RawQuery
// will be empty. (See RFC 2616, Section 5.1.2)
URL *url.URL
このコメントは以下の重要な点を明確にしています。
URL
の生成元:Request.URL
はRequest-Line
に含まれるRequestURI
から生成されること。- 一般的なフィールドの空性: ほとんどのリクエストにおいて、
Path
とRawQuery
以外のフィールド(例:Scheme
,Host
,User
,Opaque
,Fragment
)は空になること。 - RFC 2616, Section 5.1.2 への参照: この挙動がHTTP/1.1の仕様(特にRequest-URIの形式に関するセクション)に基づいていることを明示することで、開発者がさらに詳細な情報を参照できるようにしています。
これにより、開発者は Request.URL
を扱う際に、どのフィールドが信頼できるか、どのフィールドが空になり得るかを事前に理解できるようになり、より堅牢なコードを書くことができます。
コアとなるコードの変更箇所
変更は src/pkg/net/http/request.go
ファイルの Request
構造体内の URL
フィールドの定義部分に集中しています。
--- a/src/pkg/net/http/request.go
+++ b/src/pkg/net/http/request.go
@@ -71,7 +71,13 @@ var reqWriteExcludeHeader = map[string]bool{\
// or to be sent by a client.
type Request struct {
Method string // GET, POST, PUT, etc.
- URL *url.URL
+
+ // URL is created from the URI supplied on the Request-Line
+ // as stored in RequestURI.
+ //
+ // For most requests, fields other than Path and RawQuery
+ // will be empty. (See RFC 2616, Section 5.1.2)
+ URL *url.URL
// The protocol version for incoming requests.
// Outgoing requests always use HTTP/1.1.
具体的には、URL *url.URL
の行の直前に、6行のコメントが追加されています。元の1行のコメントが削除され、新しい複数行のコメントに置き換えられています。
コアとなるコードの解説
追加されたコメントは、http.Request
構造体の URL
フィールドのセマンティクスを明確にしています。
// URL is created from the URI supplied on the Request-Line
// as stored in RequestURI.
この行は、Request.URL
がHTTPリクエストの「Request-Line」に含まれるURI(RequestURI
フィールドに格納されているもの)から生成されることを説明しています。これは、サーバーが受信した生のリクエストURIをパースして url.URL
オブジェクトに変換することを示唆しています。
// For most requests, fields other than Path and RawQuery
// will be empty. (See RFC 2616, Section 5.1.2)
この重要な部分は、Request.URL
の Path
と RawQuery
フィールド以外のほとんどのフィールド(例: Scheme
, Host
, User
, Opaque
, Fragment
)が、一般的なリクエストでは空になることを明示しています。これは、HTTP/1.1の仕様(RFC 2616, Section 5.1.2)で定義されている Request-URI
の abs_path
形式(例: /path/to/resource?query=value
)が、スキームやホスト名を含まないためです。このコメントにより、開発者は Request.URL
を利用する際に、どのフィールドが常に利用可能であるかを正確に理解し、不必要なエラーハンドリングや誤った期待を避けることができます。
このドキュメントの追加は、Goの net/http
パッケージの使いやすさと堅牢性を向上させる上で非常に重要です。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/948f0b7a0bf2030bd927ccab7446324ed684d43f
- Go Issue #3805: https://golang.org/issue/3805
- Go CL 7008046: https://golang.org/cl/7008046
参考にした情報源リンク
- RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 (Section 5.1.2 Request-URI): https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
- GoDoc - net/http package: https://pkg.go.dev/net/http
- GoDoc - net/url package: https://pkg.go.dev/net/url
- Go言語のドキュメンテーションの書き方 (godoc): https://go.dev/blog/godoc (一般的な情報源として)