問題: ミドルウェアから mux.CurrentRoute(r).GetName() にアクセスできません。(ミドルウェアからアクセスできましたが、以前はリクエストにアクセスできなかったため、ミドルウェアの動作方法を変更する必要がありました)。そのため、何かをいじってしまい、ルート名にアクセスできる作業状態に戻す方法がわかりません。
どんな助けでも大歓迎です!
エラー:
runtime error: invalid memory address or nil pointer dereference
コード:
func main() {
var (
err error
r *mux.Router
devRouter *mux.Router
usersRouter *mux.Router
brandsRouter *mux.Router
)
defer db.Close()
defer store.Close()
r = mux.NewRouter()
devRouter = r.PathPrefix("/api/v1/dev").Subrouter()
usersRouter = r.PathPrefix("/api/v1/users").Subrouter()
brandsRouter = r.PathPrefix("/api/v1/brands").Subrouter()
// development endpoints
devRouter.HandleFunc("/db/seed", devDbSeed)
...
// users
usersRouter.HandleFunc("/create", usersCreateHandlerFunc).Methods("POST").Name("USERS_CREATE")
...
// brands
brandsRouter.HandleFunc("/create", brandsCreateHandlerFunc).Methods("POST").Name("BRANDS_CREATE")
...
// products
brandsRouter.HandleFunc("/{brand_id:[0-9]+}/products", brandsProductsListHandlerFunc).Methods("GET").Name("BRANDS_PRODUCTS_LIST")
...
// mwAuthorize and mwAuthenticate basically work the same
mw := []func(http.Handler) http.Handler{mwAuthenticate, mwAuthorize}
http.Handle("/", use(r, mw...))
err = http.ListenAndServe(":9000", nil)
if err != nil {
logIt(err)
}
}
func use(h http.Handler, mw ...func(http.Handler) http.Handler) http.Handler {
// exec order: mw[0],mw[1],mw[N]...
for i := len(mw) - 1; i >= 0; i-- {
h = mw[i](h)
}
return h
}
func mwAuthorize(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if true != authorize(r) {
w.WriteHeader(http.StatusForbidden)
return
} else {
next.ServeHTTP(w, r)
}
})
}
func authorize(r *http.Request) (isAuthorized bool) {
isAuthorized = false
/**
This is where it's failing!
*/
routeName := mux.CurrentRoute(r).GetName()
switch routeName {
case "USERS_CREATE":
// route-specific authorization
break
...
default:
break
}
return
}
更新 (2015-01-04 @ 4:49PM EST): したがって、ミドルウェアを削除した後 (または、少なくとも mux.CurrentRoute を読み取ろうとしているセクションをコメントアウトした後)、宛先の handlerfunc からルート名を取得できます (例: usersCreateHandlerFunc または BrandsCreateHandlerFunc)。これは私の問題を解決しません (すべての handlerfunc とは対照的に、ミドルウェアで認証/承認を実行したいのですが)、*mux.Router は最終的な後までミドルウェアで使用できないことを知らせてくれる予感があります。 .ServeHTTP 呼び出し。(または、それらの線に沿った何か...)
更新 (2015 年 1 月 4 日 @ 午後 5 時 41 分 EST): Negroni をミドルウェア コンポーネントとして使用する別の方向 (あまり好まれませんが) を試しました。mux.CurrentRoute を取得しようとすると、まだ nil-pointer エラーが発生します。
更新 (2015-01-04 @ 6:17PM EST): ミドルウェア機能からリクエスト (例: r.URL) にアクセスできますが、mux.Route (例: mux.CurrentRoute( r)))。マルチプレクサのソースをもう少し調べたところ、ルーターがまだマッチャーを実行していないため、現在のマルチプレクサ コンテキストが設定されていないことが原因だと思います (したがって、ミドルウェアが処理されるまで現在のルートがわからないためです)。完了です)。ただし、これを解決する方法、またはこれを処理するためにコードを再構築する方法はまだわかりません。