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.

387 lines
9.0 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
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 cloneHeader(opt *http.Header) *http.Header {
  164. if opt == nil {
  165. return nil
  166. }
  167. h := make(http.Header, len(*opt))
  168. for k, vv := range *opt {
  169. vv2 := make([]string, len(vv))
  170. copy(vv2, vv)
  171. h[k] = vv2
  172. }
  173. return &h
  174. }
  175. func CopyOptionsToMulti(opt *ObjectCopyOptions) *InitiateMultipartUploadOptions {
  176. if opt == nil {
  177. return nil
  178. }
  179. optini := &InitiateMultipartUploadOptions{
  180. opt.ACLHeaderOptions,
  181. &ObjectPutHeaderOptions{},
  182. }
  183. if opt.ObjectCopyHeaderOptions == nil {
  184. return optini
  185. }
  186. optini.ObjectPutHeaderOptions = &ObjectPutHeaderOptions{
  187. CacheControl: opt.ObjectCopyHeaderOptions.CacheControl,
  188. ContentDisposition: opt.ObjectCopyHeaderOptions.ContentDisposition,
  189. ContentEncoding: opt.ObjectCopyHeaderOptions.ContentEncoding,
  190. ContentType: opt.ObjectCopyHeaderOptions.ContentType,
  191. ContentLanguage: opt.ObjectCopyHeaderOptions.ContentLanguage,
  192. Expect: opt.ObjectCopyHeaderOptions.Expect,
  193. Expires: opt.ObjectCopyHeaderOptions.Expires,
  194. XCosMetaXXX: opt.ObjectCopyHeaderOptions.XCosMetaXXX,
  195. XCosStorageClass: opt.ObjectCopyHeaderOptions.XCosStorageClass,
  196. XCosServerSideEncryption: opt.ObjectCopyHeaderOptions.XCosServerSideEncryption,
  197. XCosSSECustomerAglo: opt.ObjectCopyHeaderOptions.XCosSSECustomerAglo,
  198. XCosSSECustomerKey: opt.ObjectCopyHeaderOptions.XCosSSECustomerKey,
  199. XCosSSECustomerKeyMD5: opt.ObjectCopyHeaderOptions.XCosSSECustomerKeyMD5,
  200. XOptionHeader: opt.ObjectCopyHeaderOptions.XOptionHeader,
  201. }
  202. return optini
  203. }
  204. func CloneObjectPutOptions(opt *ObjectPutOptions) *ObjectPutOptions {
  205. res := &ObjectPutOptions{
  206. &ACLHeaderOptions{},
  207. &ObjectPutHeaderOptions{},
  208. }
  209. if opt != nil {
  210. if opt.ACLHeaderOptions != nil {
  211. *res.ACLHeaderOptions = *opt.ACLHeaderOptions
  212. }
  213. if opt.ObjectPutHeaderOptions != nil {
  214. *res.ObjectPutHeaderOptions = *opt.ObjectPutHeaderOptions
  215. res.XCosMetaXXX = cloneHeader(opt.XCosMetaXXX)
  216. res.XOptionHeader = cloneHeader(opt.XOptionHeader)
  217. }
  218. }
  219. return res
  220. }
  221. func CloneInitiateMultipartUploadOptions(opt *InitiateMultipartUploadOptions) *InitiateMultipartUploadOptions {
  222. res := &InitiateMultipartUploadOptions{
  223. &ACLHeaderOptions{},
  224. &ObjectPutHeaderOptions{},
  225. }
  226. if opt != nil {
  227. if opt.ACLHeaderOptions != nil {
  228. *res.ACLHeaderOptions = *opt.ACLHeaderOptions
  229. }
  230. if opt.ObjectPutHeaderOptions != nil {
  231. *res.ObjectPutHeaderOptions = *opt.ObjectPutHeaderOptions
  232. res.XCosMetaXXX = cloneHeader(opt.XCosMetaXXX)
  233. res.XOptionHeader = cloneHeader(opt.XOptionHeader)
  234. }
  235. }
  236. return res
  237. }
  238. func CloneObjectUploadPartOptions(opt *ObjectUploadPartOptions) *ObjectUploadPartOptions {
  239. var res ObjectUploadPartOptions
  240. if opt != nil {
  241. res = *opt
  242. res.XOptionHeader = cloneHeader(opt.XOptionHeader)
  243. }
  244. return &res
  245. }
  246. func CloneObjectGetOptions(opt *ObjectGetOptions) *ObjectGetOptions {
  247. var res ObjectGetOptions
  248. if opt != nil {
  249. res = *opt
  250. res.XOptionHeader = cloneHeader(opt.XOptionHeader)
  251. }
  252. return &res
  253. }
  254. func CloneCompleteMultipartUploadOptions(opt *CompleteMultipartUploadOptions) *CompleteMultipartUploadOptions {
  255. var res CompleteMultipartUploadOptions
  256. if opt != nil {
  257. res.XMLName = opt.XMLName
  258. if len(opt.Parts) > 0 {
  259. res.Parts = make([]Object, len(opt.Parts))
  260. copy(res.Parts, opt.Parts)
  261. }
  262. res.XOptionHeader = cloneHeader(opt.XOptionHeader)
  263. }
  264. return &res
  265. }
  266. type RangeOptions struct {
  267. HasStart bool
  268. HasEnd bool
  269. Start int64
  270. End int64
  271. }
  272. func FormatRangeOptions(opt *RangeOptions) string {
  273. if opt == nil {
  274. return ""
  275. }
  276. if opt.HasStart && opt.HasEnd {
  277. return fmt.Sprintf("bytes=%v-%v", opt.Start, opt.End)
  278. }
  279. if opt.HasStart {
  280. return fmt.Sprintf("bytes=%v-", opt.Start)
  281. }
  282. if opt.HasEnd {
  283. return fmt.Sprintf("bytes=-%v", opt.End)
  284. }
  285. return ""
  286. }
  287. func GetRangeOptions(opt *ObjectGetOptions) (*RangeOptions, error) {
  288. if opt == nil || opt.Range == "" {
  289. return nil, nil
  290. }
  291. // bytes=M-N
  292. slices := strings.Split(opt.Range, "=")
  293. if len(slices) != 2 || slices[0] != "bytes" {
  294. return nil, fmt.Errorf("Invalid Parameter Range: %v", opt.Range)
  295. }
  296. // byte=M-N, X-Y
  297. fSlice := strings.Split(slices[1], ",")
  298. rstr := fSlice[0]
  299. var err error
  300. var ropt RangeOptions
  301. sted := strings.Split(rstr, "-")
  302. if len(sted) != 2 {
  303. return nil, fmt.Errorf("Invalid Parameter Range: %v", opt.Range)
  304. }
  305. // M
  306. if len(sted[0]) > 0 {
  307. ropt.Start, err = strconv.ParseInt(sted[0], 10, 64)
  308. if err != nil {
  309. return nil, fmt.Errorf("Invalid Parameter Range: %v,err: %v", opt.Range, err)
  310. }
  311. ropt.HasStart = true
  312. }
  313. // N
  314. if len(sted[1]) > 0 {
  315. ropt.End, err = strconv.ParseInt(sted[1], 10, 64)
  316. if err != nil || ropt.End == 0 {
  317. return nil, fmt.Errorf("Invalid Parameter Range: %v,err: %v", opt.Range, err)
  318. }
  319. ropt.HasEnd = true
  320. }
  321. return &ropt, nil
  322. }
  323. var deliverHeader = map[string]bool{}
  324. func isDeliverHeader(key string) bool {
  325. for k, v := range deliverHeader {
  326. if key == k && v {
  327. return true
  328. }
  329. }
  330. return strings.HasPrefix(key, privateHeaderPrefix)
  331. }
  332. func deliverInitOptions(opt *InitiateMultipartUploadOptions) (*http.Header, error) {
  333. if opt == nil {
  334. return nil, nil
  335. }
  336. h, err := httpheader.Header(opt)
  337. if err != nil {
  338. return nil, err
  339. }
  340. header := &http.Header{}
  341. for key, values := range h {
  342. key = strings.ToLower(key)
  343. if isDeliverHeader(key) {
  344. for _, value := range values {
  345. header.Add(key, value)
  346. }
  347. }
  348. }
  349. return header, nil
  350. }