Core functionality for new aiterp.net servers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.2 KiB

  1. package wrouter
  2. import (
  3. "io"
  4. "mime"
  5. "net/http"
  6. "os"
  7. "path"
  8. "strings"
  9. "git.aiterp.net/gisle/wrouter/response"
  10. "git.aiterp.net/gisle/wrouter/auth"
  11. )
  12. type Static struct {
  13. path string
  14. }
  15. func NewStatic(path string) *Static {
  16. return &Static{path}
  17. }
  18. func (static *Static) Handle(urlPath string, w http.ResponseWriter, req *http.Request, user *auth.User) bool {
  19. // Get the subpath out of the path
  20. subpath := req.URL.Path[len(urlPath):]
  21. if subpath[0] == '/' {
  22. subpath = subpath[1:]
  23. }
  24. // Disallow breaking out of the folder
  25. if strings.Contains(subpath, "..") {
  26. response.Text(w, 403, "No .. in paths allowed")
  27. return true
  28. }
  29. // Try loading the file
  30. filepath := path.Join(static.path, subpath)
  31. info, err := os.Stat(filepath)
  32. if err != nil || info.IsDir() {
  33. return false
  34. }
  35. file, err := os.Open(filepath)
  36. if err != nil || file == nil {
  37. return false
  38. }
  39. // Find and convert extension
  40. ep := strings.LastIndex(filepath, ".")
  41. ext := ""
  42. if ep != -1 {
  43. ext = filepath[ep:]
  44. }
  45. mimeType := mime.TypeByExtension(ext)
  46. if mimeType == "" {
  47. mimeType = "text/plain"
  48. }
  49. w.Header().Set("Content-Type", mimeType)
  50. // Submit
  51. w.WriteHeader(200)
  52. io.Copy(w, file)
  53. return true
  54. }