为什么http.Get导致两个请求而不是一个?

Ger*_*ens 1 testing http go server

创建一个测试文件./bower_components/index.html,并运行go test./.

为什么以下打印两行而不是第一行?

./bower_components/index.html                                                  
./bower_components/
Run Code Online (Sandbox Code Playgroud)

输出:

=== RUN   TestRootHandler                                                      
./bower_components/index.html                                                  
./bower_components/             ???                                            
--- PASS: TestRootHandler (0.00s)                                              
        main_test.go:32: 200 - ./bower_components/Hello World.html             
PASS                                                                           
ok
Run Code Online (Sandbox Code Playgroud)

码:

// RootHandler for HTTP
func RootHandler(root string, h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        _, err := os.Open(root + r.URL.Path)
        if err != nil {
            fmt.Println(err.Error())
            h.ServeHTTP(w, r)
            return
        }
        fmt.Println(root + r.URL.Path)
        r.URL.Path = root + r.URL.Path
        h.ServeHTTP(w, r)
    })
}

// TestRootHandler
func TestRootHandler(t *testing.T) {
    ts := httptest.NewServer(RootHandler("./bower_components", http.FileServer(http.Dir("./"))))
    defer ts.Close()
    res, err := http.Get(ts.URL + "/index.html")
    if err != nil {
        t.Fatal(err)
    }
    body, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        t.Fatal(err)
    }
    t.Logf("%d - %s", res.StatusCode, body)
}
Run Code Online (Sandbox Code Playgroud)

如果您不理解这个问题,请告诉我,然后我将设置一个github存储库,这样您就可以运行go test命令来查看我的意思.

icz*_*cza 7

http.FileServer()就是写作的方式.引用其文档:

作为特殊情况,返回的文件服务器将以"/index.html"结尾的任何请求重定向到相同的路径,而不是最终的"index.html".

这就是您所经历的:您正在请求/bower_components/index.html,因此返回的处理程序http.FileServer()发送重定向:

HTTP/1.1 301 Moved Permanently
Location: ./
Run Code Online (Sandbox Code Playgroud)

并且http.Get()表现良好,遵循此重定向,并执行另一个HTTP GET,现在没有index.html,并且http.FileServer()处理程序将尝试index.html在这种情况下服务.