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.

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