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

package cos
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)
// 计算 md5 或 sha1 时的分块大小
const calDigestBlockSize = 1024 * 1024 * 10
func calMD5Digest(msg []byte) []byte {
// TODO: 分块计算,减少内存消耗
m := md5.New()
m.Write(msg)
return m.Sum(nil)
}
func calSHA1Digest(msg []byte) []byte {
// TODO: 分块计算,减少内存消耗
m := sha1.New()
m.Write(msg)
return m.Sum(nil)
}
// cloneRequest returns a clone of the provided *http.Request. The clone is a
// shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request {
// shallow copy of the struct
r2 := new(http.Request)
*r2 = *r
// deep copy of the Header
r2.Header = make(http.Header, len(r.Header))
for k, s := range r.Header {
r2.Header[k] = append([]string(nil), s...)
}
return r2
}
// encodeURIComponent like same function in javascript
//
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
//
// http://www.ecma-international.org/ecma-262/6.0/#sec-uri-syntax-and-semantics
func encodeURIComponent(s string, excluded ...[]byte) string {
var b bytes.Buffer
written := 0
for i, n := 0, len(s); i < n; i++ {
c := s[i]
switch c {
case '-', '_', '.', '!', '~', '*', '\'', '(', ')':
continue
default:
// Unreserved according to RFC 3986 sec 2.3
if 'a' <= c && c <= 'z' {
continue
}
if 'A' <= c && c <= 'Z' {
continue
}
if '0' <= c && c <= '9' {
continue
}
if len(excluded) > 0 {
conti := false
for _, ch := range excluded[0] {
if ch == c {
conti = true
break
}
}
if conti {
continue
}
}
}
b.WriteString(s[written:i])
fmt.Fprintf(&b, "%%%02X", c)
written = i + 1
}
if written == 0 {
return s
}
b.WriteString(s[written:])
return b.String()
}
func decodeURIComponent(s string) (string, error) {
decodeStr, err := url.QueryUnescape(s)
if err != nil {
return s, err
}
return decodeStr, err
}
func DecodeURIComponent(s string) (string, error) {
return DecodeURIComponent(s)
}
func EncodeURIComponent(s string) string {
return encodeURIComponent(s)
}
func GetReaderLen(reader io.Reader) (length int64, err error) {
switch v := reader.(type) {
case *bytes.Buffer:
length = int64(v.Len())
case *bytes.Reader:
length = int64(v.Len())
case *strings.Reader:
length = int64(v.Len())
case *os.File:
stat, ferr := v.Stat()
if ferr != nil {
err = fmt.Errorf("can't get reader length: %s", ferr.Error())
} else {
length = stat.Size()
}
case *io.LimitedReader:
length = int64(v.N)
case FixedLengthReader:
length = v.Size()
default:
err = fmt.Errorf("can't get reader content length, unkown reader type")
}
return
}