根据FileServer的不同之处是什么?

时间:2018-06-08 21:00:30

标签: go webserver httprequest

https://www.alexedwards.net/blog/serving-static-sites-with-go处,有一个静态文件服务器示例,用于在单个目录中提供网站:static

File: app.go
...
func main() {
  fs := http.FileServer(http.Dir("static"))
  http.Handle("/static/", http.StripPrefix("/static/", fs))

  log.Println("Listening...")
  http.ListenAndServe(":3000", nil)
}

但是,我发现我可以通过以下方式得到相同的结果。

func main() {
  fs := http.FileServer(http.Dir(".")) // root at the root directory.
  http.Handle("/static/", fs) //leave off the StripPrefix call.

  log.Println("Listening...")
  http.ListenAndServe(":3000", nil)
}

这样做是否有任何(性能或安全性)缺点?我可以看到,如果我在文件系统上的文件位置与它们所服务的URL不匹配,我必须使用StripPrefix,但在这种情况下,似乎调用{{1没必要。

编辑:我忘了提及,但我自己也对此进行过调查。在性能方面,它似乎不是一个问题,因为调用StripPrefix实际上并没有将文件加载到内存中;它只是存储了地址。在安全方面,这似乎完全相同:我尝试使用类似下面的内容进行目录遍历攻击。

FileServer

但是我对这两个版本都得到了301响应,这让我感到很惊讶。

1 个答案:

答案 0 :(得分:1)

使用http.ServeMux处理程序

时也是如此

http.ServeMux将在匹配路径

之前调用cleanPath函数

https://github.com/golang/go/blob/master/src/net/http/server.go#L2305

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
// snip
    path := cleanPath(r.URL.Path)
//snip
}  

cleanPath函数返回p的规范路径,消除。和..元素。

https://github.com/golang/go/blob/master/src/net/http/server.go#L2174-L2193

// cleanPath returns the canonical path for p, eliminating . and .. elements.

func cleanPath(p string) string {
    if p == "" {
        return "/"
    }
    if p[0] != '/' {
        p = "/" + p
    }
    np := path.Clean(p)
    // path.Clean removes trailing slash except for root;
    // put the trailing slash back if necessary.
    if p[len(p)-1] == '/' && np != "/" {
        // Fast path for common case of p being the string we want:
        if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
            np = p
        } else {
            np += "/"
        }
    }
    return np
}