view_view_image_file.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package route
  2. import (
  3. "net/http"
  4. "opennamu/route/tool"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "regexp"
  9. "strings"
  10. "github.com/gin-gonic/gin"
  11. )
  12. func View_view_image_file(c *gin.Context) {
  13. db := tool.DB_connect()
  14. defer tool.DB_close(db)
  15. c.Header("X-Content-Type-Options", "nosniff")
  16. raw_path := strings.TrimPrefix(c.Param("name"), "/")
  17. if raw_path == "" {
  18. c.String(http.StatusOK, "")
  19. return
  20. }
  21. raw_path = strings.ReplaceAll(raw_path, "\\", "/")
  22. file_name := path.Base(raw_path)
  23. if file_name == "." || file_name == "/" || strings.ContainsAny(file_name, `/\`) {
  24. c.String(http.StatusBadRequest, "")
  25. return
  26. }
  27. re_cache := regexp.MustCompile(`\.cache_v[0-9]+$`)
  28. file_name = re_cache.ReplaceAllString(file_name, "")
  29. parts := strings.Split(file_name, ".")
  30. mime_type := "application/octet-stream"
  31. if len(parts) >= 2 {
  32. ext := strings.ToLower(parts[len(parts) - 1])
  33. switch ext {
  34. // Images
  35. case "jpeg", "jpg":
  36. mime_type = "image/jpeg"
  37. case "png":
  38. mime_type = "image/png"
  39. case "gif":
  40. mime_type = "image/gif"
  41. case "webp":
  42. mime_type = "image/webp"
  43. case "bmp":
  44. mime_type = "image/bmp"
  45. case "tif", "tiff":
  46. mime_type = "image/tiff"
  47. case "ico":
  48. mime_type = "image/x-icon"
  49. case "svg":
  50. mime_type = "image/svg+xml"
  51. case "avif":
  52. mime_type = "image/avif"
  53. case "heic":
  54. mime_type = "image/heic"
  55. // Video
  56. case "mp4", "m4v":
  57. mime_type = "video/mp4"
  58. case "webm":
  59. mime_type = "video/webm"
  60. case "mkv":
  61. mime_type = "video/x-matroska"
  62. case "mov":
  63. mime_type = "video/quicktime"
  64. case "avi":
  65. mime_type = "video/x-msvideo"
  66. case "mpeg", "mpg":
  67. mime_type = "video/mpeg"
  68. case "ts":
  69. mime_type = "video/mp2t"
  70. case "3gp":
  71. mime_type = "video/3gpp"
  72. case "3g2":
  73. mime_type = "video/3gpp2"
  74. // Audio
  75. case "mp3":
  76. mime_type = "audio/mpeg"
  77. case "wav":
  78. mime_type = "audio/wav"
  79. case "flac":
  80. mime_type = "audio/flac"
  81. case "aac":
  82. mime_type = "audio/aac"
  83. case "m4a":
  84. mime_type = "audio/mp4"
  85. case "ogg", "oga":
  86. mime_type = "audio/ogg"
  87. case "opus":
  88. mime_type = "audio/opus"
  89. case "amr":
  90. mime_type = "audio/amr"
  91. case "weba":
  92. mime_type = "audio/webm"
  93. // Docs / text / code
  94. case "txt":
  95. mime_type = "text/plain; charset=utf-8"
  96. case "html", "htm":
  97. mime_type = "text/html; charset=utf-8"
  98. case "css":
  99. mime_type = "text/css; charset=utf-8"
  100. case "csv":
  101. mime_type = "text/csv; charset=utf-8"
  102. case "tsv":
  103. mime_type = "text/tab-separated-values; charset=utf-8"
  104. case "js":
  105. mime_type = "application/javascript; charset=utf-8"
  106. case "json":
  107. mime_type = "application/json"
  108. case "xml":
  109. mime_type = "application/xml"
  110. case "pdf":
  111. mime_type = "application/pdf"
  112. case "wasm":
  113. mime_type = "application/wasm"
  114. // Fonts
  115. case "woff":
  116. mime_type = "font/woff"
  117. case "woff2":
  118. mime_type = "font/woff2"
  119. case "ttf":
  120. mime_type = "font/ttf"
  121. case "otf":
  122. mime_type = "font/otf"
  123. case "eot":
  124. mime_type = "application/vnd.ms-fontobject"
  125. // Archives / binaries
  126. case "zip":
  127. mime_type = "application/zip"
  128. case "7z":
  129. mime_type = "application/x-7z-compressed"
  130. case "rar":
  131. mime_type = "application/vnd.rar"
  132. case "tar":
  133. mime_type = "application/x-tar"
  134. case "gz":
  135. mime_type = "application/gzip"
  136. case "bz2":
  137. mime_type = "application/x-bzip2"
  138. case "xz":
  139. mime_type = "application/x-xz"
  140. case "zst":
  141. mime_type = "application/zstd"
  142. }
  143. }
  144. final_path := filepath.Join(tool.Get_file_main_dir(db), file_name)
  145. if _, err := os.Stat(final_path); err != nil {
  146. if os.IsNotExist(err) {
  147. c.String(http.StatusNotFound, "")
  148. return
  149. }
  150. c.String(http.StatusInternalServerError, "read error")
  151. return
  152. }
  153. if strings.HasPrefix(mime_type, "text/") || mime_type == "application/javascript" || strings.HasPrefix(mime_type, "application/xml") {
  154. c.Header("Content-Type", mime_type+"; charset=utf-8")
  155. } else {
  156. c.Header("Content-Type", mime_type)
  157. }
  158. c.File(final_path)
  159. }