Go の http パッケージを使って hello server を書いてみる
hello.go
package main
import (
"io"
"net/http"
)
func HelloServer(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello World.\n")
}
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8000", nil)
}
このサーバーは、 keep-alive してくれない。 Content-Length
ヘッダーをつけていないと勝手に Transfer-Encoding: chunked
になって、 chunked だと keep-alive してくれない。
Content-Length
ヘッダーをつけると、勝手に keep-alive してくれるようになる。
hello.go
package main
import (
"strconv"
"io"
"net/http"
)
func HelloServer(w http.ResponseWriter, req *http.Request) {
msg := "Hello World.\n"
w.Header().Add("Content-Length", strconv.Itoa(len(msg)))
io.WriteString(w, msg)
}
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8000", nil)
}
今度は勝手に Connection: keep-alive
をつけてくれて、ちゃんと keep-alive に対応してくれる。
でも、 chunked エンコーディングはいらないけど、 keep-alive はしたくない場合もあるだろう。 (kazeburoの罠とか)
その場合は明示的に Connection: close
ヘッダーを書いてやる。
hello.go
package main
import (
"strconv"
"io"
"net/http"
)
func HelloServer(w http.ResponseWriter, req *http.Request) {
msg := "Hello World.\n"
w.Header().Add("Content-Length", strconv.Itoa(len(msg)))
w.Header().Add("Connection", "close")
io.WriteString(w, msg)
}
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8000", nil)
}
Go の HTTP サーバーはパフォーマンスも結構良くて、コードも読みやすいので、HTTPサーバー自体に機能を組み込みたい時は Apache や nginx のモジュールを書く代わりに Go で Web アプリを書くという選択肢はありそう。