Запрос перенаправления в Go, карта HandleFuncs
Я хочу сопоставить пути к файлам, которые живут в другом месте. Но мой код служит /path/c.txt
когда я посещаю /a
, вместо /path/a.txt
, Что я делаю неправильно?
package main
import (
"fmt"
"net/http"
)
func main() {
fileRoutes := map[string]string {
"/a": "/path/a.txt",
"/b": "/path/b.txt",
"/c": "/path/c.txt",
}
for req, path := range fileRoutes {
http.HandleFunc(req, func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("actual request: %v\n", r.URL.Path)
fmt.Printf("registered request: %v\n", req)
r.URL.Path = path
fmt.Println(req)
fmt.Println(path)
// serveFile(w, r)
})
}
http.ListenAndServe(":8004", nil)
}
Этот пример кода производит:
actual request: /a
registered request: /c
/c
/path/c.txt
Спасибо!
2 ответа
Проблема в том, что все функции дескриптора обращаются одинаково req
а также path
который установлен в последнюю переменную цикла после цикла, которые /c
а также /path/c.txt
,
Чтобы исправить проблему, добавьте req,path := req,path
до http.HandleFunc(...)
,
Это кажется странным. Что он делает, чтобы объявить новый req
а также path
в области цикла, которая является новой для каждой итерации, поэтому каждое замыкание связывается с различным значением.
Другое решение было бы тем, которое используется здесь (которое я благодаря ответу теперь понимаю): https://github.com/golang/blog/blob/master/rewrite.go:
path := fileRoutes[req]
до http.HandleFunc