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.

357 lines
8.1 KiB

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