form.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package dara
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "math/rand"
  7. "net/url"
  8. "strings"
  9. )
  10. type FileField struct {
  11. Filename *string `json:"filename" xml:"filename" require:"true"`
  12. ContentType *string `json:"content-type" xml:"content-type" require:"true"`
  13. Content io.Reader `json:"content" xml:"content" require:"true"`
  14. }
  15. func (s *FileField) SetFilename(v string) *FileField {
  16. s.Filename = &v
  17. return s
  18. }
  19. func (s *FileField) SetContentType(v string) *FileField {
  20. s.ContentType = &v
  21. return s
  22. }
  23. func (s *FileField) SetContent(v io.Reader) *FileField {
  24. s.Content = v
  25. return s
  26. }
  27. type FileFormReader struct {
  28. formFiles []*formFile
  29. formField io.Reader
  30. index int
  31. streaming bool
  32. ifField bool
  33. }
  34. type formFile struct {
  35. StartField io.Reader
  36. EndField io.Reader
  37. File io.Reader
  38. start bool
  39. end bool
  40. }
  41. const numBytes = "1234567890"
  42. func GetBoundary() string {
  43. b := make([]byte, 14)
  44. for i := range b {
  45. b[i] = numBytes[rand.Intn(len(numBytes))]
  46. }
  47. return string(b)
  48. }
  49. func ToFileForm(body map[string]interface{}, boundary string) io.Reader {
  50. out := bytes.NewBuffer(nil)
  51. line := "--" + boundary + "\r\n"
  52. forms := make(map[string]string)
  53. files := make(map[string]map[string]interface{})
  54. for key, value := range body {
  55. switch value.(type) {
  56. case *FileField:
  57. if val, ok := value.(*FileField); ok {
  58. out := make(map[string]interface{})
  59. out["filename"] = StringValue(val.Filename)
  60. out["content-type"] = StringValue(val.ContentType)
  61. out["content"] = val.Content
  62. files[key] = out
  63. }
  64. case map[string]interface{}:
  65. if val, ok := value.(map[string]interface{}); ok {
  66. files[key] = val
  67. }
  68. default:
  69. forms[key] = fmt.Sprintf("%v", value)
  70. }
  71. }
  72. for key, value := range forms {
  73. if value != "" {
  74. out.Write([]byte(line))
  75. out.Write([]byte("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n\r\n"))
  76. out.Write([]byte(value + "\r\n"))
  77. }
  78. }
  79. formFiles := make([]*formFile, 0)
  80. for key, value := range files {
  81. var file io.Reader
  82. start := line
  83. start += "Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + value["filename"].(string) + "\"\r\n"
  84. start += "Content-Type: " + value["content-type"].(string) + "\r\n\r\n"
  85. if content, ok := value["content"].(io.Reader); ok {
  86. file = content
  87. } else {
  88. file = strings.NewReader("")
  89. }
  90. formFile := &formFile{
  91. File: file,
  92. start: true,
  93. StartField: strings.NewReader(start),
  94. }
  95. if len(files) == len(formFiles)+1 {
  96. end := "\r\n\r\n--" + boundary + "--\r\n"
  97. formFile.EndField = strings.NewReader(end)
  98. } else {
  99. formFile.EndField = strings.NewReader("\r\n\r\n")
  100. }
  101. formFiles = append(formFiles, formFile)
  102. }
  103. return &FileFormReader{
  104. formFiles: formFiles,
  105. formField: out,
  106. ifField: true,
  107. }
  108. }
  109. func (f *FileFormReader) Read(p []byte) (n int, err error) {
  110. if f.ifField {
  111. n, err = f.formField.Read(p)
  112. if err != nil && err != io.EOF {
  113. return n, err
  114. } else if err == io.EOF {
  115. err = nil
  116. f.ifField = false
  117. f.streaming = true
  118. }
  119. } else if f.streaming {
  120. form := f.formFiles[f.index]
  121. if form.start {
  122. n, err = form.StartField.Read(p)
  123. if err != nil && err != io.EOF {
  124. return n, err
  125. } else if err == io.EOF {
  126. err = nil
  127. form.start = false
  128. }
  129. } else if form.end {
  130. n, err = form.EndField.Read(p)
  131. if err != nil && err != io.EOF {
  132. return n, err
  133. } else if err == io.EOF {
  134. f.index++
  135. form.end = false
  136. if f.index < len(f.formFiles) {
  137. err = nil
  138. }
  139. }
  140. } else {
  141. n, err = form.File.Read(p)
  142. if err != nil && err != io.EOF {
  143. return n, err
  144. } else if err == io.EOF {
  145. err = nil
  146. form.end = true
  147. }
  148. }
  149. }
  150. return n, err
  151. }
  152. func ToFormString(a map[string]interface{}) string {
  153. if a == nil {
  154. return ""
  155. }
  156. res := ""
  157. urlEncoder := url.Values{}
  158. for key, value := range a {
  159. v := fmt.Sprintf("%v", value)
  160. urlEncoder.Add(key, v)
  161. }
  162. res = urlEncoder.Encode()
  163. return res
  164. }