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.

239 lines
5.5 KiB

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