goで作ったhttpサーバーは、標準ライブラリだけで静的ファイルを配信することもできる。
以下は ./static 以下にあるファイルを配信するサンプル。
package main
import (
"net/http"
)
func main() {
mux := http.NewServeMux()
fileServer := http.FileServer(http.Dir("./static"))
mux.Handle("/static/", http.StripPrefix("/static/", fileServer))
server := http.Server{
Addr: ":8080",
Handler: mux,
}
server.ListenAndServe()
}
こういう風にすれば良いんだけど、chiと組み合わせる時に少し苦戦した。
chiはルーティングを設定するとき
r.Get("/ping", pingHandler)
func pingHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World!")
}
みたいに handlerを指定するので、 http.StripPrefix("/static/", fileServer)
をぶち込んでもうまくいかない。
なので、
package main
import (
"net/http"
"os"
"github.com/go-chi/chi"
)
func main() {
r := chi.NewRouter()
fileServer := http.FileServer(http.Dir("./static/"))
r.Get("/static/",
func (w http.ResponseWriter, r *http.Request) {
http.StripPrefix("/static/", fileServer).ServeHTTP(w, r)
},
)
http.ListenAndServe(":8080", r)
}
という風に変換を挟んであげれば動くようになる。なるのだが、今度は /static
にはアクセスできても、その配下のファイルには404でアクセスできない。
なぜなら /static
にしかルーティングしていないから。
結論としては、chi はワイルドカードの指定に対応しているので、
package main
import (
"net/http"
"os"
"github.com/go-chi/chi"
)
func main() {
r := chi.NewRouter()
fileServer := http.FileServer(http.Dir("./static/"))
r.Get("/static/*",
func (w http.ResponseWriter, r *http.Request) {
http.StripPrefix("/static/", fileServer).ServeHTTP(w, r)
},
)
http.ListenAndServe(":8080", r)
}
こういう風にワイルドカードを指定すれば良い。