douxie1957 2018-06-08 21:00
浏览 61
已采纳

根目录FileServer的位置是否有所不同?

At https://www.alexedwards.net/blog/serving-static-sites-with-go, there's an example of a static file server serving sites in a single directory: 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)
}

However, I've found that I can get the same results with the following.

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

Are there any (performanace or security) downsides to doing it this way? I can see that I'd have to use StripPrefix if my location of the files on the filesystem did not match the URL they were served at, but in this case it seems as though the call to StripPrefix is unnecessary.

Edit: I forgot to mention, but I've had a look into this myself. Performance-wise, it doesn't seem to be a problem, since the call to FileServer doesn't actually load the files into memory; it just stores away the address. Security-wise, this seems to be exactly the same: I attempted a directory-traversal attack using something like the following.

$ curl -i --path-as-is 'http://localhost:3000/static/../sensitive.txt'

but I got a 301 response with both versions, which surprised me a little bit.

  • 写回答

1条回答 默认 最新

  • douhuang1852 2018-06-09 04:39
    关注

    It's same when you use http.ServeMux handler

    http.ServeMux will call cleanPath function before match path

    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 function return the canonical path for p, eliminating . and .. elements.

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决,来真人,不要ai!
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法