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.

142 lines
2.7 KiB

4 years ago
4 years ago
4 years ago
  1. package cos
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "crypto/sha1"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "net/url"
  10. "os"
  11. "strings"
  12. )
  13. // 计算 md5 或 sha1 时的分块大小
  14. const calDigestBlockSize = 1024 * 1024 * 10
  15. func calMD5Digest(msg []byte) []byte {
  16. // TODO: 分块计算,减少内存消耗
  17. m := md5.New()
  18. m.Write(msg)
  19. return m.Sum(nil)
  20. }
  21. func calSHA1Digest(msg []byte) []byte {
  22. // TODO: 分块计算,减少内存消耗
  23. m := sha1.New()
  24. m.Write(msg)
  25. return m.Sum(nil)
  26. }
  27. // cloneRequest returns a clone of the provided *http.Request. The clone is a
  28. // shallow copy of the struct and its Header map.
  29. func cloneRequest(r *http.Request) *http.Request {
  30. // shallow copy of the struct
  31. r2 := new(http.Request)
  32. *r2 = *r
  33. // deep copy of the Header
  34. r2.Header = make(http.Header, len(r.Header))
  35. for k, s := range r.Header {
  36. r2.Header[k] = append([]string(nil), s...)
  37. }
  38. return r2
  39. }
  40. // encodeURIComponent like same function in javascript
  41. //
  42. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
  43. //
  44. // http://www.ecma-international.org/ecma-262/6.0/#sec-uri-syntax-and-semantics
  45. func encodeURIComponent(s string, excluded ...[]byte) string {
  46. var b bytes.Buffer
  47. written := 0
  48. for i, n := 0, len(s); i < n; i++ {
  49. c := s[i]
  50. switch c {
  51. case '-', '_', '.', '!', '~', '*', '\'', '(', ')':
  52. continue
  53. default:
  54. // Unreserved according to RFC 3986 sec 2.3
  55. if 'a' <= c && c <= 'z' {
  56. continue
  57. }
  58. if 'A' <= c && c <= 'Z' {
  59. continue
  60. }
  61. if '0' <= c && c <= '9' {
  62. continue
  63. }
  64. if len(excluded) > 0 {
  65. conti := false
  66. for _, ch := range excluded[0] {
  67. if ch == c {
  68. conti = true
  69. break
  70. }
  71. }
  72. if conti {
  73. continue
  74. }
  75. }
  76. }
  77. b.WriteString(s[written:i])
  78. fmt.Fprintf(&b, "%%%02X", c)
  79. written = i + 1
  80. }
  81. if written == 0 {
  82. return s
  83. }
  84. b.WriteString(s[written:])
  85. return b.String()
  86. }
  87. func decodeURIComponent(s string) (string, error) {
  88. decodeStr, err := url.QueryUnescape(s)
  89. if err != nil {
  90. return s, err
  91. }
  92. return decodeStr, err
  93. }
  94. func DecodeURIComponent(s string) (string, error) {
  95. return DecodeURIComponent(s)
  96. }
  97. func EncodeURIComponent(s string) string {
  98. return encodeURIComponent(s)
  99. }
  100. func GetReaderLen(reader io.Reader) (length int64, err error) {
  101. switch v := reader.(type) {
  102. case *bytes.Buffer:
  103. length = int64(v.Len())
  104. case *bytes.Reader:
  105. length = int64(v.Len())
  106. case *strings.Reader:
  107. length = int64(v.Len())
  108. case *os.File:
  109. stat, ferr := v.Stat()
  110. if ferr != nil {
  111. err = fmt.Errorf("can't get reader length: %s", ferr.Error())
  112. } else {
  113. length = stat.Size()
  114. }
  115. case *io.LimitedReader:
  116. length = int64(v.N)
  117. case FixedLengthReader:
  118. length = v.Size()
  119. default:
  120. err = fmt.Errorf("can't get reader content length, unkown reader type")
  121. }
  122. return
  123. }