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.

96 lines
2.6 KiB

10 years ago
10 years ago
10 years ago
10 years ago
12 years ago
  1. package operation
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "mime"
  10. "mime/multipart"
  11. "net/http"
  12. "net/textproto"
  13. "path/filepath"
  14. "strings"
  15. "github.com/chrislusf/seaweedfs/weed/glog"
  16. "github.com/chrislusf/seaweedfs/weed/security"
  17. )
  18. type UploadResult struct {
  19. Name string `json:"name,omitempty"`
  20. Size uint32 `json:"size,omitempty"`
  21. Error string `json:"error,omitempty"`
  22. }
  23. var (
  24. client *http.Client
  25. )
  26. func init() {
  27. client = &http.Client{Transport: &http.Transport{
  28. MaxIdleConnsPerHost: 1024,
  29. }}
  30. }
  31. var fileNameEscaper = strings.NewReplacer("\\", "\\\\", "\"", "\\\"")
  32. func Upload(uploadUrl string, filename string, reader io.Reader, isGzipped bool, mtype string, jwt security.EncodedJwt) (*UploadResult, error) {
  33. return upload_content(uploadUrl, func(w io.Writer) (err error) {
  34. _, err = io.Copy(w, reader)
  35. return
  36. }, filename, isGzipped, mtype, jwt)
  37. }
  38. func upload_content(uploadUrl string, fillBufferFunction func(w io.Writer) error, filename string, isGzipped bool, mtype string, jwt security.EncodedJwt) (*UploadResult, error) {
  39. body_buf := bytes.NewBufferString("")
  40. body_writer := multipart.NewWriter(body_buf)
  41. h := make(textproto.MIMEHeader)
  42. h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file"; filename="%s"`, fileNameEscaper.Replace(filename)))
  43. if mtype == "" {
  44. mtype = mime.TypeByExtension(strings.ToLower(filepath.Ext(filename)))
  45. }
  46. if mtype != "" {
  47. h.Set("Content-Type", mtype)
  48. }
  49. if isGzipped {
  50. h.Set("Content-Encoding", "gzip")
  51. }
  52. if jwt != "" {
  53. h.Set("Authorization", "BEARER "+string(jwt))
  54. }
  55. file_writer, cp_err := body_writer.CreatePart(h)
  56. if cp_err != nil {
  57. glog.V(0).Infoln("error creating form file", cp_err.Error())
  58. return nil, cp_err
  59. }
  60. if err := fillBufferFunction(file_writer); err != nil {
  61. glog.V(0).Infoln("error copying data", err)
  62. return nil, err
  63. }
  64. content_type := body_writer.FormDataContentType()
  65. if err := body_writer.Close(); err != nil {
  66. glog.V(0).Infoln("error closing body", err)
  67. return nil, err
  68. }
  69. resp, post_err := client.Post(uploadUrl, content_type, body_buf)
  70. if post_err != nil {
  71. glog.V(0).Infoln("failing to upload to", uploadUrl, post_err.Error())
  72. return nil, post_err
  73. }
  74. defer resp.Body.Close()
  75. resp_body, ra_err := ioutil.ReadAll(resp.Body)
  76. if ra_err != nil {
  77. return nil, ra_err
  78. }
  79. var ret UploadResult
  80. unmarshal_err := json.Unmarshal(resp_body, &ret)
  81. if unmarshal_err != nil {
  82. glog.V(0).Infoln("failing to read upload resonse", uploadUrl, string(resp_body))
  83. return nil, unmarshal_err
  84. }
  85. if ret.Error != "" {
  86. return nil, errors.New(ret.Error)
  87. }
  88. return &ret, nil
  89. }