雑記帳

整理しない情報集

更新情報

Goで簡易サーバを作る

公開日:

カテゴリ: 開発

開発時にWebサーバが必要になったとき、今までずっとnodeでサーバを立てていました。

ところがGo言語ではサーバアプリを作るのが簡単な上に、依存なしのネイティブバイナリ1個にできるため、(筆者の使い方では)便利なことに気づいたので、メモ書きを残しておきます。

ソース

package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
)

func main() {
	var port int
	flag.IntVar(&port, "port", 8080, "serve port")
	flag.IntVar(&port, "p", 8080, "serve port (shorthand)")
	flag.Parse()

	if flag.NArg() > 1 {
		println("Missing arguments.")
		os.Exit(1)
	}

	servePath := "."
	if flag.NArg() == 1 {
		servePath = flag.Arg(0)
	}

	if _, err := os.Stat(servePath); err != nil {
		println("Not found root directory.")
		os.Exit(1)
	}

	fs := http.FileServer(http.Dir(servePath))
	handleFunc := func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Access-Control-Allow-Origin", "*")
		w.Header().Add("Cross-Origin-Opener-Policy", "same-origin")
		w.Header().Add("Cross-Origin-Embedder-Policy", "require-corp")
		fs.ServeHTTP(w, r)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/", handleFunc)

	server := http.Server{
		Addr:    fmt.Sprintf(":%d", port),
		Handler: mux,
	}

	fmt.Printf("Server starting on port :%d.\n", port)
	err := server.ListenAndServe()
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}
}

ビルド

go build -ldflags="-s -w" -trimpath -a -tags netgo serve.go

使い方

# カレントディレクトリでサーバを立てる場合
serve

# 任意のディレクトリでサーバを立てる
serve ./dest
serve /home/app

# 任意のポートでサーバを立てる
serve -p 5555
serve -port 5555

# 任意のディレクトリ・ポートでサーバを立てる
serve -p 5555 ./dest

ポイント

fs := http.FileServer(http.Dir(servePath))

この行が最大のポイントで、なんと指定したパスをルートとした静的ファイルを返すハンドラを作成してくれます。他の言語ではHTTPのリクエストをパースしてファイルを読み込んでレスポンスを返すという記述が必要ですが、Go言語ではこれらをまとめたものが標準で用意されているんですね。

最近たまーに触ることがあるGo言語ですが、デフォルトでlibcすら依存なしのバイナリを作成するので、ファイルサイズに目を瞑ればどこまでもシングルバイナリの作成に向いた言語ですね。

カテゴリ: 開発