github.com/qiniu/go-sdk/v7@v7.27.0/sms/client/qiniumac.go (about) 1 package client 2 3 import ( 4 "crypto/hmac" 5 "crypto/sha1" 6 "io" 7 "net/http" 8 "sort" 9 10 "github.com/qiniu/go-sdk/v7/sms/bytes/seekable" 11 ) 12 13 const qiniuHeaderPrefix = "X-Qiniu-" 14 15 // --------------------------------------------------------------------------------------- 16 17 func incBody(req *http.Request, ctType string) bool { 18 return req.ContentLength != 0 && req.Body != nil && ctType != "" && ctType != "application/octet-stream" 19 } 20 21 func signQiniuHeaderValues(header http.Header, w io.Writer) { 22 var keys []string 23 for key := range header { 24 if len(key) > len(qiniuHeaderPrefix) && key[:len(qiniuHeaderPrefix)] == qiniuHeaderPrefix { 25 keys = append(keys, key) 26 } 27 } 28 if len(keys) == 0 { 29 return 30 } 31 32 if len(keys) > 1 { 33 sort.Sort(sortByHeaderKey(keys)) 34 } 35 for _, key := range keys { 36 io.WriteString(w, "\n"+key+": "+header.Get(key)) 37 } 38 } 39 40 // SignRequest sign request 41 func SignRequest(sk []byte, req *http.Request) ([]byte, error) { 42 h := hmac.New(sha1.New, sk) 43 44 u := req.URL 45 data := req.Method + " " + u.Path 46 if u.RawQuery != "" { 47 data += "?" + u.RawQuery 48 } 49 io.WriteString(h, data+"\nHost: "+req.Host) 50 51 ctType := req.Header.Get("Content-Type") 52 if ctType != "" { 53 io.WriteString(h, "\nContent-Type: "+ctType) 54 } 55 56 signQiniuHeaderValues(req.Header, h) 57 58 io.WriteString(h, "\n\n") 59 60 if incBody(req, ctType) { 61 s2, err2 := seekable.New(req) 62 if err2 != nil { 63 return nil, err2 64 } 65 h.Write(s2.Bytes()) 66 } 67 68 return h.Sum(nil), nil 69 } 70 71 // --------------------------------------------------------------------------------------- 72 73 // RequestSigner request signer 74 type RequestSigner struct{} 75 76 // DefaultRequestSigner default request signer 77 var DefaultRequestSigner RequestSigner 78 79 // Sign access key and request 80 func (p RequestSigner) Sign(sk []byte, req *http.Request) ([]byte, error) { 81 return SignRequest(sk, req) 82 } 83 84 // --------------------------------------------------------------------------------------- 85 86 type sortByHeaderKey []string 87 88 func (p sortByHeaderKey) Len() int { return len(p) } 89 func (p sortByHeaderKey) Less(i, j int) bool { return p[i] < p[j] } 90 func (p sortByHeaderKey) Swap(i, j int) { p[i], p[j] = p[j], p[i] }