gorilla/mux 使ってwebアプリつくろうと思って下みたいなルーティングを作ったんだけど、 "//"の部分がどうにもダメらしい。
package main import ( "net/http" "github.com/gorilla/mux" ) func init() { r := mux.NewRouter() r.HandleFunc("/*{protocol:(https?)}://{domain}/{path:[a-zA-Z0-9/]+}", BaseHandler) http.Handle("/", r) }
URLパラメータにURLを渡したいんだけどダメみたいだね。 "//"を正規表現に含めるような書き方に変えてもなんかエラーが出てしまう。。。 バグ扱いにして直してくれないかな。
mux - GoDoc ドキュメント読むと正規表現って言ってるんだし受け入れてくれてもいいと思うんだけどな。 とりあえず、過去のissue探してみるか。
追記:
mux単体で動かしてみたら"/"2つ含んだパスだと1つ削ってリダイレクトしてたので、
どこでそんな処理してるか調べてみた。
すると下の部分が該当した。
cleanPath()のなかでpath.Clean()してるのが原因。
mux/mux.go at master · gorilla/mux · GitHub
ServerHTTP()の先頭でcleanPath()呼んでるしな。 https://github.com/gorilla/mux/blob/master/mux.go#L67-99
こうなると、path.Clean呼ばれないようにするにはforkするしかないかな。
2015-02-10 追記:
src/net/http/server.go - The Go Programming Language
gorilla/muxを外してnet/httpしかない状態で試しても同じ状態だったのでソースコードを読んでみたらこんな事なってた。
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { if r.Method != "CONNECT" { if p := cleanPath(r.URL.Path); p != r.URL.Path { _, pattern = mux.handler(r.Host, p) url := *r.URL url.Path = p return RedirectHandler(url.String(), StatusMovedPermanently), pattern } } return mux.handler(r.Host, r.URL.Path) }
// Return the canonical path for p, eliminating . and .. elements. func cleanPath(p string) string { if p == "" { return "/" } if p[0] != '/' { p = "/" + p } np := path.Clean(p) // path.Clean removes trailing slash except for root; // put the trailing slash back if necessary. if p[len(p)-1] == '/' && np != "/" { np += "/" } return np }
すべてのリクエストがcleanPathで一回処理されて、処理の前後で一致しなかったらリダイレクトしてる。cleanPathで必ず除去されると。
こうなると、net/http使わずに実装するぐらいしか方法ないのかな。
HTTP Server is too clean with its URLs - Google グループ
同じこと質問してる人がいたのでこれやればいけるかな。