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

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

このコミットは、Go言語の標準ライブラリの一部である src/lib/net/dialgoogle_test.go ファイルに対する変更です。このファイルは、net パッケージの機能、特にネットワーク接続とHTTPリクエストのテストに関連しています。具体的には、www.google.com への接続とHTTPリクエストの動作を検証するためのテストコードが含まれています。

コミット

commit 55d13cf139e9aa682e0d71eb9c9453c342ce6f96
Author: Rob Pike <r@golang.org>
Date:   Sun Feb 15 19:58:00 2009 -0800

    change the URL in the test to avoid a redirection that breaks it in sydney.
    
    R=rsc
    OCL=25054
    CL=25054

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

https://github.com/golang/go/commit/55d13cf139e9aa682e0d71eb9c9453c342ce6f96

元コミット内容

このコミットの目的は、テスト内で使用されているURLを変更し、シドニーでのリダイレクトによってテストが失敗するのを回避することです。

変更の背景

Go言語のテストスイートの一部として、www.google.com へのHTTPリクエストをシミュレートするテスト dialgoogle_test.go が存在しました。このテストは、特定のURL (/) に対して GET リクエストを送信し、その応答を検証していました。

しかし、コミットメッセージによると、「シドニーでのリダイレクトによってテストが壊れる」という問題が発生していました。これは、地理的な位置(シドニー)によって www.google.com のルートパス (/) へのアクセスが自動的にリダイレクトされる可能性があったことを示唆しています。テストコードがこのリダイレクトを適切に処理できない、またはリダイレクト後の最終的なURLやコンテンツがテストの期待値と異なっていたため、テストが失敗していたと考えられます。

開発者は、この不安定なテストを修正するために、リダイレクトが発生しにくい、より安定したURL (/intl/en/privacy.html) に変更することを決定しました。これにより、テストの信頼性を向上させ、特定の地域での環境依存の問題を解消することが目的でした。

前提知識の解説

  • Go言語の net パッケージ: Go言語の net パッケージは、ネットワークI/Oプリミティブを提供します。TCP/IP、UDP、ドメイン名解決などのネットワークプログラミングの基盤となります。このコミットでは、net.Conn インターフェース(ネットワーク接続を表す)と net.Dial 関数(ネットワーク接続を確立する)が間接的に関係しています。
  • Go言語の testing パッケージ: Go言語の標準テストフレームワークを提供します。testing.T 型はテスト関数に渡され、テストの失敗を報告したり、ログを出力したりするために使用されます。
  • HTTPプロトコル: Web上でデータを交換するためのプロトコルです。
    • GETリクエスト: サーバーからリソースを取得するための最も一般的なHTTPメソッドです。
    • Hostヘッダー: HTTP/1.1以降で必須となるヘッダーで、リクエストの対象となるサーバーのホスト名とポート番号を指定します。これにより、単一のIPアドレスで複数のドメインをホストするバーチャルホスティングが可能になります。
    • HTTPリダイレクト: サーバーがクライアントに対して、要求されたリソースが別のURLに移動したことを伝える仕組みです。HTTPステータスコード3xx(例: 301 Moved Permanently, 302 Found)で示されます。クライアントは通常、リダイレクトされた新しいURLに自動的にリクエストを再送信します。
  • io.StringBytes: この関数は、Go 1.0より前の古いGoのバージョンで使用されていたもので、文字列をバイトスライスに変換するユーティリティ関数です。現在のGoでは、[]byte("your string") のように直接文字列をバイトスライスにキャストするのが一般的です。このコミットが2009年のものであることを考えると、当時のGoの慣習を反映しています。

技術的詳細

このコミットの核心は、HTTPリクエストのターゲットURLの変更です。

元のテストでは、www.google.com のルートパス (/) に対して GET リクエストを送信していました。 req := io.StringBytes("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");

しかし、Googleのような大規模なWebサービスでは、ユーザーの地理的な位置、言語設定、デバイスの種類などに基づいて、ルートURLへのアクセスが自動的にリダイレクトされることがよくあります。例えば、日本からアクセスすれば google.co.jp に、アメリカからアクセスすれば google.com の英語版ページに、といった具合です。シドニーからのアクセスでは、何らかの理由で特定のローカライズされたページや、一時的なプロモーションページなどにリダイレクトされていた可能性があります。

テストコードは、このリダイレクトを適切に処理するように設計されていなかったか、あるいはリダイレクト後の最終的な応答がテストの期待する形式と異なっていたため、テストが失敗していました。一般的なテストでは、リダイレクトを自動的に追跡しないか、追跡しても最終的なURLやコンテンツが予期しないものである場合に問題が発生します。

新しいURL /intl/en/privacy.html は、Googleのプライバシーポリシーページへのパスです。このページは、通常、地域や言語に依存しない静的なコンテンツであり、リダイレクトされる可能性が低いと考えられます。テストの目的が www.google.com への接続と基本的なHTTPリクエストの動作確認であるならば、特定のコンテンツの正確性を検証するよりも、安定してアクセスできるURLを使用する方が適切です。この変更により、テストの安定性が向上し、特定の地理的条件に左右されずにテストがパスするようになりました。

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

--- a/src/lib/net/dialgoogle_test.go
+++ b/src/lib/net/dialgoogle_test.go
@@ -15,10 +15,10 @@ import (
 // If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address.
 var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
 
-// fd is already connected to www.google.com port 80.\n-// Run an HTTP request to fetch the main page.\n+// fd is already connected to the destination, port 80.\n+// Run an HTTP request to fetch the appropriate page.\n func fetchGoogle(t *testing.T, fd net.Conn, network, addr string) {\n-\treq := io.StringBytes(\"GET / HTTP/1.0\\r\\nHost: www.google.com\\r\\n\\r\\n\");\n+\treq := io.StringBytes(\"GET /intl/en/privacy.html HTTP/1.0\\r\\nHost: www.google.com\\r\\n\\r\\n\");\n \tn, errno := fd.Write(req);\n \n \tbuf := make([]byte, 1000);\n```

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

変更は `src/lib/net/dialgoogle_test.go` ファイル内の `fetchGoogle` 関数にあります。

*   **変更前**:
    ```go
    // fd is already connected to www.google.com port 80.
    // Run an HTTP request to fetch the main page.
    func fetchGoogle(t *testing.T, fd net.Conn, network, addr string) {
    	req := io.StringBytes("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
    	n, errno := fd.Write(req);
    	// ...
    }
    ```
    ここでは、HTTP GETリクエストのパスが `/` (ルートパス) に設定されていました。コメントも「メインページを取得する」と記載されています。

*   **変更後**:
    ```go
    // fd is already connected to the destination, port 80.
    // Run an HTTP request to fetch the appropriate page.
    func fetchGoogle(t *testing.T, fd net.Conn, network, addr string) {
    	req := io.StringBytes("GET /intl/en/privacy.html HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
    	n, errno := fd.Write(req);
    	// ...
    }
    ```
    HTTP GETリクエストのパスが `/intl/en/privacy.html` に変更されました。これに伴い、コメントも「適切なページを取得する」と修正され、特定の「メインページ」に限定されない汎用的な表現になっています。

この変更により、テストは `www.google.com` のルートパスではなく、より安定したプライバシーポリシーページにリクエストを送信するようになり、シドニーでのリダイレクト問題が回避されました。

## 関連リンク

*   Go言語の `net` パッケージドキュメント: [https://pkg.go.dev/net](https://pkg.go.dev/net)
*   Go言語の `testing` パッケージドキュメント: [https://pkg.go.dev/testing](https://pkg.go.dev/testing)
*   HTTP/1.1 RFC 2616 (Hostヘッダーなど): [https://www.rfc-editor.org/rfc/rfc2616](https://www.rfc-editor.org/rfc/rfc2616)

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

*   Go言語の公式リポジトリ (GitHub): [https://github.com/golang/go](https://github.com/golang/go)
*   コミットハッシュ `55d13cf139e9aa682e0d71eb9c9453c342ce6f96` の詳細: [https://github.com/golang/go/commit/55d13cf139e9aa682e0d71eb9c9453c342ce6f96](https://github.com/golang/go/commit/55d13cf139e9aa682e0d71eb9c9453c342ce6f96)
*   一般的なHTTPプロトコルとリダイレクトに関する情報 (MDN Web Docsなど)
*   Go言語の古いバージョンにおける `io.StringBytes` の使用に関する情報 (Goの歴史的ドキュメントやブログ記事など)