Skip to content

Instantly share code, notes, and snippets.

@giautm
Created November 7, 2022 07:09
Show Gist options
  • Save giautm/4b89670c86f7cc07305e7a2abc9a028e to your computer and use it in GitHub Desktop.
Save giautm/4b89670c86f7cc07305e7a2abc9a028e to your computer and use it in GitHub Desktop.
package floww
import (
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
)
// Transport is a HTTP transport that signs requests.
type Transport struct {
Base http.RoundTripper
PartnerID string
AccessKey string
SecretKey []byte
}
// NewTransport returns a new Transport.
func NewTransport(partnerID, accessKey, secretKey string) *Transport {
return &Transport{
Base: http.DefaultTransport,
PartnerID: partnerID,
AccessKey: accessKey,
SecretKey: []byte(secretKey),
}
}
// RoundTrip implements http.RoundTripper.
func (t *Transport) RoundTrip(req *http.Request) (_ *http.Response, err error) {
defer req.Body.Close()
m := md5.New()
b := &bytes.Buffer{}
if _, err = io.Copy(b, io.TeeReader(req.Body, m)); err != nil {
return nil, err
}
h := hmac.New(sha256.New, t.SecretKey)
if _, err = fmt.Fprintf(h, "%x", m.Sum(nil)); err != nil {
return nil, err
}
req.Header.Set("X-Partner-ID", t.PartnerID)
req.Header.Set("X-Access-Key", t.AccessKey)
req.Header.Set("X-Signature", hex.EncodeToString(h.Sum(nil)))
req.Body = io.NopCloser(b)
return t.Base.RoundTrip(req)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment