static.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package tango
  2. import (
  3. "os"
  4. "path/filepath"
  5. "net/http"
  6. "strings"
  7. )
  8. type Statics struct {
  9. Prefix string
  10. RootPath string
  11. IndexFiles []string
  12. }
  13. func NewStatic(rootPath, prefix string, indexFiles []string) *Statics {
  14. return &Statics{
  15. prefix,
  16. rootPath,
  17. indexFiles,
  18. }
  19. }
  20. func (s *Statics) Handle(ctx *Context) {
  21. if ctx.Req().Method != "GET" && ctx.Req().Method != "HEAD" {
  22. ctx.Next()
  23. return
  24. }
  25. var rPath = ctx.Req().URL.Path
  26. // if defined prefix, then only check prefix
  27. if s.Prefix != "" {
  28. if !strings.HasPrefix(ctx.Req().URL.Path, "/"+s.Prefix) {
  29. ctx.Next()
  30. return
  31. } else {
  32. if len("/"+s.Prefix) == len(ctx.Req().URL.Path) {
  33. rPath = ""
  34. } else {
  35. rPath = ctx.Req().URL.Path[len("/"+s.Prefix):]
  36. }
  37. }
  38. }
  39. fPath, _ := filepath.Abs(filepath.Join(s.RootPath, rPath))
  40. finfo, err := os.Stat(fPath)
  41. if err != nil {
  42. if !os.IsNotExist(err) {
  43. ctx.WriteHeader(http.StatusInternalServerError)
  44. ctx.Write([]byte(err.Error()))
  45. return
  46. }
  47. } else if !finfo.IsDir() {
  48. err := ctx.ServeFile(fPath)
  49. if err != nil {
  50. ctx.WriteHeader(http.StatusInternalServerError)
  51. ctx.Write([]byte(err.Error()))
  52. }
  53. return
  54. } else {
  55. // try serving index.html or index.htm
  56. if len(s.IndexFiles) > 0 {
  57. for _, index := range s.IndexFiles {
  58. nPath := filepath.Join(fPath, index)
  59. finfo, err = os.Stat(nPath)
  60. if err != nil {
  61. if !os.IsNotExist(err) {
  62. ctx.WriteHeader(http.StatusInternalServerError)
  63. ctx.Write([]byte(err.Error()))
  64. return
  65. }
  66. } else if !finfo.IsDir() {
  67. err = ctx.ServeFile(nPath)
  68. if err != nil {
  69. ctx.WriteHeader(http.StatusInternalServerError)
  70. ctx.Write([]byte(err.Error()))
  71. }
  72. return
  73. }
  74. }
  75. }
  76. }
  77. ctx.Next()
  78. }