先ほど脱線して http のクライアント側の機能に走ってしまったので気を取り直してサーバー側に行きたいと思います。
といってもハローワールドするだけなら凄く簡単。本当に凄く
package main import ( "fmt""net/http" ) func main() { http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "Hello world") }) http.ListenAndServe(":8080", nil) }
HandleFunc でハンドラーを登録して ListenAndServe で待つ。以上終了。できた。
試しに http://localhost:8080/hoge/foo?bar=puyopuyo
を叩いてハンドラーの関数にブレークポイントはってリクエストの構造体の中身を見てみた。
当然と言えば当然だけど基本的なものは詰まってるので、後は頑張ればいけそう。
ちなみにパスに対して何かしらするものを登録するのは HandleFunc の他に Hundle というのがあるみたい。 Handle には以下のような Handler インターフェースを渡す。
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
つまり、さっきのをこれを使う用に書き直すとこんな感じ。
package main import ( "fmt""net/http" ) type MyHandler struct { } func (*MyHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "Hello world!! Handler version.") } func main() { http.Handle("/", &MyHandler{}) http.ListenAndServe(":8080", nil) }
今回は MyHandler がデータを何も持ってない構造体なので、何も嬉しくないけど設定情報とかを持たせれる点で HandleFunc より柔軟そう。
現に以下の FileServer 関数の例では http.FileServer
を使って特定ディレクトリの下のファイルを返すようにしてるみたい。
https://golang.org/pkg/net/http/#FileServer
試しに以下のコードを動かすと C:\Work
の下のファイルを返してくれるようになった。
package main import ( "fmt""net/http" ) type MyHandler struct { } func (*MyHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "Hello world!! Handler version.") } func main() { http.Handle("/", http.FileServer(http.Dir("/work"))) //http.Handle("/", &MyHandler{}) http.ListenAndServe(":8080", nil) }
http.FileServer
関数で作ったやつは、素直にパスをみてファイルを返してくれるみたいなので/static/
とかにマッピングすると C:\Work
の下にも static フォルダを切らないと NotFound になる。
基本的には、パスから static を外して欲しいから、そこらへんのことをしてくれると思われるのが http.StripPrefix
関数。こんな感じでいける。
package main import ( "fmt""net/http" ) type MyHandler struct { } func (*MyHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "Hello world!! Handler version.") } func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/work")))) http.Handle("/", &MyHandler{}) http.ListenAndServe(":8080", nil) }
これで http://localhost:8080/static/hello.txt
にアクセスすると c:\work\hello.txt
の中身が返ってくるし、http://localhost:8080/hogehoge
みたいなのにアクセスすると MyHandler のほうに処理がいく。
結構単純でいいね。