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

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

このコミットは、Go言語の標準ライブラリ net/http パッケージ内の example_test.go ファイルにおける FileServer の使用例を改善するものです。具体的には、http.FileServer の基本的な使用方法と、http.StripPrefix を用いてURLパスを調整しながら静的ファイルを提供するより実践的な例を追加・修正しています。

コミット

commit d97157d3825f12e7b9702474136085276f7ef0a0
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Thu Apr 4 13:40:15 2013 -0700

    net/http: better stand-alone FileServer doc example
    
    Motivated by a deletion in the wiki, which had a better
    example.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/8288045

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

https://github.com/golang/go/commit/d97157d3825f12e7b9702474136085276f7ef0a0

元コミット内容

net/http: better stand-alone FileServer doc example (net/http: より良いスタンドアロンのFileServerドキュメント例)

Motivated by a deletion in the wiki, which had a better example. (より良い例が記載されていたWikiの削除に動機付けられた。)

変更の背景

このコミットの背景には、Go言語の公式Wikiから、http.FileServer のより実践的で分かりやすい使用例が削除されたという経緯があります。コミットメッセージにある「Motivated by a deletion in the wiki, which had a better example.」がそれを示しています。

net/http.FileServer はGoで静的ファイルを提供する際に非常に便利な機能ですが、特に http.StripPrefix と組み合わせて特定のURLパスからファイルを配信するケースは、ウェブアプリケーション開発で頻繁に登場します。しかし、その設定方法が初心者には直感的でない場合があります。

以前の ExampleFileServer の例は、StripPrefix の使用に焦点を当てていましたが、FileServer の最も基本的な「静的ウェブサーバー」としての役割を示すには不十分でした。Wikiに存在したより良い例が失われたことで、公式ドキュメントの例を改善し、開発者が FileServer の使い方をより簡単に理解できるようにする必要性が生じました。

この変更は、Goの標準ライブラリのドキュメントと例の品質を向上させ、開発者の学習体験をよりスムーズにすることを目的としています。

前提知識の解説

このコミットを理解するためには、Go言語の net/http パッケージにおける以下の概念を理解しておく必要があります。

  1. net/http パッケージ: Go言語でHTTPクライアントおよびサーバーを実装するための標準ライブラリです。ウェブアプリケーション開発の基盤となります。

  2. http.Handler インターフェース: net/http パッケージの中心的な概念の一つで、HTTPリクエストを処理するためのインターフェースです。

    type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
    }
    

    ServeHTTP メソッドは、HTTPリクエストを受け取り、それに応答を書き込む責任を持ちます。

  3. http.FileServer(root FileSystem) Handler: 指定された FileSystem からファイルを提供する http.Handler を返します。これは、ウェブサーバーが静的ファイル(HTML、CSS、JavaScript、画像など)を配信するために使用されます。 http.Dirhttp.FileSystem インターフェースを実装しており、ローカルファイルシステムのディレクトリを FileServer に渡すことができます。

  4. http.Dir(dir string) FileSystem: 指定されたディレクトリをルートとするファイルシステムを返します。http.FileServer に渡すことで、そのディレクトリ以下のファイルを配信できるようになります。

  5. http.ListenAndServe(addr string, handler Handler) error: 指定されたアドレス (addr) でHTTPサーバーを起動し、受信したリクエストを handler に渡して処理させます。handlernil の場合、http.DefaultServeMux が使用されます。これは、GoでHTTPサーバーを起動する最も一般的な方法です。

  6. http.Handle(pattern string, handler Handler): 指定されたURLパスパターン (pattern) に対応する handler を登録します。これにより、特定のURLへのリクエストがその handler によって処理されるようになります。

  7. http.StripPrefix(prefix string, h Handler) Handler: この関数は、非常に重要です。これは http.Handler をラップするもので、受信したリクエストのURLパスから指定された prefix を取り除いてから、内部の h (別の http.Handler) にリクエストを渡します。 例えば、/static/ というURLパスで /path/to/static_files/ ディレクトリのファイルを配信したい場合、FileServer/path/to/static_files/ をルートとして /index.html のようなパスを期待します。しかし、ブラウザからのリクエストは /static/index.html となります。ここで StripPrefix("/static/", ...) を使うことで、FileServer に渡されるパスが /index.html となり、正しくファイルが配信されます。

  8. _test.go ファイルと Example 関数: Go言語では、_test.go で終わるファイルはテストファイルとして扱われます。このファイル内に Example というプレフィックスを持つ関数を定義すると、それはドキュメントの例として抽出され、go doc コマンドや godoc サーバーで表示されます。これらの例は、コードの動作を簡潔に示し、ドキュメントの品質を高めるために非常に有用です。

技術的詳細

このコミットは、net/http パッケージの example_test.go ファイルを修正し、http.FileServer の使用例をより明確で包括的なものにしています。

変更のポイントは以下の通りです。

  1. ExampleFileServer の変更:

    • 以前の ExampleFileServerhttp.StripPrefix を使用した例のみを含んでいました。これは FileServer の一般的なユースケースの一つですが、最も基本的な「静的ウェブサーバー」としての役割を直接示していませんでした。
    • 新しい ExampleFileServer は、http.FileServer(http.Dir("/usr/share/doc")) を直接 http.ListenAndServe に渡すことで、指定されたディレクトリ (/usr/share/doc) の内容をそのままルート (/) から配信する、最もシンプルな静的サーバーの例を示しています。これにより、FileServer の基本的な機能がより明確になります。
    • log.Fatal を使用してサーバーの起動とエラーハンドリングを簡潔に示しています。
  2. ExampleFileServer_stripPrefix の追加:

    • 以前の ExampleFileServer が持っていた StripPrefix を使用する例は、ExampleFileServer_stripPrefix という新しい関数として分離されました。
    • この新しい関数名により、StripPrefix の具体的なユースケース(URLパスの調整)が明確に示されます。
    • コメントも「Simple static webserver:」から「To serve a directory on disk (/tmp) under an alternate URL path (/tmpfiles/), use StripPrefix to modify the request URL's path before the FileServer sees it:」と、より詳細で分かりやすい説明に更新されています。これにより、なぜ StripPrefix が必要なのか、その目的が明確になります。
  3. ExampleStripPrefix の変更:

    • ExampleStripPrefix 関数は、元々 ExampleFileServer と全く同じコードを含んでいました。これは冗長であり、StripPrefix 自体の例としては不十分でした。
    • このコミットでは、ExampleStripPrefix のコードは変更されていませんが、ExampleFileServer_stripPrefix が追加されたことで、StripPrefix の使用例がより適切に配置され、ドキュメントとしての役割が明確になりました。ExampleStripPrefixStripPrefix の一般的な説明として機能し、ExampleFileServer_stripPrefixFileServer との組み合わせの具体的な例として機能します。

これらの変更により、net/http パッケージのドキュメントは、FileServer の基本的な使い方と、StripPrefix と組み合わせたより高度な使い方を、それぞれ独立した、しかし関連性の高い例として提供できるようになりました。これは、Goのドキュメントがコード例を通じて機能の理解を深めるという哲学に沿った改善です。

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

--- a/src/pkg/net/http/example_test.go
+++ b/src/pkg/net/http/example_test.go
@@ -51,11 +51,20 @@ func ExampleGet() {
 }
 
 func ExampleFileServer() {
-	// we use StripPrefix so that /tmpfiles/somefile will access /tmp/somefile
-+	// Simple static webserver:
-+	log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
++}
++
++func ExampleFileServer_stripPrefix() {
++	// To serve a directory on disk (/tmp) under an alternate URL
++	// path (/tmpfiles/), use StripPrefix to modify the request
++	// URL's path before the FileServer sees it:
+ 	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
 }
 
 func ExampleStripPrefix() {
-	// we use StripPrefix so that /tmpfiles/somefile will access /tmp/somefile
-+	// To serve a directory on disk (/tmp) under an alternate URL
-+	// path (/tmpfiles/), use StripPrefix to modify the request
-+	// URL's path before the FileServer sees it:
+ 	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
 }

コアとなるコードの解説

このコミットでは、src/pkg/net/http/example_test.go ファイル内の ExampleFileServer 関数が大幅に修正され、新たに ExampleFileServer_stripPrefix 関数が追加されました。

  1. func ExampleFileServer() の変更:

    • 削除された行:
      // we use StripPrefix so that /tmpfiles/somefile will access /tmp/somefile
      http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
      
      以前の ExampleFileServer は、http.StripPrefix を使用して /tmpfiles/ というURLパスで /tmp ディレクトリのファイルを配信する例でした。これは FileServer の一般的な使い方ですが、FileServer 自体の最も基本的な機能を示すものではありませんでした。
    • 追加された行:
      // Simple static webserver:
      log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
      
      新しい ExampleFileServer は、http.FileServer の最もシンプルな使用例を示しています。
      • http.Dir("/usr/share/doc"): /usr/share/doc ディレクトリをファイルシステムのルートとして指定します。
      • http.FileServer(...): このファイルシステムからファイルを提供するハンドラを作成します。
      • http.ListenAndServe(":8080", ...): ポート 8080 でHTTPサーバーを起動し、すべてのリクエストを FileServer ハンドラに渡します。これにより、http://localhost:8080/ にアクセスすると /usr/share/doc ディレクトリの内容が直接配信される、基本的な静的ウェブサーバーが構築されます。
      • log.Fatal(...): サーバーの起動に失敗した場合にエラーをログに出力し、プログラムを終了させます。
  2. func ExampleFileServer_stripPrefix() の追加:

    • 追加された行:
      func ExampleFileServer_stripPrefix() {
          // To serve a directory on disk (/tmp) under an alternate URL
          // path (/tmpfiles/), use StripPrefix to modify the request
          // URL's path before the FileServer sees it:
          http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
      }
      
      この新しい関数は、以前 ExampleFileServer にあった StripPrefix を使用する例を独立させ、より明確な名前と説明を付けています。
      • http.Handle("/tmpfiles/", ...): /tmpfiles/ で始まるURLパスのリクエストを処理するように設定します。
      • http.StripPrefix("/tmpfiles/", ...): 受信したリクエストのURLパスから /tmpfiles/ というプレフィックスを取り除きます。例えば、/tmpfiles/somefile.txt というリクエストは /somefile.txt に変換されます。
      • http.FileServer(http.Dir("/tmp")): /tmp ディレクトリをルートとするファイルサーバーを作成します。 この組み合わせにより、ブラウザから http://localhost:8080/tmpfiles/somefile.txt にアクセスすると、サーバーは /tmp/somefile.txt を配信します。これは、URLパスと実際のファイルシステムパスを分離する一般的なパターンです。
  3. func ExampleStripPrefix() の変更:

    • この関数は、以前から存在しており、StripPrefix の使用例を示していました。コミットの差分では変更がないように見えますが、実際には ExampleFileServer から移動されたコードと同じ内容が元々含まれていました。このコミットにより、ExampleFileServer_stripPrefix が追加されたことで、StripPrefix の具体的なユースケースがより適切に示されるようになりました。ExampleStripPrefixStripPrefix 自体の一般的な説明として機能し、ExampleFileServer_stripPrefixFileServer との組み合わせの具体的な例として機能します。

これらの変更により、Goの net/http パッケージのドキュメントは、FileServer の基本的な使い方と、StripPrefix と組み合わせたより実践的な使い方を、それぞれ独立した、しかし関連性の高い例として提供できるようになり、開発者にとってより分かりやすくなりました。

関連リンク

参考にした情報源リンク