我正在尝试为我的http文件服务器编写单元测试。 我已经实现了ServeHTTP函数,以便将URL中的“ //”替换为“ /”:
type slashFix struct {
mux http.Handler
}
func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r.URL.Path = strings.Replace(r.URL.Path, "//", "/", -1)
h.mux.ServeHTTP(w, r)
}
最起码的代码如下:
func StartFileServer() {
httpMux := http.NewServeMux()
httpMux.HandleFunc("/abc/", basicAuth(handle))
http.ListenAndServe(":8000", &slashFix{httpMux})
}
func handle(writer http.ResponseWriter, r *http.Request) {
dirName := "C:\\Users\\gayr\\GolandProjects\\src\\NDAC\\download\\"
http.StripPrefix("/abc",
http.FileServer(http.Dir(dirName))).ServeHTTP(writer, r)
}
func basicAuth(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if user != "UserName" || pass != "Password" {
w.WriteHeader(401)
w.Write([]byte("Unauthorised.\n"))
return
}
handler(w, r)
}
}
我遇到了以下实例来测试http处理程序:
req, err := http.NewRequest("GET", "/abc/testfile.txt", nil)
if err != nil {
t.Fatal(err)
}
req.SetBasicAuth("UserName", "Password")
rr := httptest.NewRecorder()
handler := http.HandlerFunc(basicAuth(handle))
handler.ServeHTTP(rr, req)
这样做将调用使用http.HandleFunc实现的ServeHTTP函数,但是我希望调用在我的代码中实现的ServeHTTP。如何做到这一点?另外,有没有办法让我直接测试StartFileServer()?
编辑:我检查了评论中提供的链接;我的问题似乎不是重复的。我有一个具体的问题:我不想调用使用http.HandleFunc实现的ServeHTTP函数,而是要调用在我的代码中实现的ServeHTTP。在提供的链接中看不到此问题。
答案 0 :(得分:2)
http.HandlerFunc实现http.Handler。正如Flimzy在评论中指出的那样,不需要basicAuth就需要HandlerFunc;任何http.Handler都可以。坚持使用http.Handler接口而不是具体的HandlerFunc类型将使所有内容都易于组合:
func basicAuth(handler http.Handler) http.Handler { // Note: http.Handler, not http.HandlerFunc
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok {
// TODO
}
if user != "UserName" || pass != "Password" {
w.WriteHeader(401)
w.Write([]byte("Unauthorised.\n"))
return
}
handler.ServeHTTP(w, r)
})
}
func TestFoo(t *testing.T) {
req, err := http.NewRequest("GET", "/abc/testfile.txt", nil)
if err != nil {
t.Fatal(err)
}
req.SetBasicAuth("UserName", "Password")
rr := httptest.NewRecorder()
// composition is trivial now
sf := &slashFix{
mux: http.HandlerFunc(handle),
}
handler := basicAuth(sf)
handler.ServeHTTP(rr, req)
// assert correct rr
}