example_filesystem_test.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package http_test
  5. import (
  6. "io/fs"
  7. "log"
  8. "net/http"
  9. "strings"
  10. )
  11. // containsDotFile reports whether name contains a path element starting with a period.
  12. // The name is assumed to be a delimited by forward slashes, as guaranteed
  13. // by the http.FileSystem interface.
  14. func containsDotFile(name string) bool {
  15. parts := strings.Split(name, "/")
  16. for _, part := range parts {
  17. if strings.HasPrefix(part, ".") {
  18. return true
  19. }
  20. }
  21. return false
  22. }
  23. // dotFileHidingFile is the http.File use in dotFileHidingFileSystem.
  24. // It is used to wrap the Readdir method of http.File so that we can
  25. // remove files and directories that start with a period from its output.
  26. type dotFileHidingFile struct {
  27. http.File
  28. }
  29. // Readdir is a wrapper around the Readdir method of the embedded File
  30. // that filters out all files that start with a period in their name.
  31. func (f dotFileHidingFile) Readdir(n int) (fis []fs.FileInfo, err error) {
  32. files, err := f.File.Readdir(n)
  33. for _, file := range files { // Filters out the dot files
  34. if !strings.HasPrefix(file.Name(), ".") {
  35. fis = append(fis, file)
  36. }
  37. }
  38. return
  39. }
  40. // dotFileHidingFileSystem is an http.FileSystem that hides
  41. // hidden "dot files" from being served.
  42. type dotFileHidingFileSystem struct {
  43. http.FileSystem
  44. }
  45. // Open is a wrapper around the Open method of the embedded FileSystem
  46. // that serves a 403 permission error when name has a file or directory
  47. // with whose name starts with a period in its path.
  48. func (fsys dotFileHidingFileSystem) Open(name string) (http.File, error) {
  49. if containsDotFile(name) { // If dot file, return 403 response
  50. return nil, fs.ErrPermission
  51. }
  52. file, err := fsys.FileSystem.Open(name)
  53. if err != nil {
  54. return nil, err
  55. }
  56. return dotFileHidingFile{file}, err
  57. }
  58. func ExampleFileServer_dotFileHiding() {
  59. fsys := dotFileHidingFileSystem{http.Dir(".")}
  60. http.Handle("/", http.FileServer(fsys))
  61. log.Fatal(http.ListenAndServe(":8080", nil))
  62. }