Contains the Concourse pipeline definition for building a line-server container
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.

184 lines
4.2 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package main
  2. import (
  3. "archive/tar"
  4. "archive/zip"
  5. "compress/bzip2"
  6. "compress/gzip"
  7. "encoding/json"
  8. "io"
  9. "io/ioutil"
  10. "net/http"
  11. "os"
  12. "path"
  13. "path/filepath"
  14. "sort"
  15. "strconv"
  16. "strings"
  17. "time"
  18. "bitbucket.org/taruti/mimemagic"
  19. "github.com/dustin/go-humanize"
  20. "github.com/flosch/pongo2"
  21. "github.com/microcosm-cc/bluemonday"
  22. "github.com/russross/blackfriday"
  23. "github.com/zenazn/goji/web"
  24. )
  25. const maxDisplayFileSizeBytes = 1024 * 512
  26. func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
  27. fileName := c.URLParams["name"]
  28. filePath := path.Join(Config.filesDir, fileName)
  29. fileInfo, err := os.Stat(filePath)
  30. if !fileExistsAndNotExpired(fileName) {
  31. notFoundHandler(c, w, r)
  32. return
  33. }
  34. expiry, _ := metadataGetExpiry(fileName)
  35. var expiryHuman string
  36. if expiry != neverExpire {
  37. expiryHuman = humanize.RelTime(time.Now(), expiry, "", "")
  38. }
  39. sizeHuman := humanize.Bytes(uint64(fileInfo.Size()))
  40. extra := make(map[string]string)
  41. files := []string{}
  42. file, _ := os.Open(filePath)
  43. defer file.Close()
  44. header := make([]byte, 512)
  45. file.Read(header)
  46. mimetype := mimemagic.Match("", header)
  47. extension := strings.TrimPrefix(filepath.Ext(fileName), ".")
  48. if strings.EqualFold("application/json", r.Header.Get("Accept")) {
  49. js, _ := json.Marshal(map[string]string{
  50. "filename": fileName,
  51. "mimetype": mimetype,
  52. "expiry": strconv.FormatInt(expiry.Unix(), 10),
  53. "size": strconv.FormatInt(fileInfo.Size(), 10),
  54. })
  55. w.Write(js)
  56. return
  57. }
  58. var tpl *pongo2.Template
  59. if strings.HasPrefix(mimetype, "image/") {
  60. tpl = Templates["display/image.html"]
  61. } else if strings.HasPrefix(mimetype, "video/") {
  62. tpl = Templates["display/video.html"]
  63. } else if strings.HasPrefix(mimetype, "audio/") {
  64. tpl = Templates["display/audio.html"]
  65. } else if mimetype == "application/pdf" {
  66. tpl = Templates["display/pdf.html"]
  67. } else if mimetype == "application/x-tar" {
  68. f, _ := os.Open(filePath)
  69. defer f.Close()
  70. tReadr := tar.NewReader(f)
  71. for {
  72. header, err := tReadr.Next()
  73. if err == io.EOF || err != nil {
  74. break
  75. }
  76. if header.Typeflag == tar.TypeDir || header.Typeflag == tar.TypeReg {
  77. files = append(files, header.Name)
  78. }
  79. }
  80. sort.Strings(files)
  81. } else if mimetype == "application/x-gzip" {
  82. f, _ := os.Open(filePath)
  83. defer f.Close()
  84. gzf, err := gzip.NewReader(f)
  85. if err == nil {
  86. tReadr := tar.NewReader(gzf)
  87. for {
  88. header, err := tReadr.Next()
  89. if err == io.EOF || err != nil {
  90. break
  91. }
  92. if header.Typeflag == tar.TypeDir || header.Typeflag == tar.TypeReg {
  93. files = append(files, header.Name)
  94. }
  95. }
  96. sort.Strings(files)
  97. }
  98. } else if mimetype == "application/x-bzip" {
  99. f, _ := os.Open(filePath)
  100. defer f.Close()
  101. bzf := bzip2.NewReader(f)
  102. tReadr := tar.NewReader(bzf)
  103. for {
  104. header, err := tReadr.Next()
  105. if err == io.EOF || err != nil {
  106. break
  107. }
  108. if header.Typeflag == tar.TypeDir || header.Typeflag == tar.TypeReg {
  109. files = append(files, header.Name)
  110. }
  111. }
  112. sort.Strings(files)
  113. } else if mimetype == "application/zip" {
  114. f, _ := os.Open(filePath)
  115. defer f.Close()
  116. zf, err := zip.NewReader(f, fileInfo.Size())
  117. if err == nil {
  118. for _, f := range zf.File {
  119. files = append(files, f.Name)
  120. }
  121. }
  122. } else if supportedBinExtension(extension) {
  123. if fileInfo.Size() < maxDisplayFileSizeBytes {
  124. bytes, err := ioutil.ReadFile(filePath)
  125. if err == nil {
  126. extra["extension"] = extension
  127. extra["lang_hl"], extra["lang_ace"] = extensionToHlAndAceLangs(extension)
  128. extra["contents"] = string(bytes)
  129. tpl = Templates["display/bin.html"]
  130. }
  131. }
  132. } else if extension == "md" {
  133. if fileInfo.Size() < maxDisplayFileSizeBytes {
  134. bytes, err := ioutil.ReadFile(filePath)
  135. if err == nil {
  136. unsafe := blackfriday.MarkdownCommon(bytes)
  137. html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
  138. extra["contents"] = string(html)
  139. tpl = Templates["display/md.html"]
  140. }
  141. }
  142. }
  143. // Catch other files
  144. if tpl == nil {
  145. tpl = Templates["display/file.html"]
  146. }
  147. err = tpl.ExecuteWriter(pongo2.Context{
  148. "mime": mimetype,
  149. "filename": fileName,
  150. "size": sizeHuman,
  151. "expiry": expiryHuman,
  152. "extra": extra,
  153. "files": files,
  154. }, w)
  155. if err != nil {
  156. oopsHandler(c, w, r, RespHTML, "")
  157. }
  158. }