Gorilla Mux router from inside handler only works once then gives 404 page not found

允我心安 提交于 2019-12-30 11:21:23

问题


I'm using Gorilla mux as my router and I'm having a very strange behaviour. On the first request to the server, I get a valid response. But on subsequent requests, I receive a 404 page not found. There are no errors in the console.

My code is pretty straightforward (it can be copy-pasted to test it right out):

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", RootHandler).Name("root")
    http.Handle("/", router)

    log.Println("Listening on port 1337...")
    if err := http.ListenAndServe(":1337", nil); err != nil {
        log.Fatal("http.ListenAndServe: ", err)
    }
}

func RootHandler(w http.ResponseWriter, r *http.Request) {
    content := "Welcome to "
    rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()
    if err != nil {
        log.Printf("mux.CurrentRoute(r).Subrouter().Get(\"root\").URL(): ", err)
    }
    response := content + rootUrl.String()
    fmt.Fprintf(w, response)
}

After some code commenting and tests, it seems the following line is the culprit:

rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()

This method of getting the router inside the handler using the current request comes from another StackOverflow post: How to call a route by its name from inside a handler?

But for a strange reason, it only works once:

shell-1$ go run servertest.go
2014/10/30 13:31:34 Listening on port 1337...

shell-2$ curl http://127.0.0.1:1337
Welcome to /
shell-2$ curl http://127.0.0.1:1337
404 page not found

As you can see, there are no errors in the console.

Does someone have an idea of why it only works once ?


回答1:


The problem is Subrouter() isn't made to return the router, but to create one, thus it changes the matcher of the router it is called on, making you lose the handler.

You could try passing the router to the handler using closures instead.

func RootHandler(router *mux.Router) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        ...
    }
}


来源:https://stackoverflow.com/questions/26653152/gorilla-mux-router-from-inside-handler-only-works-once-then-gives-404-page-not-f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!