upload.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package service
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/md5"
  6. "fmt"
  7. "io"
  8. "mime/multipart"
  9. "net/http"
  10. "net/url"
  11. "os"
  12. "sort"
  13. "strconv"
  14. "strings"
  15. "time"
  16. "go-common/library/ecode"
  17. "go-common/library/log"
  18. )
  19. // Upload add mids file.
  20. func (s *Service) Upload(c context.Context, dir, path string, data []byte) (err error) {
  21. if _, err = os.Stat(dir); err != nil {
  22. if !os.IsNotExist(err) {
  23. log.Error("os.IsNotExist(%s) error(%v)", dir, err)
  24. return
  25. }
  26. if err = os.MkdirAll(dir, 0777); err != nil {
  27. log.Error("os.MkdirAll(%s) error(%v)", dir, err)
  28. return
  29. }
  30. }
  31. f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
  32. if err != nil {
  33. log.Error("s.Upload(%s) error(%v)", path, err)
  34. return
  35. }
  36. defer f.Close()
  37. if _, err = f.Write(data); err != nil {
  38. log.Error("f.Write() error(%v)", err)
  39. }
  40. return
  41. }
  42. // Upimg upload image
  43. func (s *Service) Upimg(ctx context.Context, file multipart.File, header *multipart.FileHeader) (url string, err error) {
  44. buf := new(bytes.Buffer)
  45. w := multipart.NewWriter(buf)
  46. dest, err := w.CreateFormFile("file", header.Filename)
  47. if err != nil {
  48. log.Error("Upimg CreateFormFile error(%v)", err)
  49. return
  50. }
  51. if _, err = io.Copy(dest, file); err != nil {
  52. log.Error("Upimg Copy error(%v)", err)
  53. return
  54. }
  55. w.Close()
  56. query := map[string]string{
  57. "ts": strconv.FormatInt(time.Now().Unix(), 10),
  58. "appkey": s.c.HTTPClient.App.Key,
  59. }
  60. query["sign"] = sign(query, s.c.HTTPClient.App.Secret)
  61. u := fmt.Sprintf("%s?ts=%s&appkey=%s&sign=%s", s.c.Cfg.UpimgURL, query["ts"], query["appkey"], query["sign"])
  62. req, err := http.NewRequest(http.MethodPost, u, buf)
  63. if err != nil {
  64. log.Error("http.NewRequest(%s) error(%v)", u, err)
  65. return
  66. }
  67. req.Header.Set("Content-Type", w.FormDataContentType())
  68. res := &struct {
  69. Code int `json:"code"`
  70. Message string `json:"message"`
  71. Data struct {
  72. URL string `json:"url"`
  73. } `json:"data"`
  74. }{}
  75. if err = s.httpClient.Do(context.TODO(), req, &res); err != nil {
  76. log.Error("httpClient.Do() error(%v)", err)
  77. return
  78. }
  79. if !ecode.Int(res.Code).Equal(ecode.OK) {
  80. log.Error("upimg error code(%d)", res.Code)
  81. err = ecode.Int(res.Code)
  82. return
  83. }
  84. url = strings.Replace(res.Data.URL, "http://", "https://", 1)
  85. return
  86. }
  87. func sign(params map[string]string, secret string) string {
  88. var keys []string
  89. for k := range params {
  90. keys = append(keys, k)
  91. }
  92. sort.Strings(keys)
  93. buf := bytes.Buffer{}
  94. for _, k := range keys {
  95. if buf.Len() > 0 {
  96. buf.WriteByte('&')
  97. }
  98. buf.WriteString(url.QueryEscape(k) + "=")
  99. buf.WriteString(url.QueryEscape(params[k]))
  100. }
  101. h := md5.New()
  102. io.WriteString(h, buf.String()+secret)
  103. return fmt.Sprintf("%x", h.Sum(nil))
  104. }