douzhi3454 2016-09-18 20:42
浏览 148
已采纳

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

Create a test file ./bower_components/index.html and run go test in ./.

Why does the following print two lines instead of just the first one?

./bower_components/index.html                                                  
./bower_components/

Output:

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

Code:

// 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)
}

Let me know if you don't understand the question then I will setup a github repository so you can just run the go test command to see what I mean.

  • 写回答

1条回答 默认 最新

  • duanshang9426 2016-09-18 21:38
    关注

    That's just the way how http.FileServer() is written. Quoting from its doc:

    As a special case, the returned file server redirects any request ending in "/index.html" to the same path, without the final "index.html".

    This is what you experience: you were requesting /bower_components/index.html, so the handler returned by http.FileServer() sends a redirect:

    HTTP/1.1 301 Moved Permanently
    Location: ./
    

    And http.Get() being well-behaved, follows this redirect, and performs another HTTP GET, now without the index.html, and the http.FileServer() handler will try and serve the index.html in such case.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?