Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion pkg/form3/auth_request_signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ type RequestSigningClientConfig struct {
pubKeyID string
privateKey *rsa.PrivateKey
underlyingTransport http.RoundTripper
retryPolicy *RetryPolicyConfig
}

type requestSigningTransport struct {
config *RequestSigningClientConfig
underlyingTransport http.RoundTripper
}

type RetryPolicyConfig struct {
retries int
incrementalTime bool
sleepTime time.Duration
}

func NewRequestSigningClientConfig(pubKeyID string, privateKey *rsa.PrivateKey) *RequestSigningClientConfig {
return &RequestSigningClientConfig{
pubKeyID: pubKeyID,
Expand All @@ -38,6 +45,11 @@ func (c *RequestSigningClientConfig) WithUnderlyingTransport(underlyingTransport
return c
}

func (c *RequestSigningClientConfig) WithRetryPolicyConfig(underlyingTransport http.RoundTripper, retryPolicyConfig *RetryPolicyConfig) *RequestSigningClientConfig {
c.retryPolicy = retryPolicyConfig
return c
}

func NewRequestSigningHTTPClient(config *RequestSigningClientConfig) *http.Client {
transport := &requestSigningTransport{
underlyingTransport: config.underlyingTransport,
Expand Down Expand Up @@ -126,5 +138,29 @@ content-length: %d`,
),
)

return t.underlyingTransport.RoundTrip(req)
return t.roundTripWithRetries(req, t.config.retryPolicy.retries, t.config.retryPolicy.sleepTime)
}

func (t *requestSigningTransport) roundTripWithRetries(req *http.Request, retries int, sleep time.Duration) (*http.Response, error) {
resp, err := t.underlyingTransport.RoundTrip(req)

if err != nil { // retry algorithm
if retries == 0 {
return nil, err // No further attempts left
}

time.Sleep(sleep)

var newSleepTime time.Duration

if t.config.retryPolicy.incrementalTime {
newSleepTime = sleep * 2
} else {
newSleepTime = sleep
}

return t.roundTripWithRetries(req, retries-1, newSleepTime)
}

return resp, nil
}