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

报告相同问题?

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题