(c *Context, file string, filesystem fs.FS)
| 672 | } |
| 673 | |
| 674 | func fsFile(c *Context, file string, filesystem fs.FS) error { |
| 675 | file = path.Clean(file) // `os.Open` and `os.DirFs.Open()` behave differently, later does not like ``, `.`, `..` at all, but we allowed those now need to clean |
| 676 | f, err := filesystem.Open(file) |
| 677 | if err != nil { |
| 678 | return ErrNotFound |
| 679 | } |
| 680 | defer f.Close() |
| 681 | |
| 682 | fi, _ := f.Stat() |
| 683 | if fi.IsDir() { |
| 684 | file = filepath.ToSlash(filepath.Join(file, indexPage)) // ToSlash is necessary for Windows. fs.Open and os.Open are different in that aspect. |
| 685 | f, err = filesystem.Open(file) |
| 686 | if err != nil { |
| 687 | return ErrNotFound |
| 688 | } |
| 689 | defer f.Close() |
| 690 | if fi, err = f.Stat(); err != nil { |
| 691 | return err |
| 692 | } |
| 693 | } |
| 694 | ff, ok := f.(io.ReadSeeker) |
| 695 | if !ok { |
| 696 | return errors.New("file does not implement io.ReadSeeker") |
| 697 | } |
| 698 | http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), ff) |
| 699 | return nil |
| 700 | } |
| 701 | |
| 702 | // Attachment sends a response as attachment, prompting client to save the file. |
| 703 | // |
no test coverage detected
searching dependent graphs…