Goでサーバを立ち上げる
のは簡単です。
ルートに、URIと関数をセットで登録し、起動すればOKです。
パッケージは、gorilla/mux
を使っています。
URIをいじった際のメソッド(GET
、POST
)を追いたいので、標準エラー出力とレスポンスにメソッドの中身を出力しています。
なぜ標準エラー出力かのツッコミは、一旦置いといてください。
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/api/out", out)
http.ListenAndServe(":8080", r)
}
func out(w http.ResponseWriter, r *http.Request) {
method := r.Method
println(method)
w.Write([]byte(method))
}
正しいURIでアクセス
してみます。上記ソースを起動し、API Clientからアクセスしてみましょう。
アクセス
http://localhost:8080/api/out
出力
POST
意図したとおりに動作しています。
それでは次は
「/」=>「//」にしてアクセス
してみます。「/api/out」=>「/api//out」になっていることにご留意ください。同じく
アクセス
http://localhost:8080/api//out
出力
GET
勝手にGET
に変わっていることが分かります。
そもそも
違うURIでアクセスできてしまうのが問題
なのではないでしょうか。
実は、muxのRouterは、「/」が複数続いた際にそのまま使うか、Cleanしてから使うかを決めるフィールドskipClean
を持っています。
デフォルト値はfalse
で、きれいにCleanしてから使っているので、「//」でもリクエストが通ってしまいます。
まあ、メソッドがPOST
=>GET
に変わってしまうので、リクエストボディが受け取れず正しい処理はできないでしょう。
// If true, when the path pattern is "/path//to", accessing "/path//to"
// will not redirect
skipClean bool
URIを厳密にチェックするには
上記skipClean
をtrue
にすれば良いでしょう。
mux
からRouter
を生成する際に、このフィールドにtrue
をセットします。
r := mux.NewRouter().SkipClean(true)
このようにすることで、「/」=>「//」でアクセスできなくなります。
アクセス
http://localhost:8080/api//out
出力
404 page not found
ソースの完成形はこちら
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter().SkipClean(true)
r.HandleFunc("/api/out", out)
http.ListenAndServe(":8080", r)
}
func out(w http.ResponseWriter, r *http.Request) {
method := r.Method
println(method)
w.Write([]byte(method))
}