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.

196 lines
4.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package cos
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "crypto/sha1"
  6. "errors"
  7. "fmt"
  8. "hash/crc64"
  9. "io"
  10. "net/http"
  11. "net/url"
  12. "os"
  13. "strings"
  14. )
  15. // 单次上传文件最大为5GB
  16. const singleUploadMaxLength = 5 * 1024 * 1024 * 1024
  17. // 计算 md5 或 sha1 时的分块大小
  18. const calDigestBlockSize = 1024 * 1024 * 10
  19. func calMD5Digest(msg []byte) []byte {
  20. // TODO: 分块计算,减少内存消耗
  21. m := md5.New()
  22. m.Write(msg)
  23. return m.Sum(nil)
  24. }
  25. func calSHA1Digest(msg []byte) []byte {
  26. // TODO: 分块计算,减少内存消耗
  27. m := sha1.New()
  28. m.Write(msg)
  29. return m.Sum(nil)
  30. }
  31. func calCRC64(fd io.Reader) (uint64, error) {
  32. tb := crc64.MakeTable(crc64.ECMA)
  33. hash := crc64.New(tb)
  34. _, err := io.Copy(hash, fd)
  35. if err != nil {
  36. return 0, err
  37. }
  38. sum := hash.Sum64()
  39. return sum, nil
  40. }
  41. // cloneRequest returns a clone of the provided *http.Request. The clone is a
  42. // shallow copy of the struct and its Header map.
  43. func cloneRequest(r *http.Request) *http.Request {
  44. // shallow copy of the struct
  45. r2 := new(http.Request)
  46. *r2 = *r
  47. // deep copy of the Header
  48. r2.Header = make(http.Header, len(r.Header))
  49. for k, s := range r.Header {
  50. r2.Header[k] = append([]string(nil), s...)
  51. }
  52. return r2
  53. }
  54. // encodeURIComponent like same function in javascript
  55. //
  56. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
  57. //
  58. // http://www.ecma-international.org/ecma-262/6.0/#sec-uri-syntax-and-semantics
  59. func encodeURIComponent(s string, excluded ...[]byte) string {
  60. var b bytes.Buffer
  61. written := 0
  62. for i, n := 0, len(s); i < n; i++ {
  63. c := s[i]
  64. switch c {
  65. case '-', '_', '.', '!', '~', '*', '\'', '(', ')':
  66. continue
  67. default:
  68. // Unreserved according to RFC 3986 sec 2.3
  69. if 'a' <= c && c <= 'z' {
  70. continue
  71. }
  72. if 'A' <= c && c <= 'Z' {
  73. continue
  74. }
  75. if '0' <= c && c <= '9' {
  76. continue
  77. }
  78. if len(excluded) > 0 {
  79. conti := false
  80. for _, ch := range excluded[0] {
  81. if ch == c {
  82. conti = true
  83. break
  84. }
  85. }
  86. if conti {
  87. continue
  88. }
  89. }
  90. }
  91. b.WriteString(s[written:i])
  92. fmt.Fprintf(&b, "%%%02X", c)
  93. written = i + 1
  94. }
  95. if written == 0 {
  96. return s
  97. }
  98. b.WriteString(s[written:])
  99. return b.String()
  100. }
  101. func decodeURIComponent(s string) (string, error) {
  102. decodeStr, err := url.QueryUnescape(s)
  103. if err != nil {
  104. return s, err
  105. }
  106. return decodeStr, err
  107. }
  108. func DecodeURIComponent(s string) (string, error) {
  109. return decodeURIComponent(s)
  110. }
  111. func EncodeURIComponent(s string) string {
  112. return encodeURIComponent(s)
  113. }
  114. func GetReaderLen(reader io.Reader) (length int64, err error) {
  115. switch v := reader.(type) {
  116. case *bytes.Buffer:
  117. length = int64(v.Len())
  118. case *bytes.Reader:
  119. length = int64(v.Len())
  120. case *strings.Reader:
  121. length = int64(v.Len())
  122. case *os.File:
  123. stat, ferr := v.Stat()
  124. if ferr != nil {
  125. err = fmt.Errorf("can't get reader length: %s", ferr.Error())
  126. } else {
  127. length = stat.Size()
  128. }
  129. case *io.LimitedReader:
  130. length = int64(v.N)
  131. case FixedLengthReader:
  132. length = v.Size()
  133. default:
  134. err = fmt.Errorf("can't get reader content length, unkown reader type")
  135. }
  136. return
  137. }
  138. func CheckReaderLen(reader io.Reader) error {
  139. nlen, err := GetReaderLen(reader)
  140. if err != nil || nlen < singleUploadMaxLength {
  141. return nil
  142. }
  143. return errors.New("The single object size you upload can not be larger than 5GB")
  144. }
  145. func CopyOptionsToMulti(opt *ObjectCopyOptions) *InitiateMultipartUploadOptions {
  146. if opt == nil {
  147. return nil
  148. }
  149. optini := &InitiateMultipartUploadOptions{
  150. opt.ACLHeaderOptions,
  151. &ObjectPutHeaderOptions{},
  152. }
  153. if opt.ObjectCopyHeaderOptions == nil {
  154. return optini
  155. }
  156. optini.ObjectPutHeaderOptions = &ObjectPutHeaderOptions{
  157. CacheControl: opt.ObjectCopyHeaderOptions.CacheControl,
  158. ContentDisposition: opt.ObjectCopyHeaderOptions.ContentDisposition,
  159. ContentEncoding: opt.ObjectCopyHeaderOptions.ContentEncoding,
  160. ContentType: opt.ObjectCopyHeaderOptions.ContentType,
  161. ContentLanguage: opt.ObjectCopyHeaderOptions.ContentLanguage,
  162. Expect: opt.ObjectCopyHeaderOptions.Expect,
  163. Expires: opt.ObjectCopyHeaderOptions.Expires,
  164. XCosMetaXXX: opt.ObjectCopyHeaderOptions.XCosMetaXXX,
  165. XCosStorageClass: opt.ObjectCopyHeaderOptions.XCosStorageClass,
  166. XCosServerSideEncryption: opt.ObjectCopyHeaderOptions.XCosServerSideEncryption,
  167. XCosSSECustomerAglo: opt.ObjectCopyHeaderOptions.XCosSSECustomerAglo,
  168. XCosSSECustomerKey: opt.ObjectCopyHeaderOptions.XCosSSECustomerKey,
  169. XCosSSECustomerKeyMD5: opt.ObjectCopyHeaderOptions.XCosSSECustomerKeyMD5,
  170. XOptionHeader: opt.ObjectCopyHeaderOptions.XOptionHeader,
  171. }
  172. return optini
  173. }