From 84845a66ab3953351f2dccc8ed00cd491f7f52f6 Mon Sep 17 00:00:00 2001 From: Abiola Ibrahim Date: Fri, 11 Mar 2016 23:11:21 +0100 Subject: [PATCH] Fix broken build. --- middleware/fileserver.go | 42 +++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/middleware/fileserver.go b/middleware/fileserver.go index 9c15900e..4b3cab02 100644 --- a/middleware/fileserver.go +++ b/middleware/fileserver.go @@ -44,12 +44,19 @@ func (fh *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, e upath = "/" + upath r.URL.Path = upath } - return fh.serveFile(w, r, filepath.Clean(upath)) + return fh.serveFile(w, r, path.Clean(upath)) } // serveFile writes the specified file to the HTTP response. // name is '/'-separated, not filepath.Separator. func (fh *fileHandler) serveFile(w http.ResponseWriter, r *http.Request, name string) (int, error) { + // Prevent absolute path access on Windows. + // TODO remove when stdlib http.Dir fixes this. + if runtimeGoos == "windows" { + if filepath.IsAbs(name[1:]) { + return http.StatusNotFound, nil + } + } f, err := fh.root.Open(name) if err != nil { if os.IsNotExist(err) { @@ -114,6 +121,28 @@ func (fh *fileHandler) serveFile(w http.ResponseWriter, r *http.Request, name st return http.StatusNotFound, nil } + // If file is on hide list. + if fh.isHidden(d.Name()) { + return http.StatusNotFound, nil + } + + // Note: Errors generated by ServeContent are written immediately + // to the response. This usually only happens if seeking fails (rare). + http.ServeContent(w, r, d.Name(), d.ModTime(), f) + + return http.StatusOK, nil +} + +// isHidden checks if file with name is on hide list. +func (fh fileHandler) isHidden(name string) bool { + // Clean up on Windows. + // Remove trailing dots and trim whitespaces. + if runtimeGoos == "windows" { + name = strings.TrimSpace(name) + for strings.HasSuffix(name, ".") { + name = name[:len(name)-1] + } + } // If the file is supposed to be hidden, return a 404 // (TODO: If the slice gets large, a set may be faster) for _, hiddenPath := range fh.hide { @@ -123,16 +152,11 @@ func (fh *fileHandler) serveFile(w http.ResponseWriter, r *http.Request, name st // TODO: This matches file NAME only, regardless of path. In other // words, trying to serve another file with the same name as the // active config file will result in a 404 when it shouldn't. - if strings.EqualFold(d.Name(), path.Base(hiddenPath)) { - return http.StatusNotFound, nil + if strings.EqualFold(name, filepath.Base(hiddenPath)) { + return true } } - - // Note: Errors generated by ServeContent are written immediately - // to the response. This usually only happens if seeking fails (rare). - http.ServeContent(w, r, d.Name(), d.ModTime(), f) - - return http.StatusOK, nil + return false } // redirect is taken from http.localRedirect of the std lib. It