31 lines
814 B
Go
31 lines
814 B
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"crypto"
|
||
|
"crypto/rand"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type Signer struct {
|
||
|
key crypto.Signer
|
||
|
keyID string
|
||
|
}
|
||
|
|
||
|
// Sign modifies the request, computing and setting the Signature header, and setting the Date header to the provided time.
|
||
|
func (s Signer) Sign(r *http.Request, date time.Time) error {
|
||
|
host := r.URL.Host
|
||
|
path := r.URL.Path
|
||
|
method := strings.ToLower(r.Method)
|
||
|
stringToSign := fmt.Sprintf("(request-target): %s %s\nhost: %s\ndate: %s", method, path, host, date.Format(time.RFC1123))
|
||
|
sig, err := s.key.Sign(rand.Reader, []byte(stringToSign), nil)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
r.Header.Set("Date", date.Format(time.RFC1123))
|
||
|
r.Header.Set("Signature", fmt.Sprintf(`keyId="%s",headers="(request-target) host date",signature="%s"`, s.keyID, sig))
|
||
|
return nil
|
||
|
}
|