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.

120 lines
2.6 KiB

6 years ago
7 years ago
7 years ago
6 years ago
6 years ago
  1. package needle
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "mime"
  7. "net/http"
  8. "path"
  9. "strconv"
  10. "strings"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. "github.com/chrislusf/seaweedfs/weed/util"
  13. )
  14. func parseMultipart(r *http.Request, sizeLimit int64) (
  15. fileName string, data []byte, mimeType string, isGzipped bool, originalDataSize int, isChunkedFile bool, e error) {
  16. defer func() {
  17. if e != nil && r.Body != nil {
  18. io.Copy(ioutil.Discard, r.Body)
  19. r.Body.Close()
  20. }
  21. }()
  22. form, fe := r.MultipartReader()
  23. if fe != nil {
  24. glog.V(0).Infoln("MultipartReader [ERROR]", fe)
  25. e = fe
  26. return
  27. }
  28. //first multi-part item
  29. part, fe := form.NextPart()
  30. if fe != nil {
  31. glog.V(0).Infoln("Reading Multi part [ERROR]", fe)
  32. e = fe
  33. return
  34. }
  35. fileName = part.FileName()
  36. if fileName != "" {
  37. fileName = path.Base(fileName)
  38. }
  39. println("reading part", sizeLimit)
  40. data, e = ioutil.ReadAll(io.LimitReader(part, sizeLimit+1))
  41. if e != nil {
  42. glog.V(0).Infoln("Reading Content [ERROR]", e)
  43. return
  44. }
  45. if len(data) == int(sizeLimit)+1 {
  46. e = fmt.Errorf("file over the limited %d bytes", sizeLimit)
  47. return
  48. }
  49. //if the filename is empty string, do a search on the other multi-part items
  50. for fileName == "" {
  51. part2, fe := form.NextPart()
  52. if fe != nil {
  53. break // no more or on error, just safely break
  54. }
  55. fName := part2.FileName()
  56. //found the first <file type> multi-part has filename
  57. if fName != "" {
  58. data2, fe2 := ioutil.ReadAll(io.LimitReader(part2, sizeLimit+1))
  59. if fe2 != nil {
  60. glog.V(0).Infoln("Reading Content [ERROR]", fe2)
  61. e = fe2
  62. return
  63. }
  64. if len(data) == int(sizeLimit)+1 {
  65. e = fmt.Errorf("file over the limited %d bytes", sizeLimit)
  66. return
  67. }
  68. //update
  69. data = data2
  70. fileName = path.Base(fName)
  71. break
  72. }
  73. }
  74. originalDataSize = len(data)
  75. isChunkedFile, _ = strconv.ParseBool(r.FormValue("cm"))
  76. if !isChunkedFile {
  77. dotIndex := strings.LastIndex(fileName, ".")
  78. ext, mtype := "", ""
  79. if dotIndex > 0 {
  80. ext = strings.ToLower(fileName[dotIndex:])
  81. mtype = mime.TypeByExtension(ext)
  82. }
  83. contentType := part.Header.Get("Content-Type")
  84. if contentType != "" && mtype != contentType {
  85. mimeType = contentType //only return mime type if not deductable
  86. mtype = contentType
  87. }
  88. if part.Header.Get("Content-Encoding") == "gzip" {
  89. if unzipped, e := util.UnGzipData(data); e == nil {
  90. originalDataSize = len(unzipped)
  91. }
  92. isGzipped = true
  93. } else if util.IsGzippable(ext, mtype, data) {
  94. if compressedData, err := util.GzipData(data); err == nil {
  95. if len(data) > len(compressedData) {
  96. data = compressedData
  97. isGzipped = true
  98. }
  99. }
  100. }
  101. }
  102. return
  103. }