Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19100] ファイルの概要

このコミットは、Go言語の公式ドキュメントの一部である doc/go1.3.html ファイルに対する変更です。具体的には、Go 1.3リリースにおける net/http パッケージの重要な新機能に関する記述を完成させ、以前の「TODO」コメントを実際の機能説明に置き換えています。

コミット

commit 1e68e6ae21ec4e88f7f59635831be74e39b26f7c
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Thu Apr 10 15:09:59 2014 -0700

    doc: finish net/http notes in go1.3.html
    
    LGTM=r
    R=r
    CC=golang-codereviews
    https://golang.org/cl/86580043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/1e68e6ae21ec4e88f7f59635831be74e39b26f7c

元コミット内容

このコミットは、doc/go1.3.html ファイル内の net/http パッケージに関する記述を更新し、Go 1.3で導入された以下の新機能に関する説明を追記・修正しています。

  • クライアントリクエストで使用されるTLS接続のプロパティを公開する Response.TLS フィールド。
  • サーバーでHTTPキープアライブ接続を無効にする Server.SetKeepAlivesEnabled メソッド。
  • HTTPクライアントリクエストがTLSハンドシェイクの完了を待つ時間を制限する Transport.TLSHandshakeTimeout 設定。
  • DefaultTransport におけるTCPキープアライブのデフォルト有効化。
  • ListenAndServe および ListenAndServeTLS 使用時の受信サーバーリクエストに対するTCPキープアライブの有効化。
  • サーバー接続のライフサイクルにおける様々なフェーズにフックするための Server.ConnState コールバック。
  • クライアントによるリクエストに対するエンドツーエンドのタイムアウトを指定する Client.Timeout フィールド。

これらの変更は、以前の「TODO」コメントを具体的な説明に置き換える形で実装されています。

変更の背景

このコミットの背景には、Go 1.3のリリースがあります。Go言語は定期的に新しいバージョンをリリースし、そのたびに言語、標準ライブラリ、ツールチェインに様々な改善や新機能が追加されます。net/http パッケージはGoの標準ライブラリの中でも特に重要な部分であり、Webアプリケーションやネットワークサービスを構築する上で中心的な役割を担っています。

Go 1.3では、net/http パッケージにいくつかの重要な機能強化が加えられました。これらの機能は、より堅牢で高性能なネットワークアプリケーションを開発するために不可欠です。しかし、新機能が追加されただけでは開発者はその存在や使い方を知ることができません。そのため、公式ドキュメントである go1.3.html にこれらの新機能を正確かつ詳細に記述する必要がありました。

このコミットは、Go 1.3のリリースノートの一部として、net/http パッケージの変更点を網羅的に文書化することを目的としています。これにより、開発者はGo 1.3にアップグレードする際に、どのような新機能が利用可能になったのか、そしてそれらをどのように活用できるのかを理解できるようになります。特に、以前のバージョンでは実現が困難であったり、手動での実装が必要であったりした機能(例:TLSハンドシェイクのタイムアウト、接続状態のフック、クライアントリクエストのタイムアウト)が標準ライブラリに組み込まれたことで、開発の効率性と信頼性が向上します。

前提知識の解説

このコミットの変更内容を理解するためには、以下のネットワークおよびGo言語の基本的な概念を理解しておく必要があります。

1. HTTP (Hypertext Transfer Protocol)

HTTPは、Web上でデータを交換するためのプロトコルです。クライアント(Webブラウザなど)がサーバー(Webサイトなど)にリクエストを送信し、サーバーがレスポンスを返すという形で通信が行われます。Goの net/http パッケージは、このHTTPプロトコルをGoアプリケーションで簡単に扱うための機能を提供します。

2. TLS (Transport Layer Security)

TLSは、インターネット上での通信を暗号化し、データの盗聴や改ざんを防ぐためのプロトコルです。HTTPS(HTTP Secure)は、HTTP通信をTLSで保護したものです。TLSハンドシェイクは、クライアントとサーバーが安全な通信チャネルを確立するために行う一連のネゴシエーションプロセスです。

3. HTTP Keep-Alive (持続的接続)

HTTP/1.1では、複数のHTTPリクエスト/レスポンスを単一のTCP接続上で送受信できる「持続的接続(Persistent Connections)」、一般に「HTTP Keep-Alive」と呼ばれる機能が導入されました。これにより、リクエストごとに新しいTCP接続を確立するオーバーヘッドが削減され、Webページのロード時間やサーバーの負荷が軽減されます。

4. TCP Keep-Alive

TCP Keep-Aliveは、TCPプロトコルレベルの機能で、アイドル状態のTCP接続がまだ有効であるかどうかを確認するために、定期的に小さなパケット(キープアライブプローブ)を送信するメカニズムです。これにより、ネットワークの途中で接続が切断された場合でも、アプリケーションがそれを検知し、リソースを解放することができます。HTTP Keep-Aliveとは異なるレイヤーの機能であり、混同しないように注意が必要です。HTTP Keep-Aliveはアプリケーション層での接続再利用を指し、TCP Keep-Aliveはトランスポート層での接続の生存確認を指します。

5. Goの net/http パッケージ

Goの net/http パッケージは、HTTPクライアントとサーバーの両方を実装するための包括的な機能を提供します。

  • http.Client: HTTPリクエストを送信するためのクライアント。
  • http.Transport: http.Client の内部で使用され、HTTPリクエストの送信方法(接続の確立、TLSハンドシェイク、プロキシなど)を制御します。DefaultTransport は、http.DefaultClient が使用するデフォルトの Transport です。
  • http.Server: HTTPリクエストを処理するためのサーバー。
  • http.ListenAndServe / http.ListenAndServeTLS: HTTPサーバーを起動するための便利な関数。

技術的詳細

このコミットで文書化された net/http パッケージの各新機能について、技術的な詳細を解説します。

1. Response.TLS フィールド

  • 機能: クライアントがHTTPリクエストを送信し、サーバーからレスポンスを受け取った際、そのレスポンスがTLS接続(HTTPS)を介して行われた場合、http.Response 構造体の新しい TLS フィールドに *tls.ConnectionState 型のデータが格納されるようになりました。
  • 目的: これにより、クライアント側で実際に使用されたTLS接続の詳細(例:TLSバージョン、暗号スイート、サーバー証明書、ピア証明書チェーンなど)をプログラム的に検査できるようになります。これは、セキュリティ監査、デバッグ、または特定のTLSプロパティに基づいて動作を変更する必要がある場合に非常に有用です。
  • 影響: 以前は、クライアント側でTLS接続の詳細を取得するには、より低レベルのネットワーク操作を行う必要がありましたが、このフィールドの追加により、net/http の高レベルAPIを通じて簡単にアクセスできるようになりました。

2. Server.SetKeepAlivesEnabled メソッド

  • 機能: http.ServerSetKeepAlivesEnabled(bool) メソッドが追加され、サーバーがHTTPキープアライブ接続を許可するかどうかを制御できるようになりました。デフォルトでは true であり、キープアライブが有効です。
  • 目的: 通常、HTTPキープアライブはパフォーマンス向上に寄与するため有効にしておくべきです。しかし、リソースが制約されたサーバー(例:組み込みシステム)や、グレースフルシャットダウン(既存の接続を処理しつつ新しい接続を受け付けないようにする)のプロセス中に、新しいキープアライブ接続を無効にしたい場合があります。このメソッドは、そのような特定のシナリオでサーバーの動作を細かく制御するために提供されます。
  • 影響: サーバー管理者は、必要に応じてキープアライブを動的に無効にすることで、サーバーのリソース消費を管理したり、シャットダウンプロセスをよりスムーズに実行したりできるようになります。

3. Transport.TLSHandshakeTimeout 設定

  • 機能: http.Transport 構造体に TLSHandshakeTimeout time.Duration フィールドが追加されました。これは、HTTPクライアントがTLSハンドシェイクの完了を待つ最大時間を設定します。DefaultTransport では、このタイムアウトがデフォルトで設定されるようになりました。
  • 目的: TLSハンドシェイクは、ネットワークの遅延やサーバー側の問題によって時間がかかることがあります。タイムアウトを設定しないと、ハンドシェイクが完了しない場合にクライアントが indefinitely にブロックされる可能性があります。このタイムアウトにより、クライアントは指定された時間内にハンドシェイクが完了しない場合、エラーを返すことでリソースの無駄な消費を防ぎ、アプリケーションの応答性を向上させます。
  • 影響: クライアントアプリケーションは、TLSハンドシェイクの遅延によってハングアップするリスクを軽減し、より堅牢なネットワーク通信を実現できます。

4. DefaultTransport におけるTCP Keep-Alivesのデフォルト有効化

  • 機能: net/http パッケージの DefaultTransporthttp.DefaultClient が使用するデフォルトのトランスポート)が、デフォルトでTCPキープアライブを有効にするようになりました。
  • 目的: TCPキープアライブは、アイドル状態のTCP接続がまだ有効であるかを確認し、ネットワークの途中で接続が切断された場合にそれを検知するのに役立ちます。これにより、クライアントが切断された接続に対してリクエストを送信し続けることを防ぎ、より迅速にエラーを検知してリソースを解放できます。
  • 影響: http.DefaultClient を使用するアプリケーションは、特別な設定なしに、より堅牢な接続管理の恩恵を受けられるようになります。ただし、Dial フィールドが nil でないカスタムの Transport を使用している場合は、以前と同様にTCPキープアライブは使用されません。

5. ListenAndServe および ListenAndServeTLS 使用時のTCP Keep-Alives有効化

  • 機能: http.ListenAndServe および http.ListenAndServeTLS 関数を使用してHTTPサーバーを起動した場合、受信するサーバーリクエストに対してTCPキープアライブが有効になるようになりました。
  • 目的: クライアント側と同様に、サーバー側でもアイドル状態の接続の生存確認は重要です。これにより、クライアントが予期せず切断された場合に、サーバーがその接続に関連するリソースをより早く解放できるようになります。
  • 影響: これらの便利な関数を使用するサーバーは、自動的にTCPキープアライブの恩恵を受け、リソースリークのリスクを低減できます。ただし、http.Server を直接インスタンス化して Serve メソッドを呼び出すなど、他の方法でサーバーを起動した場合は、TCPキープアライブは自動的には有効になりません。

6. Server.ConnState コールバック

  • 機能: http.ServerConnState func(net.Conn, ConnState) 型の ConnState フィールドが追加されました。これは、サーバー接続のライフサイクルにおける様々な状態変化(新しい接続、アクティブなリクエスト処理中、アイドル状態、クローズ)をフックするためのコールバック関数です。
  • 目的: このコールバックは、サーバー接続のより詳細な制御と監視を可能にします。例えば、以下のような用途が考えられます。
    • レートリミット: 特定のIPアドレスからの同時接続数を制限する。
    • グレースフルシャットダウン: サーバーがシャットダウンする際に、既存の接続が完了するのを待つ。
    • 接続の統計情報: アクティブな接続数やアイドル接続数などを追跡する。
    • デバッグ: 接続の状態遷移をログに記録する。
  • 影響: サーバー開発者は、net/http パッケージの抽象化レベルを維持しつつ、接続管理に関するより高度なロジックを実装できるようになります。

7. Client.Timeout フィールド

  • 機能: http.Client 構造体に Timeout time.Duration フィールドが追加されました。これは、クライアントが単一のHTTPリクエスト(リダイレクトを含む)の完了を待つ最大時間を指定するエンドツーエンドのタイムアウトです。
  • 目的: ネットワークの遅延、サーバーの応答遅延、またはその他の問題により、HTTPリクエストが完了するまでに非常に長い時間がかかることがあります。タイムアウトを設定しないと、クライアントアプリケーションが indefinitely にブロックされ、リソースを消費し続ける可能性があります。この Timeout フィールドは、DNSルックアップ、接続確立、TLSハンドシェイク、リクエストの書き込み、レスポンスヘッダーの読み取り、レスポンスボディの読み取りを含む、リクエスト全体の処理時間を制限します。
  • 影響: クライアントアプリケーションは、ネットワーク操作のタイムアウトを簡単に設定できるようになり、アプリケーションの応答性と堅牢性が大幅に向上します。以前は、各ステージ(DialerのTimeout、TLSHandshakeTimeoutなど)で個別にタイムアウトを設定する必要がありましたが、このフィールドにより一元的に制御できるようになりました。

コアとなるコードの変更箇所

このコミットにおけるコアとなるコードの変更箇所は、doc/go1.3.html ファイルです。

--- a/doc/go1.3.html
+++ b/doc/go1.3.html
@@ -278,7 +278,7 @@ as a synonym for <code>%f</code> when printing floating-point values.\n \n <li>\n The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package now exposes the\n-the properties of a TLS connection used to make a client request in the new\n+properties of a TLS connection used to make a client request in the new\n <a href=\"/pkg/net/http/#Response\"><code>Response.TLS</code></a> field.\n </li>\n \n@@ -289,15 +289,61 @@ with <a href=\"/pkg/net/http/#Server\"><code>Server.ErrorLog</code></a>.\n The default is still that all errors go to stderr.\n </li>\n \n-<li> TODO: net/http: add Server.SetKeepAlivesEnabled (CL 69670043)</li>\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package now\n+supports disabling HTTP keep-alive connections on the server\n+with <a href=\"/pkg/net/http/#Server.SetKeepAlivesEnabled\"><code>Server.SetKeepAlivesEnabled</code></a>.\n+The default continues to be that the server does keep-alive (reuses\n+connections for multiple requests) by default.  Only\n+resource-constrained servers or those in the process of graceful\n+shutdown will want to disable them.\n+</li>\n \n-<li> TODO: net/http: add Transport.TLSHandshakeTimeout; set it by default (CL 68150045)</li>\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package adds an optional\n+<a href=\"/pkg/net/http/#Transport\"><code>Transport.TLSHandshakeTimeout</code></a>\n+setting to cap the amount of time HTTP client requests will wait for\n+TLS handshakes to complete. It\'s now also set by default\n+on <a href=\"/pkg/net/http#DefaultTransport\"><code>DefaultTransport</code></a>.\n+</li>\n \n-<li> TODO: net/http: add optional Server.ConnState callback (CL 69260044)</li>\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package\'s\n+<a href=\"/pkg/net/http/#DefaultTransport\"><code>DefaultTransport</code></a>,\n+used by the HTTP client code, now\n+enables <a href=\"http://en.wikipedia.org/wiki/Keepalive#TCP_keepalive\">TCP\n+keep-alives</a> by\n+default. Other <a href=\"/pkg/net/http/#Transport\"><code>Transport</code></a>\n+values with a nil <code>Dial</code> field continue to function the same\n+as before: no TCP keep-alives are used.\n+</li>\n \n-<li> TODO: net/http: use TCP Keep-Alives on DefaultTransport\'s connections (CL 68330046)</li>\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package\n+now enables <a href=\"http://en.wikipedia.org/wiki/Keepalive#TCP_keepalive\">TCP\n+keep-alives</a> for incoming server requests when\n+<a href=\"/pkg/net/http/#ListenAndServe\"><code>ListenAndServe</code></a>\n+or\n+<a href=\"/pkg/net/http/#ListenAndServeTLS\"><code>ListenAndServeTLS</code></a>\n+are used. When a server is started otherwise, TCP keep-alives are not enabled.\n+</li>\n \n-<li> TODO: net/http: use TCP keep-alives for ListenAndServe and ListenAndServeTLS (CL 48300043)</li>\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package now\n+provides an\n+optional <a href=\"/pkg/net/http/#Server\"><code>Server.ConnState</code></a>\n+callback to hook various phases of a server connection\'s lifecycle\n+(see <a href=\"/pkg/net/http/#ConnState\"><code>ConnState</code></a>). This\n+can be used to implement rate limiting or graceful shutdown.\n+</li>\n+\n+<li>\n+The <a href=\"/pkg/net/http/\"><code>net/http</code></a> package\'s HTTP\n+client now has an\n+optional <a href=\"/pkg/net/http/#Client\"><code>Client.Timeout</code></a>\n+field to specify an end-to-end timeout on requests made using the\n+client.\n+</li>\n \n <li> In the <a href=\"/pkg/net/\"><code>net</code></a> package,\n the <a href=\"/pkg/net/#Dialer\"><code>Dialer</code></a> struct now\n```

この差分は、主に以下の変更を示しています。

- 既存の `Response.TLS` フィールドに関する記述の軽微な修正。
- 複数の「TODO」コメント行が削除され、それぞれのTODOが指していた `net/http` の新機能に関する詳細なHTML記述に置き換えられています。これには、`Server.SetKeepAlivesEnabled`、`Transport.TLSHandshakeTimeout`、`DefaultTransport` および `ListenAndServe`/`ListenAndServeTLS` におけるTCPキープアライブ、`Server.ConnState`、そして `Client.Timeout` に関する説明が含まれます。

## コアとなるコードの解説

このコミットの「コアとなるコード」は、Go 1.3のリリースノートである `doc/go1.3.html` ファイルそのものです。このファイルは、Go言語の新しいバージョンがリリースされる際に、そのバージョンで導入された主要な変更点、新機能、改善点などを開発者に伝えるための公式ドキュメントとして機能します。

このコミットで行われた変更は、Go 1.3で `net/http` パッケージに導入された重要な機能強化を、開発者が理解しやすい形で文書化することにあります。具体的には、以前のバージョンでは存在しなかった、あるいは明示的に設定する必要があった機能が、Go 1.3で標準ライブラリに組み込まれたことを説明しています。

- **`Response.TLS`**: クライアントがTLS接続の詳細を簡単に取得できるようにすることで、セキュリティ関連の処理やデバッグが容易になります。
- **`Server.SetKeepAlivesEnabled`**: サーバーのHTTPキープアライブ動作を細かく制御する能力を提供し、特定の運用シナリオ(リソース制約、グレースフルシャットダウン)での柔軟性を高めます。
- **`Transport.TLSHandshakeTimeout`**: クライアント側のTLSハンドシェイクのタイムアウトを設定することで、ネットワークの不安定性やサーバーの応答遅延によるアプリケーションのハングアップを防ぎ、堅牢性を向上させます。
- **TCP Keep-Alivesのデフォルト有効化**: `DefaultTransport` および `ListenAndServe`/`ListenAndServeTLS` を使用する際に、TCPレベルでの接続生存確認が自動的に行われるようになり、アイドル接続のリソースリークを防ぎ、切断された接続をより迅速に検知できるようになります。
- **`Server.ConnState`**: サーバー接続のライフサイクルをフックするメカニズムを提供し、レートリミット、グレースフルシャットダウン、接続統計の収集など、より高度なサーバーサイドロジックの実装を可能にします。
- **`Client.Timeout`**: クライアントリクエスト全体のエンドツーエンドのタイムアウトを設定するシンプルな方法を提供し、アプリケーションの応答性と信頼性を大幅に向上させます。

これらのドキュメントの追加は、単なるテキストの変更以上の意味を持ちます。それは、Go 1.3がネットワークプログラミングにおいて、より高度な制御、堅牢性、そして使いやすさを提供することを示すものです。開発者はこのドキュメントを通じて、新しいAPIを効果的に利用し、より高性能で信頼性の高いネットワークアプリケーションを構築できるようになります。

## 関連リンク

- Go 1.3 Release Notes (公式ドキュメント): このコミットが更新しているドキュメントの全体像を理解するために参照すると良いでしょう。
- `net/http` パッケージのGoDoc: 各APIの詳細な説明と使用例が記載されています。
    - [https://pkg.go.dev/net/http](https://pkg.go.dev/net/http)
- TCP Keep-Aliveに関するWikipedia記事:
    - [https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive](https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive)

## 参考にした情報源リンク

- コミットメッセージと差分情報: GitHubのコミットページ
- Go言語の公式ドキュメント: `go1.3.html` の内容と構造
- `net/http` パッケージのGoDoc: 各APIの機能と目的
- TCP/IPおよびHTTPプロトコルに関する一般的な知識
- Go言語のリリースプロセスとドキュメンテーションの慣習に関する理解
- Wikipedia: TCP Keep-Alive