StaticDirectoryHandler creates handler function to serve files from provided file system When disablePathUnescaping is set then file name from path is not unescaped and is served as is. Note: when disablePathUnescaping=false, the handler decodes the wildcard param before serving. If route guards (e
(fileSystem fs.FS, disablePathUnescaping bool)
| 625 | // Do not rely on route guards alone to restrict a filesystem served by this handler. |
| 626 | // See https://github.com/labstack/echo/security/advisories/GHSA-vfp3-v2gw-7wfq |
| 627 | func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc { |
| 628 | return func(c *Context) error { |
| 629 | p := c.Param("*") |
| 630 | if !disablePathUnescaping { // when router is already unescaping we do not want to do is twice |
| 631 | tmpPath, err := url.PathUnescape(p) |
| 632 | if err != nil { |
| 633 | return fmt.Errorf("failed to unescape path variable: %w", err) |
| 634 | } |
| 635 | p = tmpPath |
| 636 | } |
| 637 | |
| 638 | // fs.FS.Open() already assumes that file names are relative to FS root path and considers name with prefix `/` |
| 639 | // as invalid |
| 640 | // Use path.Clean (not filepath.Clean): fs.FS paths are always forward-slash, so a backslash must stay a literal |
| 641 | // character rather than being interpreted as a separator on Windows (which would resolve a file across a boundary |
| 642 | // the router never matched on, the same Windows backslash traversal class as GHSA-pgvm-wxw2-hrv9). |
| 643 | name := path.Clean(strings.TrimPrefix(p, "/")) |
| 644 | fi, err := fs.Stat(fileSystem, name) |
| 645 | if err != nil { |
| 646 | return ErrNotFound |
| 647 | } |
| 648 | |
| 649 | // If the request is for a directory and does not end with "/" redirect to path which ends with "/" |
| 650 | p = c.Request().URL.Path |
| 651 | if fi.IsDir() && len(p) > 0 && p[len(p)-1] != '/' { |
| 652 | return c.Redirect(http.StatusMovedPermanently, sanitizeURI(p+"/")) |
| 653 | } |
| 654 | return fsFile(c, name, fileSystem) |
| 655 | } |
| 656 | } |
| 657 | |
| 658 | // FileFS registers a new route with path to serve file from the provided file system. |
| 659 | // |
no test coverage detected
searching dependent graphs…