Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add client-side support for datetime value of Retry-After header #131

Merged
merged 4 commits into from
Sep 26, 2022

Conversation

nemoshlag
Copy link
Member

@nemoshlag nemoshlag commented Sep 19, 2022

According to specifications, Retry-After header should be either seconds-delay or HTTP-date
https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3

Resolves #119

@nemoshlag nemoshlag requested a review from a team September 19, 2022 13:28
@nemoshlag nemoshlag changed the title Fix/retry-after #119 Retry-After dateTIme value Sep 19, 2022
retryIntervalSec, err := strconv.Atoi(retryAfter)
if err == nil {
retryInterval := time.Duration(retryIntervalSec) * time.Second
return OptionalDuration{Defined: true, Duration: retryInterval}
}
// Try to parse retryAfterHTTPHeader as HTTP-date
// See https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3
t, err := time.Parse(time.RFC1123, retryAfter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP RFC7231 defines 3 different formats of HTTP-date that receivers MUST support. One of the formats is RFC5322. This uses RFC1123 which does not seem to be what RFC7231 requires.

@codecov
Copy link

codecov bot commented Sep 22, 2022

Codecov Report

Base: 74.61% // Head: 76.22% // Increases project coverage by +1.61% 🎉

Coverage data is based on head (75cd666) compared to base (89eeb30).
Patch coverage: 100.00% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #131      +/-   ##
==========================================
+ Coverage   74.61%   76.22%   +1.61%     
==========================================
  Files          23       23              
  Lines        1765     1792      +27     
==========================================
+ Hits         1317     1366      +49     
+ Misses        334      319      -15     
+ Partials      114      107       -7     
Impacted Files Coverage Δ
internal/retryafter.go 100.00% <100.00%> (+9.09%) ⬆️
client/internal/tcpproxy.go 73.01% <0.00%> (-7.94%) ⬇️
client/wsclient.go 87.19% <0.00%> (+2.43%) ⬆️
server/callbacks.go 72.72% <0.00%> (+4.54%) ⬆️
server/wsconnection.go 70.00% <0.00%> (+7.50%) ⬆️
client/internal/receivedprocessor.go 84.28% <0.00%> (+15.00%) ⬆️
server/httpconnection.go 33.33% <0.00%> (+33.33%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

// See https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3
t, err := http.ParseTime(retryAfter)
if err == nil {
retryInterval := time.Until(t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably check that this is not negative. And the same in the case above with seconds. Seems like omission to me.

Comment on lines 19 to 50
func TestExtractRetryAfterHeaderDelaySeconds(t *testing.T) {
// Generate random n > 0 int
rand.Seed(time.Now().UnixNano())
retryIntervalSec := rand.Intn(9999)

// Generate a 503 status code response with Retry-After = n header
resp := response503()
resp.Header.Add(retryAfterHTTPHeader, strconv.Itoa(retryIntervalSec))

expectedDuration := OptionalDuration{
Defined: true,
Duration: time.Second * time.Duration(retryIntervalSec),
}
assert.Equal(t, expectedDuration, ExtractRetryAfterHeader(resp))
}

func TestExtractRetryAfterHeader429StatusCode(t *testing.T) {
// Generate random n > 0 int
rand.Seed(time.Now().UnixNano())
retryIntervalSec := rand.Intn(9999)

// Generate a 429 status code response with Retry-After = n header
resp := response503()
resp.StatusCode = http.StatusTooManyRequests
resp.Header.Add(retryAfterHTTPHeader, strconv.Itoa(retryIntervalSec))

expectedDuration := OptionalDuration{
Defined: true,
Duration: time.Second * time.Duration(retryIntervalSec),
}
assert.Equal(t, expectedDuration, ExtractRetryAfterHeader(resp))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 tests are almost identical. It would be nice to make them one test with 2 sub-tests. It will eliminate a lot of lines.

@tigrannajaryan tigrannajaryan changed the title Retry-After dateTIme value Add client-side support for datetime value of Retry-After header Sep 22, 2022
Copy link
Member

@tigrannajaryan tigrannajaryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @nemoshlag

@tigrannajaryan tigrannajaryan merged commit 491ce60 into open-telemetry:main Sep 26, 2022
@nemoshlag nemoshlag deleted the fix/retryAfter branch September 28, 2022 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

retry policy: parse datetime value for Retry-After header?
2 participants